Python随机字符串收敛程序偶发无法执行main()问题求助
Hey there, let's tackle that frustrating intermittent hanging problem with your weasel program. I've looked over your code, and I can see why it's getting stuck on your 2015 MacBook Air (but working fine elsewhere)—it's a mix of inefficient randomness and potential output buffering. Here's how to fix it for good:
First, Why It's Stuck
Your current approach relies on generating entirely random strings and only keeping matches when they happen to line up with the goal. The problem? Once you've got most characters correct, the remaining few might take an absurdly long time to hit randomly. On slower hardware like your 2015 Air, this feels like a freeze, even though the program is still chugging away in an infinite loop waiting for those last random hits. Also, Eclipse's console might be buffering output, so you don't see progress even when it's running.
Fixes That Work
1. Rewrite the Algorithm (The Real Solution)
The classic weasel program doesn't generate full random strings every time—it keeps the correct characters and only re-randomizes the wrong ones. This makes convergence fast and predictable. Here's the improved code:
import random def generate_candidate(goal, current_best): alphabet = "abcdefghijklmnopqrstuvwxyz " candidate = [] for goal_char, best_char in zip(goal, current_best): # Keep correct characters, randomize the rest if goal_char == best_char: candidate.append(best_char) else: candidate.append(alphabet[random.randrange(27)]) return ''.join(candidate) def calculate_score(goal, test_string): matches = sum(1 for g, t in zip(goal, test_string) if g == t) return matches / len(goal) def main(): goal = "methinks it is like a weasel" current_best = generate_candidate(goal, ['']*len(goal)) iterations = 0 best_score = calculate_score(goal, current_best) print(f"Starting with: {current_best}") while best_score < 1.0: candidate = generate_candidate(goal, current_best) candidate_score = calculate_score(goal, candidate) # Update if we found a better candidate if candidate_score > best_score: best_score = candidate_score current_best = candidate print(f"Iteration {iterations}: Score {best_score:.2f} | {current_best}", flush=True) iterations += 1 print(f"\nSuccess! Final string: {current_best}") print(f"Total iterations: {iterations}") print("hi") if __name__ == '__main__': main() print("ho")
This version will converge in seconds, no more hanging.
2. Fix Output Buffering (Quick Win for Your Original Code)
If you want to keep your original code but see progress, add flush=True to all print statements. This forces Eclipse's console to show output immediately instead of buffering it:
print(finalstring, flush=True)
3. Add Guardrails to Avoid Infinite Loops
For your original code, add a maximum iteration limit so it doesn't run forever if luck isn't on your side:
max_iterations = 1_000_000 # Adjust as needed while score(list(goalstring), workingstring) < 1 and countvar < max_iterations: # Your existing loop code here
You can also add a status update every X iterations to confirm it's still running:
if countvar % 10_000 == 0: current_score = score(goalstring, workingstring) print(f"Still running... Iteration {countvar}, Score: {current_score:.2f}", flush=True)
Why It Works Elsewhere
Randomness is fickle! Other computers might get lucky and hit those last few characters quickly, while your Air's slower CPU combined with an unlucky random seed makes it take way longer. The improved algorithm eliminates that luck dependency entirely.
Final Recommendation
Go with the rewritten algorithm (fix #1)—it's the standard approach for this problem, and it'll never hang on you again. The other fixes are band-aids for the original inefficient code.
内容的提问来源于stack exchange,提问作者Xavier

