| | 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') |
| |
|
| | option = st.selectbox( |
| | "select template grids", |
| | grids, |
| | ) |
| | x = st.text_area('grid', value=grids[option], height=300) |
| |
|
| | tensor_grid, df_styler = build_grid_and_display(str_to_row_col_grid(x)) |
| | |
| | |
| | html = df_styler.to_html(escape=False, index=False) |
| | |
| | st.html(html) |
| | st.markdown(''' |
| | ## Checking the number of solutions |
| | (with backtracking algorithm) |
| | must be equal 1 |
| | ''') |
| | 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: |
| | 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) |
| | 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''') |
| | is_valid, new_X = model.backtracking_predict(new_X) |
| | 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!') |
| |
|
| | |
| |
|