Solve a row with constraints
This commit is contained in:
parent
4f44c1442a
commit
a4d3ac9247
1 changed files with 47 additions and 11 deletions
58
main.py
58
main.py
|
@ -3,13 +3,12 @@
|
|||
from itertools import combinations_with_replacement
|
||||
|
||||
|
||||
def row_solutions(width, pattern):
|
||||
def solve1(width, pattern):
|
||||
"""
|
||||
This yields a tuple for each possible layout of
|
||||
pattern inside the row. The tuple elements are the
|
||||
amount of cells that must be inserted before each
|
||||
block in pattern. The tuple doesn't include the
|
||||
number of cells at the end of the row since that's
|
||||
gaps before each block in pattern.
|
||||
The tuple doesn't include the last gap, since that's
|
||||
just: width - sum(sol) - sum(pattern)
|
||||
"""
|
||||
spaces = width - (sum(pattern) + len(pattern) - 1)
|
||||
|
@ -31,7 +30,7 @@ def expand_solution(solution, width, pattern):
|
|||
|
||||
def matches(expanded_solution, constraints):
|
||||
"""
|
||||
solution is a tuple of spaces, the output of row_solutions
|
||||
solution is a tuple of spaces, the output of solve1
|
||||
constraints is a tuple of values from 1, 0 and -1, that
|
||||
mean:
|
||||
0 -> OFF
|
||||
|
@ -46,6 +45,41 @@ def matches(expanded_solution, constraints):
|
|||
return True
|
||||
|
||||
|
||||
def solve2(width, pattern, constraints=None):
|
||||
"""
|
||||
@width: int
|
||||
@pattern: sequence of ints
|
||||
@constraints: optional list of length width containing 1,0,-1 as elements
|
||||
|
||||
Does the same as solve1, but takes constraints
|
||||
in consideration to be faster than solve1 + matches
|
||||
"""
|
||||
|
||||
if len(pattern) == 0:
|
||||
return tuple()
|
||||
|
||||
if constraints is None:
|
||||
constraints = [-1] * width
|
||||
|
||||
p = pattern[0]
|
||||
|
||||
# the first gap can go from 0 to the following, inclusive
|
||||
maxgap = width - sum(pattern[1:]) - (len(pattern) - 1) - p
|
||||
|
||||
for gap in range(maxgap + 1):
|
||||
e = expand_solution((gap,), gap + p + 1, (p,))
|
||||
if not matches(e, constraints[:gap + p + 1]):
|
||||
continue
|
||||
if len(pattern) == 1:
|
||||
yield (gap,)
|
||||
continue
|
||||
subwidth = width - gap - p - 1
|
||||
subpattern = pattern[1:]
|
||||
subconstraints = constraints[-subwidth:]
|
||||
for s in solve2(subwidth, subpattern, subconstraints):
|
||||
yield (gap,s[0]+1) + s[1:]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
import sys
|
||||
|
@ -53,7 +87,7 @@ if __name__ == "__main__":
|
|||
def draw(solution, width, pattern):
|
||||
for s,p in zip(solution, pattern):
|
||||
print('.' * s, end="")
|
||||
print('\N{FULL BLOCK}' * p, end="")
|
||||
print('\N{LEFT SEVEN EIGHTHS BLOCK}' * p, end="")
|
||||
print('.' * (width - sum(solution) - sum(pattern)))
|
||||
|
||||
width = int(sys.argv[1])
|
||||
|
@ -63,10 +97,12 @@ if __name__ == "__main__":
|
|||
for i,c in enumerate(sys.argv[3]):
|
||||
constraints[i]= {'1':1, '0':0, '?':-1}[c]
|
||||
except:
|
||||
print(sys.exc_info())
|
||||
constraints = [-1] * width
|
||||
|
||||
for solution in row_solutions(width, pattern):
|
||||
e = expand_solution(solution, width, pattern)
|
||||
if matches(e, constraints):
|
||||
draw(solution, width, pattern)
|
||||
# for solution in solve1(width, pattern):
|
||||
# e = expand_solution(solution, width, pattern)
|
||||
# if matches(e, constraints):
|
||||
# draw(solution, width, pattern)
|
||||
|
||||
for sol in solve2(width, pattern, constraints):
|
||||
draw(sol, width, pattern)
|
||||
|
|
Loading…
Reference in a new issue