Skip to content

Instantly share code, notes, and snippets.

@ali1234
Created January 8, 2022 00:33
Show Gist options
  • Save ali1234/3bef1f31f3c11b432953a9ce9202b274 to your computer and use it in GitHub Desktop.
Save ali1234/3bef1f31f3c11b432953a9ce9202b274 to your computer and use it in GitHub Desktop.
Find orthogonal solutions for hypersudoku
#!/usr/bin/env python3
from collections import defaultdict
from itertools import combinations, permutations
from math import isqrt
from subprocess import check_call
def inner(n):
return range(1, n+1)
def outer(n):
return range(1, n*n, n)
def hyperbox(n):
for x in inner(n):
for y in inner(n):
yield range(x, x+(n*n), x), range(y, y+(n*n), n)
def hyperrow(n):
for x in outer(n):
for y in inner(n):
yield range(x, x+n), range(y, y+(n*n), n)
def hypercolumn(n):
for x in inner(n):
for y in outer(n):
yield range(x, x+(n*n), n), range(y, y+n)
def mkregions(f, n):
for r, c in f(n):
yield '-c=extraregion:R{}C{}'.format(
','.join(str(x) for x in r),
','.join(str(x) for x in c)
)
def hyper(n):
yield from mkregions(hyperrow, n)
yield from mkregions(hypercolumn, n)
def t2s(s):
return ''.join(str(d) for d in s)
def ravel(*solutions):
sstrings = list(t2s(s) for s in solutions)
for n in range(0, 81, 9):
print(' '.join(s[n:n+9] for s in sstrings))
print()
given='123......456......789............................................................'
n = isqrt(isqrt(len(given)))
args = [
'./SudokuSolverConsole',
'-g='+given.strip(),
#'-b 4', # no solutions!
'-n', '-o=result.txt'
]
args.append('-c=djg') # equivalent to hyperbox
args.extend(list(hyper(n)))
print(args)
check_call(args)
with open('result.txt', 'r') as f:
solutions = set()
for line in f:
sln = tuple(int(c) for c in line.strip())
solutions.add(sln)
orthogonal = defaultdict(set)
for s1, s2 in combinations(solutions, 2):
combined = set(zip(s1,s2))
if len(combined) == 81:
orthogonal[s1].add(s1)
orthogonal[s1].add(s2)
orthogonal[s2].add(s1)
orthogonal[s2].add(s2)
seen = []
print('And now the final result...')
print()
for k, v in orthogonal.items():
if v in seen:
continue
# ravel(*v)
for sln in v:
print(t2s(sln))
print()
seen.append(v)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment