Skip to content

Instantly share code, notes, and snippets.

@uroybd
Last active July 24, 2016 08:18
Show Gist options
  • Save uroybd/6a8ed4171db6684bd2578c5aa2f946f2 to your computer and use it in GitHub Desktop.
Save uroybd/6a8ed4171db6684bd2578c5aa2f946f2 to your computer and use it in GitHub Desktop.
Sudoku Solver
from copy import deepcopy
# Datastructure: [{'r': int, 'c': int, 'd': boolean, 'v': int, 'p': vecotor of int}.....]
def related(case, unit, data):
grider = [[1,2,3], [4,5,6], [7,8,9]]
for g in grider:
if unit['c'] in g:
cols = g
if unit['r'] in g:
rows = g
if case['r'] == unit['r'] or case['c'] == unit['c'] or (case['r'] in rows and case['c'] in cols):
return True
else:
return False
def change_hook(data):
if data is False:
return False
for d in list(filter(lambda x: x['v'] != 0, data)):
for rel in list(filter(lambda x: related(x, d, data), data)):
if d['v'] in rel['p']:
rel['p'].remove(d['v'])
return data
def get_data():
data = []
for r in range(1, 10):
inp = list(map(lambda x: int(x), input().split(" ")))
for c in range(1, 10):
val = inp[c-1]
data.append({
'r':r,
'c':c,
'd': False if val == 0 else True,
'v': False if val == 0 else val,
'p': [] if val != 0 else [1,2,3,4,5,6,7,8,9]
})
data = change_hook(data)
return data
def check_integrity(data):
if data is False or data is None:
return False
else:
for d in data:
for rel in list(filter(lambda x: related(x, d, data), data)):
if rel != d:
if rel['v'] == d['v'] and d['v'] is not False:
return False
return data
def print_ready(data):
pready = []
data.sort(key=lambda x: x['r'])
pdata = [data[i:i+9] for i in range(0, len(data), 9)]
for row in pdata:
row.sort(key=lambda x: x['c'])
pready.append("{}".format(" ".join(list(map(lambda x: "0" if x["v"] is False else str(x["v"]), row)))))
return "\n".join(pready)
def solve(data, v=False):
if data is False:
return False
elif check_integrity(data) is False:
return False
elif any(d['v'] is False for d in data):
if v is True:
print(print_ready(data))
ndata = deepcopy(data)
ndata.sort(key=lambda x: len(x['p']))
for d in list(filter(lambda x: len(x['p']) == 1, ndata)):
d['v'] = d['p'][0]
ndata = change_hook(ndata)
for d in ndata:
if d['d'] is True:
pass
elif d['v'] is False:
for n in d['p']:
d['v'] = n
r = solve(ndata, v)
if r:
return change_hook(r)
else:
d['v'] = False
else:
return data
def main(v=False):
data = get_data()
result = solve(data, v)
print("--------------------------")
print(print_ready(result))
print("--------------------------")
# EVIL
0 4 7 0 5 0 0 0 0
0 0 0 6 0 0 3 7 0
6 0 0 4 0 7 0 0 0
0 0 3 0 0 9 0 0 2
0 0 9 0 0 0 5 0 0
8 0 0 2 0 0 1 0 0
0 0 0 9 0 3 0 0 7
0 8 1 0 0 2 0 0 0
0 0 0 0 8 0 9 2 0
# Easy
1 6 5 9 2 0 4 0 0
7 0 0 0 0 3 0 9 0
0 0 9 0 7 0 0 0 0
0 8 0 1 0 0 9 3 2
0 9 0 0 0 0 0 4 0
3 7 4 0 0 2 0 8 0
0 0 0 0 6 0 3 0 0
0 5 0 2 0 0 0 0 4
0 0 3 0 1 4 7 5 6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment