IDK what this WIP is
This commit is contained in:
parent
6cc3fed4b3
commit
e004d319e3
1 changed files with 18 additions and 20 deletions
36
sudoku.py
36
sudoku.py
|
@ -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):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue