Compare commits
No commits in common. "904c34ac738fb8908394fb8da008104721000ea0" and "a2fa29ab4b9e9c6ef95d2fbc7a2c8a9ec87d6808" have entirely different histories.
904c34ac73
...
a2fa29ab4b
1 changed files with 43 additions and 166 deletions
207
main.py
207
main.py
|
@ -89,21 +89,18 @@ def invariants(width, pattern, constraints=None):
|
||||||
invs = []
|
invs = []
|
||||||
for sol in solve2(width, pattern, constraints):
|
for sol in solve2(width, pattern, constraints):
|
||||||
exp = list(expand_solution(sol, width, pattern))
|
exp = list(expand_solution(sol, width, pattern))
|
||||||
|
count += 1
|
||||||
if len(invs) == 0:
|
if len(invs) == 0:
|
||||||
invs = exp
|
invs = exp
|
||||||
else:
|
else:
|
||||||
for i, e in enumerate(exp):
|
for i, e in enumerate(exp):
|
||||||
if invs[i] != e:
|
if invs[i] != e:
|
||||||
invs[i] = -1
|
invs[i] = -1
|
||||||
return invs
|
return count, invs
|
||||||
|
|
||||||
def visual(constraints):
|
def visual(constraints):
|
||||||
"returns a visual representation of constraints"
|
"returns a visual representation of constraints"
|
||||||
return "".join({
|
return "".join({1:'\N{LEFT SEVEN EIGHTHS BLOCK}', 0:'.', -1:'?'}[x] for x in constraints)
|
||||||
1:'\N{FULL BLOCK}\N{LEFT SEVEN EIGHTHS BLOCK}',
|
|
||||||
0:'__',
|
|
||||||
-1:'??'
|
|
||||||
}[x] for x in constraints)
|
|
||||||
|
|
||||||
class Board:
|
class Board:
|
||||||
"""Board
|
"""Board
|
||||||
|
@ -122,17 +119,17 @@ class Board:
|
||||||
for i in range(self.height):
|
for i in range(self.height):
|
||||||
self.rows[i] = [-1] * self.width
|
self.rows[i] = [-1] * self.width
|
||||||
|
|
||||||
# print("rows:")
|
print("rows:")
|
||||||
# for y in range(self.height):
|
for y in range(self.height):
|
||||||
# n, c = invariants(self.width, self.row_patterns[y])
|
n, c = invariants(self.width, self.row_patterns[y])
|
||||||
# print(n, self.row_patterns[y], visual(c))
|
print(n, self.row_patterns[y], visual(c))
|
||||||
|
|
||||||
# print("cols:")
|
print("cols:")
|
||||||
# for x in range(self.height):
|
for x in range(self.height):
|
||||||
# n, c = invariants(self.width, self.col_patterns[x])
|
n, c = invariants(self.width, self.col_patterns[x])
|
||||||
# print(n, self.col_patterns[x], visual(c))
|
print(n, self.col_patterns[x], visual(c))
|
||||||
|
|
||||||
# print(self.row(0))
|
print(self.row(0))
|
||||||
|
|
||||||
def col(self, i):
|
def col(self, i):
|
||||||
"""a column"""
|
"""a column"""
|
||||||
|
@ -142,121 +139,37 @@ class Board:
|
||||||
"""a row"""
|
"""a row"""
|
||||||
return self.rows[i]
|
return self.rows[i]
|
||||||
|
|
||||||
def replace_row(self, i, row):
|
def solve(self):
|
||||||
self.rows[i] = row
|
min_row_index = 0
|
||||||
|
min_row_count = 0
|
||||||
def replace_col(self, i , col):
|
|
||||||
for y in range(self.height):
|
for y in range(self.height):
|
||||||
self.rows[y][i] = col[y]
|
count = 0
|
||||||
|
|
||||||
|
|
||||||
def compute_invariants(self):
|
|
||||||
while True:
|
|
||||||
changed = False
|
|
||||||
|
|
||||||
row_sols = [0] * self.height
|
|
||||||
col_sols = [0] * self.width
|
|
||||||
|
|
||||||
# rows
|
|
||||||
for y in range(self.height):
|
|
||||||
invs = None; count = 0
|
|
||||||
for sol in solve2(self.width, self.row_patterns[y], self.row(y)):
|
for sol in solve2(self.width, self.row_patterns[y], self.row(y)):
|
||||||
count += 1
|
count += 1
|
||||||
exp = list(expand_solution(sol, self.width, self.row_patterns[y]))
|
if count < min_row_count:
|
||||||
if invs == None:
|
min_row_count = count
|
||||||
invs = exp
|
min_row_index = y
|
||||||
for i, e in enumerate(exp):
|
|
||||||
if invs[i] != e:
|
|
||||||
invs[i] = -1
|
|
||||||
if invs != None and self.row(y) != invs:
|
|
||||||
self.replace_row(y, invs)
|
|
||||||
changed = True
|
|
||||||
row_sols[y] = count
|
|
||||||
|
|
||||||
# columns
|
|
||||||
for x in range(self.width):
|
|
||||||
invs = None; count = 0
|
|
||||||
for sol in solve2(self.height, self.col_patterns[x], self.col(x)):
|
|
||||||
count += 1
|
|
||||||
exp = list(expand_solution(sol, self.height, self.col_patterns[x]))
|
|
||||||
if invs == None:
|
|
||||||
invs = exp
|
|
||||||
for i, e in enumerate(exp):
|
|
||||||
if invs[i] != e:
|
|
||||||
invs[i] = -1
|
|
||||||
if invs != None and self.col(x) != invs:
|
|
||||||
self.replace_col(x, invs)
|
|
||||||
changed = True
|
|
||||||
col_sols[x] = count
|
|
||||||
|
|
||||||
if not changed:
|
|
||||||
break
|
|
||||||
|
|
||||||
return row_sols, col_sols
|
|
||||||
|
|
||||||
def solve(self, solved=lambda x: None, depth=0):
|
|
||||||
row_sols, col_sols = self.compute_invariants()
|
|
||||||
# if depth < 2:
|
|
||||||
# print("depth:", depth)
|
|
||||||
# print(self)
|
|
||||||
# print("row_sols:", row_sols)
|
|
||||||
# print("col_sols:", col_sols)
|
|
||||||
|
|
||||||
if min(row_sols) == 0 or min(col_sols) == 0:
|
|
||||||
return False
|
|
||||||
|
|
||||||
if max(row_sols) == 1:
|
|
||||||
print("solved")
|
|
||||||
solved(self)
|
|
||||||
return True
|
|
||||||
|
|
||||||
min_row, y = min((a,b) for b,a in enumerate(row_sols) if a > 1)
|
|
||||||
min_col, x = min((a,b) for b,a in enumerate(col_sols) if a > 1)
|
|
||||||
|
|
||||||
if min_row < min_col:
|
|
||||||
for sol in solve2(self.width, self.row_patterns[y], self.row(y)):
|
|
||||||
b = self.copy()
|
|
||||||
b.replace_row(y, expand_solution(sol, self.width, self.row_patterns[y]))
|
|
||||||
if b.solve(solved, depth + 1):
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
for sol in solve2(self.height, self.col_patterns[x], self.col(x)):
|
|
||||||
b = self.copy()
|
|
||||||
b.replace_col(x, expand_solution(sol, self.height, self.col_patterns[x]))
|
|
||||||
if b.solve(solved, depth + 1):
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def copy(self):
|
pass
|
||||||
newboard = Board((self.col_patterns, self.row_patterns))
|
|
||||||
for i in range(self.height):
|
|
||||||
newboard.rows[i] = self.rows[i][:]
|
|
||||||
return newboard
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
s = ""
|
|
||||||
for y in range(self.height):
|
|
||||||
s += visual(self.rows[y])
|
|
||||||
s += "\n"
|
|
||||||
return s
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
def draw(solution, width, pattern):
|
def draw(solution, width, pattern):
|
||||||
"draws a solution"
|
"draws a solution"
|
||||||
for s, p in zip(solution, pattern):
|
for s, p in zip(solution, pattern):
|
||||||
print('__' * s, end="")
|
print('.' * s, end="")
|
||||||
print('\N{FULL BLOCK}\N{LEFT SEVEN EIGHTHS BLOCK}' * p, end="")
|
print('\N{LEFT SEVEN EIGHTHS BLOCK}' * p, end="")
|
||||||
print('__' * (width - sum(solution) - sum(pattern)))
|
print('.' * (width - sum(solution) - sum(pattern)))
|
||||||
|
|
||||||
# width = int(sys.argv[1])
|
width = int(sys.argv[1])
|
||||||
# pattern = tuple(int(x) for x in sys.argv[2].split())
|
pattern = tuple(int(x) for x in sys.argv[2].split())
|
||||||
# constraints = [-1] * width
|
constraints = [-1] * width
|
||||||
# try:
|
try:
|
||||||
# for i, c in enumerate(sys.argv[3]):
|
for i, c in enumerate(sys.argv[3]):
|
||||||
# constraints[i] = {'1':1, '0':0, '?':-1}[c]
|
constraints[i] = {'1':1, '0':0, '?':-1}[c]
|
||||||
# except:
|
except:
|
||||||
# constraints = [-1] * width
|
constraints = [-1] * width
|
||||||
|
|
||||||
# for solution in solve1(width, pattern):
|
# for solution in solve1(width, pattern):
|
||||||
# e = expand_solution(solution, width, pattern)
|
# e = expand_solution(solution, width, pattern)
|
||||||
|
@ -269,54 +182,18 @@ if __name__ == "__main__":
|
||||||
rows = [[int(y) for y in x.strip().split()] for x in rows]
|
rows = [[int(y) for y in x.strip().split()] for x in rows]
|
||||||
return rows
|
return rows
|
||||||
|
|
||||||
def parse_constraints(s, width):
|
|
||||||
constraints = [-1] * width
|
|
||||||
for i, c in enumerate(s):
|
|
||||||
constraints[i] = {'1':1, '0':0, '?':-1, '.':0, '\N{LEFT SEVEN EIGHTHS BLOCK}': 1}[c]
|
|
||||||
return constraints
|
|
||||||
|
|
||||||
# width = 15
|
b = Board((
|
||||||
# pattern = (1, 1, 1, 2)
|
parse("""1 1 1 1 1, 1 1 1, 1 1 1 1, 1 2, 1 1 1 1, 1 1 1, 1 1 1,
|
||||||
# constraints = parse_constraints('????????010?', width)
|
3 1, 1 1, 1 2 6 1, 2 1, 2 3 1, 1 1, 1 1 3 1, 2 1 1"""),
|
||||||
# for sol in solve2(width, pattern, constraints):
|
parse("""1 2, 1 1 2, 2 1 1 1 1, 3 1, 1 1 1 1, 1 2 1, 1, 1 1 1 2,
|
||||||
# draw(sol, width, pattern)
|
2 2 1 1, 1 1 1 1 1, 1 2 2, 2 2, 1 1 1 1 1, 1 1 1 1, 1 1""")
|
||||||
|
|
||||||
# b = Board((
|
|
||||||
# parse("1 1 1, 1 1 1, 1 1 1, 1 1 1, 1 1 1, 1 1 1"),
|
|
||||||
# parse("1 1 1, 1 1 1, 1 1 1, 1 1 1, 1 1 1, 1 1 1")
|
|
||||||
# ))
|
|
||||||
# b.solve(print)
|
|
||||||
|
|
||||||
# b = Board((
|
|
||||||
# parse("""1 1 1 1 1, 1 1 1, 1 1 1 1, 1 2, 1 1 1 1, 1 1 1, 1 1 1,
|
|
||||||
# 3 1, 1 1, 1 2 6 1, 2 1, 2 3 1, 1 1, 1 1 3 1, 2 1 1"""),
|
|
||||||
# parse("""1 2, 1 1 2, 2 1 1 1 1, 3 1, 1 1 1 1, 1 2 1, 1, 1 1 1 2,
|
|
||||||
# 2 2 1 1, 1 1 1 1 1, 1 2 2, 2 2, 1 1 1 1 1, 1 1 1 1, 1 1""")
|
|
||||||
# ))
|
|
||||||
# b.solve(print)
|
|
||||||
|
|
||||||
# b = Board((
|
|
||||||
# parse("""2 4, 1 1 3 1, 6, 3 3, 3 4, 1 3 2, 3 4 1, 3 5 1 1, 12,
|
|
||||||
# 5 3 3, 6 4, 2 3, 1 2 2, 3 4, 3 5"""),
|
|
||||||
# parse("""1 6, 2 2 4 2, 3 5 2, 11, 1 6 1, 4 1 5, 5 3 3, 10 2, 1 7 1 1, 5 1 1 1,
|
|
||||||
# 1 3 1, 3, 3, 1 1, 3"""),
|
|
||||||
# ))
|
|
||||||
# b.solve()
|
|
||||||
|
|
||||||
c = Board((
|
|
||||||
parse("""1 5 2, 1 1 2, 1 1 2 1 2, 2 2, 2 1 1 1, 1 1 1, 1 1, 1 1 1, 2 3 1 1,
|
|
||||||
1 2 3 1 1, 1 3 1 1, 2 1 1 1, 1 1 1 2 1, 1 1 1 2 1, 2 1"""),
|
|
||||||
parse("""1 2 1 1, 1 1 4, 2 1, 1 1 1 1 2, 1 3 1 1, 1 2, 1 1 1 1 1 1,
|
|
||||||
1 1 1 1 1 2, 1 1 2, 1 2 1 1, 3 1 4, 1 4 1, 3, 3 1 1, 1 2 1""")
|
|
||||||
))
|
))
|
||||||
c.solve(print)
|
|
||||||
|
|
||||||
# c = Board(([[2, 1], [2, 1, 1], [1, 1, 1, 1], [2, 1], [1, 1, 1], [1, 1, 1, 1], [3], [3, 2, 1], [1, 1, 3, 1],
|
# c = Board((
|
||||||
# [1, 1, 1, 1], [1, 2, 1, 1, 1], [1, 1, 1, 1], [1, 2, 1], [1], [1, 4, 1]],
|
# parse("""1 5 2, 1 1 2, 1 1 2 1 2, 2 2, 2 1 1 1, 1 1 1, 1 1, 1 1 1, 2 3 1 1,
|
||||||
# [[1, 2, 1], [1, 3, 1], [1, 1, 3], [1, 1, 1], [1, 1], [1, 1], [1, 2, 1, 1, 1], [2, 3, 3, 1, 1],
|
# 1 2 3 1 1, 1 3 1 1, 2 1 1 1, 1 1 1 2 1, 1 1 1 2 1, 2 1"""),
|
||||||
# [1, 1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1], [1, 2], [1, 1], [1, 1, 1]]))
|
# parse("""1 2 1 1, 1 1 4, 2 1, 1 1 1 1 2, 1 3 1 1, 1 2, 1 1 1 1 1 1,
|
||||||
# c.solve(print)
|
# 1 1 1 1 1 2, 1 1 2, 1 2 1 1, 3 1 4, 1 4 1, 3, 3 1 1, 1 2 1""")
|
||||||
|
# ))
|
||||||
|
|
||||||
if len(sys.argv) > 2:
|
|
||||||
b = Board((parse(sys.argv[1]), parse(sys.argv[2])))
|
|
||||||
b.solve(print)
|
|
||||||
|
|
Loading…
Reference in a new issue