solution work
This commit is contained in:
parent
54b6f58333
commit
2264ff4663
102
main.py
102
main.py
@ -1,4 +1,5 @@
|
||||
import itertools
|
||||
from copy import deepcopy
|
||||
from itertools import combinations, combinations_with_replacement
|
||||
|
||||
OP_PLUS = "PLUS"
|
||||
@ -24,7 +25,7 @@ OP_LAMBDAS = {
|
||||
}
|
||||
|
||||
BOX_H_LABELS = 'ABCDEF'
|
||||
BOX_V_LABELS = '123456'
|
||||
BOX_V_LABELS = '654321'
|
||||
|
||||
|
||||
class Block(object):
|
||||
@ -33,7 +34,7 @@ class Block(object):
|
||||
self.operation = operation
|
||||
self.result = result
|
||||
|
||||
self.solutions = []
|
||||
self.solutions = set()
|
||||
|
||||
self.verify()
|
||||
|
||||
@ -86,20 +87,49 @@ class Block(object):
|
||||
self.generate_hypotheses(grid_size)
|
||||
for hyp in self.generate_hypotheses(grid_size):
|
||||
for perm in itertools.permutations(hyp):
|
||||
sol = list(zip(self.boxes, perm))
|
||||
self.solutions.append(sol)
|
||||
sol = tuple(zip(self.boxes, perm))
|
||||
self.solutions.add(sol)
|
||||
|
||||
def __repr__(self):
|
||||
return 'Block {}'.format(self.boxes)
|
||||
|
||||
|
||||
def translate_box_to_rc(box):
|
||||
return BOX_V_LABELS.index(box[1]), BOX_H_LABELS.index(box[0])
|
||||
|
||||
|
||||
def has_line_integrity(line):
|
||||
existing_values = set()
|
||||
for value in line:
|
||||
if value in existing_values:
|
||||
return False
|
||||
if value != 0:
|
||||
existing_values.add(value)
|
||||
return True
|
||||
|
||||
|
||||
def fill_grid(grid, solution):
|
||||
box_values = []
|
||||
for box_value in solution:
|
||||
box_values.append(box_value)
|
||||
for box, value in box_values:
|
||||
br, bc = translate_box_to_rc(box)
|
||||
grid[br][bc] = value
|
||||
return grid
|
||||
|
||||
|
||||
class Game(object):
|
||||
def __init__(self, grid_size, blocks):
|
||||
self.blocks = blocks
|
||||
self.grid_size = grid_size
|
||||
self.grid = [[0] * grid_size] * grid_size
|
||||
self.verify()
|
||||
|
||||
for block in self.blocks:
|
||||
block.generate_solutions(self.grid_size)
|
||||
|
||||
def init_grid(self):
|
||||
return [[0] * self.grid_size for _ in range(self.grid_size)]
|
||||
|
||||
def verify(self):
|
||||
found = set()
|
||||
for block in self.blocks:
|
||||
@ -116,34 +146,52 @@ class Game(object):
|
||||
rv.add(block)
|
||||
return rv
|
||||
|
||||
def solve(self):
|
||||
for block in self.blocks:
|
||||
block.generate_solutions(self.grid_size)
|
||||
# row_permutations = itertools.permutations(1, self.grid_size + 1)
|
||||
for row_id, row in enumerate(self.grid):
|
||||
for col_id, cell in enumerate(row):
|
||||
self.grid[row_id][col_id] = self.generate_possible_cell_values(row_id, col_id)
|
||||
def check_grid(self, grid):
|
||||
for row in grid:
|
||||
if not has_line_integrity(row):
|
||||
return False
|
||||
for col_id in range(self.grid_size):
|
||||
col = [grid[r][col_id] for r in range(self.grid_size)]
|
||||
if not has_line_integrity(col):
|
||||
return False
|
||||
return True
|
||||
|
||||
def solve(self, grid, current_block_id=0):
|
||||
block = self.blocks[current_block_id]
|
||||
for solution in block.solutions:
|
||||
prev_grid = deepcopy(grid)
|
||||
grid = fill_grid(grid, solution)
|
||||
if not self.check_grid(grid):
|
||||
grid = prev_grid
|
||||
else:
|
||||
if current_block_id == len(self.blocks) - 1:
|
||||
return grid
|
||||
sol = self.solve(deepcopy(grid), current_block_id + 1)
|
||||
if sol:
|
||||
return sol
|
||||
|
||||
|
||||
def main():
|
||||
game = Game(grid_size=6,
|
||||
blocks=[
|
||||
Block(boxes=['A6', 'A5'], operation=OP_MINUS, result=2),
|
||||
Block(boxes=['B6', 'C6', 'C5'], operation=OP_MULTIPLY, result=20),
|
||||
Block(boxes=['D6', 'D5', 'E5'], operation=OP_PLUS, result=11),
|
||||
Block(boxes=['E6', 'F6', 'F5'], operation=OP_MULTIPLY, result=18),
|
||||
Block(boxes=['A4', 'B4', 'B5'], operation=OP_PLUS, result=9),
|
||||
Block(boxes=['C4', 'D4'], operation=OP_MINUS, result=5),
|
||||
Block(boxes=['E4', 'F4', 'E3', 'F3'], operation=OP_MULTIPLY, result=80),
|
||||
Block(boxes=['D3', 'C3'], operation=OP_MINUS, result=1),
|
||||
Block(boxes=['A3', 'B3', 'B2'], operation=OP_PLUS, result=12),
|
||||
Block(boxes=['C2', 'D2'], operation=OP_DIVIDE, result=2),
|
||||
Block(boxes=['A1', 'A2'], operation=OP_PLUS, result=5),
|
||||
Block(boxes=['B1'], operation=OP_NONE, result=6),
|
||||
Block(boxes=['C1', 'D1', 'E1'], operation=OP_MULTIPLY, result=60),
|
||||
Block(boxes=['F1', 'E2', 'F2'], operation=OP_MULTIPLY, result=9),
|
||||
Block(boxes=['A6', 'B6', 'C6', 'D6'], operation=OP_MULTIPLY, result=120),
|
||||
Block(boxes=['E6', 'E5', 'E4', 'F4'], operation=OP_PLUS, result=17),
|
||||
Block(boxes=['F6', 'F5'], operation=OP_PLUS, result=5),
|
||||
Block(boxes=['A5', 'B5'], operation=OP_MINUS, result=1),
|
||||
Block(boxes=['C5', 'C4'], operation=OP_DIVIDE, result=2),
|
||||
Block(boxes=['D5', 'D4'], operation=OP_PLUS, result=3),
|
||||
Block(boxes=['A4', 'A3'], operation=OP_PLUS, result=5),
|
||||
Block(boxes=['B4', 'B3', 'C3'], operation=OP_MULTIPLY, result=30),
|
||||
Block(boxes=['D3', 'D2', 'E2'], operation=OP_MULTIPLY, result=15),
|
||||
Block(boxes=['B2', 'C2', 'C1'], operation=OP_MULTIPLY, result=10),
|
||||
Block(boxes=['A2'], operation=OP_NONE, result=6),
|
||||
Block(boxes=['A1', 'B1'], operation=OP_DIVIDE, result=3),
|
||||
Block(boxes=['D1', 'E1'], operation=OP_MINUS, result=1),
|
||||
Block(boxes=['F1', 'F2', 'F3', 'E3'], operation=OP_PLUS, result=16),
|
||||
])
|
||||
game.solve()
|
||||
grid = game.solve(grid=game.init_grid())
|
||||
for line in grid:
|
||||
print(line)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
Loading…
Reference in New Issue
Block a user