Last active
July 24, 2016 08:18
-
-
Save uroybd/6a8ed4171db6684bd2578c5aa2f946f2 to your computer and use it in GitHub Desktop.
Sudoku Solver
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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("--------------------------") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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