Skip to content

Instantly share code, notes, and snippets.

@undergroundmonorail
Last active April 5, 2019 16:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save undergroundmonorail/ade03143a13b33f3c7cb5687d755cad8 to your computer and use it in GitHub Desktop.
Save undergroundmonorail/ade03143a13b33f3c7cb5687d755cad8 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# brute forcer of valid solutions to this bingo puzzle:
# https://i.imgur.com/50cpnw3.png
board = []
conditions = []
cells_in_bingo = []
class Cell:
def __init__(self, col, row, value, func):
self.col = col
self.row = row
self.value = value
self.func = func
self.index = self.index(col + row)
@staticmethod
def index(coords, row=None):
if row == None:
col = 'ABCDE'.index(coords[0])
row = '12345'.index(coords[1])
else:
col = coords
return row*5+col
def bingo(line):
if line in 'ABCDE':
return all((board[Cell.index(line + row)].value for row in '12345'))
elif line in '12345':
return all((board[Cell.index(col + line)].value for col in 'ABCDE'))
elif line == 'NE' or line == 'SW':
return all((board[Cell.index(c)].value for c in ('A5', 'B4', 'C3', 'D2', 'E1')))
elif line == 'NW' or line == 'SE':
return all((board[Cell.index(c)].value for c in ('A1', 'B2', 'C3', 'D4', 'E5')))
def value(coords):
return board[Cell.index(coords)].value
# row 1
conditions.append(lambda: not bingo('NE'))
conditions.append(lambda: not bingo('B') and not bingo('1'))
conditions.append(lambda: bingo('NW'))
conditions.append(lambda: value('D4'))
conditions.append(lambda: bingo('E') or bingo('1') or bingo('NE'))
# row 2
conditions.append(lambda: not value('A4'))
conditions.append(lambda: all(((bingo(col) for col in 'ABCDE'), (bingo(row) for row in '12345'), (bingo('NE') or bingo('SE')))))
conditions.append(lambda: value('C2'))
conditions.append(lambda: sum((c.value for c in board) < 17))
conditions.append(lambda: len(cells_in_bingo)%2 == 0)
# row 3
conditions.append(lambda: bingo('A') or bingo('3'))
conditions.append(lambda: sum((c.value for c in board)) - len(cells_in_bingo) > 5)
conditions.append(lambda: any((bingo('C'), bingo('3'), bingo('SE'), bingo('NE'))))
conditions.append(lambda: sum(bingo(col) for col in 'ABCDE') >= 2)
conditions.append(lambda: 25 - len(cells_in_bingo) > 10)
# row 4
conditions.append(lambda: not value('A2'))
conditions.append(lambda: bingo('D') or bingo('2'))
conditions.append(lambda: sum((value('C'+row for row in '12345') < 3)))
conditions.append(lambda: value('D1'))
conditions.append(lambda: bingo('NE') or bingo('NW'))
# row 5
conditions.append(lambda: value('E5'))
conditions.append(lambda: True) # assume this for now
conditions.append(lambda: value('C5'))
conditions.append(lambda: sum((bingo(line) for line in ('A', 'B', 'C', 'D', 'E', '1', '2', '3', '4', '5', 'NE', 'SE')) > 3))
conditions.append(lambda: value('A5'))
for row in '12345':
for col in 'ABCDE':
board.append(Cell(col, row, False, conditions[Cell.index(col+row)]))
for i in range(2**25):
# just check every combination of 25 trues and falses
values = list(map(bool, map(int, bin(i)[2:].zfill(25))))
for c, v in zip(board, values):
c.value = v
cells_in_bingo = []
if bingo('NE'):
cells_in_bingo += ['A1', 'B2', 'C3', 'D4', 'E5']
if bingo('NW'):
cells_in_bingo += ['A5', 'B4', 'C3', 'D2', 'E1']
for col in 'ABCDE':
if bingo(col):
cells_in_bingo += [col+row for row in '12345']
for row in '12345':
if bingo(row):
cells_in_bingo += [col+row for col in 'ABCDE']
cells_in_bingo = list(set(cells_in_bingo)) # remove duplicates
if i%10000 == 0:
print('Checking board {}/{}'.format(i, 2**25))
if all((c.value == c.func() for c in board)):
print('Solution found!!!!!')
with open('bingo_solutions', 'a') as f:
f.write(bin(i)[2:].zfill(25) + '\n')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment