File size: 4,506 Bytes
4484b8a
cd4d5f4
4484b8a
 
 
 
 
b423232
4484b8a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
946af58
 
 
 
4484b8a
 
 
 
 
9c80fef
4484b8a
9c80fef
4484b8a
 
 
 
 
 
 
 
9c80fef
 
 
4484b8a
 
 
 
 
9c80fef
4484b8a
 
 
 
 
 
 
cd4d5f4
19320e5
cd4d5f4
 
 
19320e5
 
 
 
 
 
 
 
 
cd4d5f4
4484b8a
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
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!')