Skip to content

Instantly share code, notes, and snippets.

@highfestiva
Created March 27, 2023 15:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save highfestiva/dc3c77db91fc1e2ccdba24ccf1855365 to your computer and use it in GitHub Desktop.
Save highfestiva/dc3c77db91fc1e2ccdba24ccf1855365 to your computer and use it in GitHub Desktop.
Just another sudoku solver
#!/usr/bin/env python3
import pandas as pd
puzzle = '''
+-----+-----+-----+
|5 | 8 | 4 9|
| |5 | 3 |
| 6 7|3 | 1|
+-----+-----+-----+
|1 5 | | |
| |2 8| |
| | | 1 8|
+-----+-----+-----+
|7 | 4|1 5 |
| 3 | 2| |
|4 9 | 5 | 3|
+-----+-----+-----+'''.strip().splitlines()
data = [[int(c) if c in '123456789' else 0 for c in r[1::2]] for r in puzzle]
data = [r for i,r in enumerate(data) if i%4 != 0]
df = pd.DataFrame(data)
get_row = lambda df, y: list(df.loc[y, :])
get_col = lambda df, x: list(df.loc[:, x])
def get_sqr(df, x, y):
yy = y//3 * 3
xx = x//3 * 3
return list(df.loc[yy:yy+2, xx:xx+2].values.reshape(9))
def get_possibles(df):
possibles = pd.DataFrame([[set() for x in range(9)] for y in range(9)])
vals = set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) # include 0, which is always ignored
for y in range(9):
for x in range(9):
v = df.loc[y,x]
if v == 0:
in_row = get_row(df, y)
in_col = get_col(df, x)
in_sqr = get_sqr(df, x, y)
possible = vals - set(in_row+in_col+in_sqr)
possibles.loc[y, x].update(possible)
else:
possibles.loc[y, x].add(v)
return possibles
def get_moves(df):
possibles = get_possibles(df)
moves = []
for y in range(9):
for x in range(9):
v = df.loc[y,x]
if v == 0:
p = possibles.loc[y,x]
if len(p) == 1:
moves.append(dict(x=x, y=y, num=list(p)[0]))
continue
possibles.loc[y,x] = set()
in_row = get_row(possibles, y)
in_col = get_col(possibles, x)
in_sqr = get_sqr(possibles, x, y)
possibles.loc[y,x] = p
for l in [in_row, in_col, in_sqr]:
s = set()
for t in l:
s.update(t)
q = p - s
if len(q) == 1:
moves.append(dict(x=x, y=y, num=list(q)[0]))
possibles.loc[y,x] = q
break
return moves
moves = ['moves goes here']
while moves:
print(df, end='\n\n')
moves = get_moves(df)
for move in moves:
df.loc[move['y'], move['x']] = move['num']
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment