IDK what this WIP is

This commit is contained in:
Eryn Wells 2017-10-06 20:27:01 -07:00
parent 6cc3fed4b3
commit e004d319e3

View file

@ -140,15 +140,18 @@ class Board(dict):
# Chose the square with the fewest possible values. # Chose the square with the fewest possible values.
_, smallest = min((len(self[sq]), sq) for sq in self if len(self[sq]) > 1) _, smallest = min((len(self[sq]), sq) for sq in self if len(self[sq]) > 1)
# Deepcopy the board. # Deepcopy the board.
trials = []
for v in self[smallest]: for v in self[smallest]:
trial_board = copy.deepcopy(self) trial_board = copy.deepcopy(self)
try: if trial_board.assign(smallest, [v]):
trial_board.assign(smallest, [v]) trials.append(trial_board)
if trial_board.search(): trial_board.search()
return trial_board else:
except ValueError: trials.append(None)
continue for t in trials:
raise ValueError('No possible solution found.') if t is not None:
return t
return False
def assign(self, square, value): def assign(self, square, value):
@ -159,12 +162,8 @@ class Board(dict):
LOG.debug('Assigning values {} to square {}.'.format(value, square)) LOG.debug('Assigning values {} to square {}.'.format(value, square))
removed_values = set(self[square]) - set(value) removed_values = set(self[square]) - set(value)
for v in removed_values: for v in removed_values:
try: if not self.eliminate(square, v):
self.eliminate(square, v) return False
except ValueError:
raise
# TODO: To make this work right, I should probably also do the same as above for the values added *back* into
# the values for {square}.
return True return True
def eliminate(self, square, value): def eliminate(self, square, value):
@ -186,25 +185,24 @@ class Board(dict):
if len(self[square]) == 0: if len(self[square]) == 0:
# Whoops. Removed the last value... We have a contradiction now. # Whoops. Removed the last value... We have a contradiction now.
LOG.error('Removed last value from square {}'.format(square)) LOG.error('Removed last value from square {}'.format(square))
raise ValueError('Removed last value from square {}; board is now invalid'.format(square)) return False
elif len(self[square]) == 1: elif len(self[square]) == 1:
# One value left in this square. Propagate changes to its peers. # One value left in this square. Propagate changes to its peers.
LOG.debug('One value left in square {}; eliminating {} from its peers'.format(square, self[square][0])) LOG.debug('One value left in square {}; eliminating {} from its peers'.format(square, self[square][0]))
try:
for peer in self.peers(*square): for peer in self.peers(*square):
self.eliminate(peer, self[square][0]) if not self.eliminate(peer, self[square][0]):
except ValueError: return False
raise
# (2) If a unit has only one square for a value, put it there. # (2) If a unit has only one square for a value, put it there.
for unit in (self.row(square[1]), self.col(square[0]), self.box(*square)): for unit in (self.row(square[1]), self.col(square[0]), self.box(*square)):
places = [sq for sq in unit if value in unit[sq]] places = [sq for sq in unit if value in unit[sq]]
if len(places) == 0: if len(places) == 0:
LOG.error('No place for value {} to go in unit {}'.format(value, unit)) LOG.error('No place for value {} to go in unit {}'.format(value, unit))
raise ValueError('No place for value {} to go in unit {}; board is now invalid'.format(value, unit)) return False
elif len(places) == 1: elif len(places) == 1:
LOG.debug('One place for value {} to be in unit {}; setting'.format(value, unit)) LOG.debug('One place for value {} to be in unit {}; setting'.format(value, unit))
self.assign(places[0], [value]) self.assign(places[0], [value])
return True return True
def __delitem__(self, key): def __delitem__(self, key):