# Better Wordle Solver

https://github.com/bakert/wordle

This one takes advantage of the wordlist being known and solves every word in a maximum of five guesses except “mover” which takes six.

``````import sys

def solve(fast = False):
solutions = possible_solutions()
guesses = possible_guesses()
while True:
if not fast:
b = best(solutions, guesses)
print(f"You should guess {b} ({solutions})")
fast = False
print("What did you guess?")
guess = input()
print("What was the result (in this format: _aT_r) where lowercase is orange and caps is green")
result = input()
solutions = resolve(guess, result, solutions)

def autosolve(solution):
print(f"Solving {solution}")
num_guesses = 0
solutions = possible_solutions()
guesses = possible_guesses()
while len(solutions) > 1:
if len(solutions) > 200:
guess = 'arise'
else:
guess = best(solutions, guesses)
num_guesses += 1
print(f"Guessing {guess} {num_guesses}")
solutions = resolve(guess, profile(guess, solution), solutions)
print(f"{len(solutions)} solutions left ({solutions})")
if num_guesses >= 5 and solutions != [guess]:
print(f"Failed on {solution}")

def resolve(guess, result, solutions):
return [solution for solution in solutions if profile(guess, solution) == result]

def profile(guess, solution):
p = ['_', '_', '_', '_', '_']
count = {}
for i in range(0, len(guess)):
if guess[i] == solution[i]:
p[i] = guess[i].upper()
count[guess[i]] = count.get(guess[i], 0) + 1
for i in range(0, len(guess)):
if p[i] == '_' and solution.count(guess[i]) > count.get(guess[i], 0):
p[i] = guess[i]
count[guess[i]] = count.get(guess[i], 0) + 1
return ''.join(p)

def profiled(guess, words):
hist = {}
for word in words:
p = profile(guess, word)
hist[p] = hist.get(p, []) + [word]
return hist

def score(guess, words):
n = 0
for ws in profiled(guess, words).values():
if len(ws) > n:
n = len(ws)
r = ws
if guess in words:
n -= 0.01 # If a word is a possible solution it's a better guess than a word that has the same worst case scenario but is not a possible solution.
if n == 0:
return sys.maxsize
return n, r

def best(solutions, guesses):
n = sys.maxsize
for guess in guesses:
x, ws = score(guess, solutions)
# print(f'Score for {guess} was {x}')
if x < n:
n = x
final_guess = guess
return final_guess

def possible_guesses():

def possible_solutions():

def test():
test_resolve()
test_profile()
test_profiled()

def test_resolve():
assert resolve('later', '_____', ['alert', 'disco']) == ['disco']

def test_profile():
assert profile('pouch', 'couch') == '_OUCH'

def test_profiled():

if len(sys.argv) <= 1:
solve()
elif sys.argv[1] == 'test':
test()
elif sys.argv[1] == 'fast':
# Skip the first search which will always tell you to guess 'arise' and takes a little while.
solve(True)
elif sys.argv[1] == 'all':
for word in possible_solutions():
autosolve(word)
else:
autosolve(sys.argv[1])

``````