Sebastien
add paper link
946af58
import streamlit as st
from sudoku.train import SudokuTrialErrorLightning, TrialEveryPosException
from sudoku.helper import display_as_dataframe, get_grid_number_soluce
import numpy as np
import re
import torch
model = SudokuTrialErrorLightning.load_from_checkpoint(checkpoint_path="model_9_m3_big_validation_th.ckpt")
empty_grid = '''
0 0 0 | 0 0 0 | 0 0 0
0 0 0 | 0 0 0 | 0 0 0
0 0 0 | 0 0 0 | 0 0 0
---------------------
0 0 0 | 0 0 0 | 0 0 0
0 0 0 | 0 0 0 | 0 0 0
0 0 0 | 0 0 0 | 0 0 0
---------------------
0 0 0 | 0 0 0 | 0 0 0
0 0 0 | 0 0 0 | 0 0 0
0 0 0 | 0 0 0 | 0 0 0
'''
grid_evil_0 = '''
[0,0,0, 1,6,0, 2,0,0],
[0,3,0, 0,0,5, 0,0,4],
[0,0,7, 0,0,0, 0,9,0],
[0,0,1, 0,0,0, 0,8,2],
[3,0,0, 7,0,4, 0,0,5],
[4,2,0, 0,0,0, 6,0,0],
[0,8,0, 0,0,0, 5,0,0],
[7,0,0, 8,0,0, 0,2,0],
[0,0,6, 0,5,1, 0,0,0],
'''
grid_evil_1 = '''
[0,0,0, 2,0,0, 0,0,0],
[0,0,9, 7,0,0, 3,8,0],
[3,6,0, 0,0,0, 0,7,0],
[1,0,6, 8,0,0, 0,0,0],
[0,0,0, 3,5,9, 0,0,0],
[0,0,0, 0,0,2, 8,0,5],
[0,4,0, 0,0,0, 0,9,1],
[0,2,5, 0,0,8, 7,0,0],
[0,0,0, 0,0,6, 0,0,0],
]
'''
grid_evil_2 = '''
[0,2,0, 1,0,0, 0,7,0],
[0,0,0, 3,0,2, 0,0,0],
[0,0,1, 0,8,0, 0,4,0],
[9,0,0, 0,1,0, 0,0,7],
[0,0,8, 0,6,0, 0,5,0],
[0,0,0, 0,0,0, 0,0,0],
[0,8,0, 0,3,6, 0,0,9],
[0,0,5, 0,7,0, 0,0,6],
[0,0,2, 0,0,0, 0,0,3],
]
'''
grids = {
'empty': empty_grid,
'evil_1': grid_evil_0,
'evil_2': grid_evil_1,
'evil_3': grid_evil_2
}
def str_to_row_col_grid(su_str):
su_str = re.sub(r'[^\d.]', '', su_str).replace('.','0')
assert len(su_str)==81
return [[int(su_str[j*9+i]) for i in range(9)] for j in range(9)]
def build_tensor_out_of_grid(grid):
np_grid = np.asarray(grid)
big_grid = np.zeros((1,2,9,9,9), dtype=np.float32)
for i in range(9):
big_grid[0,1,:,:,i] = (np_grid==i+1)
big_grid[0,0,:,:,i] = ((np_grid!=i+1) & (np_grid!=0))
return torch.from_numpy(big_grid).view(1,2,729)
def build_grid_and_display(str_grid):
test_x = build_tensor_out_of_grid(str_grid)
return test_x, display_as_dataframe(test_x)
st.markdown('# Deep learning sudoku Solver')
st.markdown('''### Author: Sébastien Guissart
Detailed method in this [paper](https://huggingface.co/spaces/SebastienGuissart/deeplearning_sudoku_solver/blob/main/100%25%20accurate%20Sudoku%20solving%20with%20deep%20learning%20algorithm.pdf)
''')
option = st.selectbox(
"select template grids",
grids,
)
x = st.text_area('You can edit the grid, every format is accepted. Empty cell can be designed by `0` or by `.`', value=grids[option], height=300)
st.markdown('### Initial grid')
tensor_grid, df_styler = build_grid_and_display(str_to_row_col_grid(x))
# st.table(df_styler)
# st.dataframe(df_styler)
html = df_styler.to_html(escape=False, index=False)
# # st.text(html)
st.html(html)
st.markdown('''
## Checking the number of solutions
(with classical backtracking algorithm).
Number of solutions must be one to trigger the grid resolution.
''')
n_sol = get_grid_number_soluce(str_to_row_col_grid(x))
st.markdown(f"number of solution: {'>2' if n_sol==2 else n_sol}")
if n_sol==1:
st.markdown('## Predicting grid step by step')
new_X = model.predict(tensor_grid)
X_sum= new_X.sum()
st.html(display_as_dataframe(new_X).to_html(escape=False, index=False))
i=1
while new_X.sum()<729:
i+=1
st.markdown(f'iteration {i}')
try:
new_X = model.predict(new_X, func_text_display=st.markdown)
except TrialEveryPosException:
st.markdown('''## The grid is super evil!
please share it as A Discussion in the `Community` tab.
Except if it is this one: https://www.telegraph.co.uk/news/science/science-news/9359579/Worlds-hardest-sudoku-can-you-crack-it.html
Using trail error model enhanced by backtracking
''')
is_valid, new_X = model.backtracking_predict(
new_X,
func_text_display=st.markdown,
func_tensor_display=lambda t: st.html(display_as_dataframe(t).to_html(escape=False, index=False)),
)
assert is_valid
st.html(display_as_dataframe(new_X).to_html(escape=False, index=False))
new_X_sum = new_X.sum()
assert new_X_sum> X_sum
X_sum = new_X_sum
st.markdown('## Grid solved!')