Skip to content

Commit

Permalink
Vector (#41)
Browse files Browse the repository at this point in the history
* first ideas

* first heuristics

* more tweaks

* first heuristic solver

* adding jupyter book
  • Loading branch information
iheitlager authored Nov 23, 2023
1 parent c85e1b0 commit e3b8d12
Show file tree
Hide file tree
Showing 13 changed files with 447 additions and 30 deletions.
8 changes: 8 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@
"request": "launch",
"program": "${file}",
"justMyCode": true
},
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"purpose": ["debug-test"]
}
]
}
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ dev_env: ## Install the dev env
@python -m pip install pytest
@python -m pip install coverage
@python -m pip install ipykernel
@python -m pip install -r requirements.txt

virtualenv: $(VIRTUALENV)/sudoku/bin/activate
virtualenv $(VIRTUALENV)/sudoku
Expand Down
238 changes: 238 additions & 0 deletions notebooks/heuristic_sudoku.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This notebook provides a simple sudoku solver. Let's start with a simple 4 (\\*\\*\\*\\*) star sudoku"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"# Parool Dinsdag 19 sept ****\n",
"sudoku_grid = [\n",
" [0, 6, 0, 0, 0, 0, 1, 9, 0],\n",
" [0, 0, 2, 6, 1, 0, 0, 0, 4],\n",
" [7, 0, 1, 0, 0, 0, 0, 0, 0],\n",
" [0, 0, 0, 0, 7, 0, 0, 1, 0],\n",
" [0, 0, 6, 0, 8, 3, 0, 0, 0],\n",
" [5, 4, 0, 0, 6, 0, 0, 0, 3],\n",
" [0, 8, 0, 0, 2, 7, 0, 3, 9],\n",
" [0, 0, 0, 4, 0, 0, 0, 7, 8],\n",
" [0, 0, 0, 0, 0, 0, 4, 0, 0]\n",
"]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And let's show the grid by importing a simple pretty printer. "
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from sudoku.solvers import heuristic\n",
"\n",
"grid = heuristic.pencil_in_numbers(sudoku_grid)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"292"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"heuristic.simple_elimination(grid)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"heuristic.simple_elimination(grid)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"15"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"heuristic.hidden_single(grid)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"#heuristic.hidden_single(grid)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[[[3, 4, 8],\n",
" [6],\n",
" [3, 4, 5, 8],\n",
" [7],\n",
" [3, 4, 5],\n",
" [2, 4, 5, 8],\n",
" [1],\n",
" [9],\n",
" [2, 5, 7]],\n",
" [[3, 8, 9], [3, 5, 9], [2], [6], [1], [5, 8, 9], [7], [5, 8], [4]],\n",
" [[7],\n",
" [3, 5, 9],\n",
" [1],\n",
" [2, 3, 5, 8, 9],\n",
" [3, 4, 5, 9],\n",
" [2, 4, 5, 8, 9],\n",
" [2, 3, 5, 6, 8],\n",
" [2, 5, 6, 8],\n",
" [2, 5, 6]],\n",
" [[2, 3, 8, 9],\n",
" [2, 3, 9],\n",
" [3, 8, 9],\n",
" [2, 5, 9],\n",
" [7],\n",
" [4],\n",
" [2, 5, 6, 8, 9],\n",
" [1],\n",
" [2, 5, 6]],\n",
" [[1, 2, 9],\n",
" [1, 2, 7, 9],\n",
" [6],\n",
" [1, 2, 5, 9],\n",
" [8],\n",
" [3],\n",
" [2, 5, 7, 9],\n",
" [4],\n",
" [2, 5, 7]],\n",
" [[5], [4], [7, 8, 9], [1, 2, 9], [6], [1, 2, 9], [2, 7, 8, 9], [2, 8], [3]],\n",
" [[1, 4, 6], [8], [4, 5], [1, 5], [2], [7], [5, 6], [3], [9]],\n",
" [[1, 2, 3, 6, 9],\n",
" [1, 2, 3, 5, 9],\n",
" [3, 5, 9],\n",
" [4],\n",
" [3, 5, 9],\n",
" [1, 5, 6, 9],\n",
" [2, 5, 6],\n",
" [7],\n",
" [8]],\n",
" [[1, 2, 3, 6, 9],\n",
" [1, 2, 3, 5, 7, 9],\n",
" [3, 5, 7, 9],\n",
" [1, 3, 5, 8, 9],\n",
" [3, 5, 9],\n",
" [1, 5, 6, 8, 9],\n",
" [4],\n",
" [2, 5, 6],\n",
" [1]]]"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"grid"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sudoku.solvers import heuristic\n",
"\n",
"heuristic.solve(grid)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}
36 changes: 22 additions & 14 deletions src/sudoku/__init__.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
def count_nonzero(grid):
# just get all coordinates
all_grid = [(i, j) for i in range(9) for j in range(9)]

def n_nonzero(grid):
n = 0
for row in range(9):
for col in range(9):
if grid[row][col] != 0:
n += 1
for (i, j) in all_grid:
if grid[i][j] != 0:
n += 1
return n


def is_complete(grid):
for row in range(9):
for col in range(9):
if grid[row][col] == 0:
return False
def is_solved(grid):
for (i, j) in all_grid:
if isinstance(grid[i][j], list) and len(grid[i][j]) != 1:
return False
elif grid[i][j] == 0 :
return False
return True


def find_empty_cell(grid):
for row in range(9):
for col in range(9):
if grid[row][col] == 0:
return row, col
for (i, j) in all_grid:
if grid[i][j] == 0:
return i, j
return None, None


def flatten(grid):
for (i, j) in all_grid:
if isinstance(grid[i][j], list) and len(grid[i][j]) == 1:
grid[i][j] = grid[i][j][0]
11 changes: 11 additions & 0 deletions src/sudoku/printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,14 @@ def display_pylist(grid):
print(" [%s]," % ', '.join([str(x) for x in row]))
print(" [%s]" % ', '.join([str(x) for x in grid[-1]]))
print("]")


def as_string(grid):
'''
Return as single line string
'''
result = ""
for row in grid:
for cell in row:
result += str(cell)
return result
4 changes: 2 additions & 2 deletions src/sudoku/solvers/backtracking.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from sudoku import find_empty_cell, is_complete
from sudoku import find_empty_cell, is_solved

iterations = 0

Expand All @@ -20,7 +20,7 @@ def is_valid(grid, row, col, num):
def solve(grid):
global iterations

if is_complete(grid):
if is_solved(grid):
return True

iterations += 1
Expand Down
4 changes: 2 additions & 2 deletions src/sudoku/solvers/csp.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from sudoku import is_complete
from sudoku import is_solved
from constraint import *


def solve(sudoku_grid):
if is_complete(sudoku_grid):
if is_solved(sudoku_grid):
return True

problem = Problem(BacktrackingSolver())
Expand Down
Loading

0 comments on commit e3b8d12

Please sign in to comment.