Module 16: Solver Class (Python code)
This commit is contained in:
parent
b587e75022
commit
25d683ffef
141
a.py
141
a.py
@ -1,8 +1,9 @@
|
||||
from copy import copy
|
||||
from copy import copy, deepcopy
|
||||
|
||||
def ToUpper(s):
|
||||
return s.upper()
|
||||
|
||||
|
||||
## ----------------------------------------------------------------------------
|
||||
##-Point
|
||||
class Point:
|
||||
@ -35,6 +36,7 @@ class Spans:
|
||||
def __str__(self):
|
||||
return f'[{self.point} len={self.len} vert={self.vert}]'
|
||||
|
||||
|
||||
## ----------------------------------------------------------------------------
|
||||
##-Words
|
||||
class Words:
|
||||
@ -56,7 +58,7 @@ class Library:
|
||||
|
||||
# Returns NULL if can't find any matches to the given pattern
|
||||
def FindWord(self, s):
|
||||
print(list(key for key, values in self.word_map_.items() if s in values))
|
||||
return [key for key, values in self.word_map_.items() if s in values]
|
||||
|
||||
def IsWord(self, s):
|
||||
return s in self.word_map_
|
||||
@ -83,8 +85,6 @@ class Library:
|
||||
|
||||
def CreatePatternHash(self, w):
|
||||
len_w = len(w)
|
||||
if len_w > 7:
|
||||
return
|
||||
num_patterns = 1 << len_w
|
||||
# print(f"PATTERN HASH on {w}")
|
||||
self.word_map_[w] = []
|
||||
@ -111,7 +111,31 @@ class Library:
|
||||
for i, (k,v) in enumerate(self.word_map_.items()):
|
||||
print(f"[{i}] {len(v)}")# {self.word_map_[i]}")
|
||||
|
||||
lib = Library()
|
||||
|
||||
|
||||
## ----------------------------------------------------------------------------
|
||||
##-Attr
|
||||
class Attr:
|
||||
|
||||
has_letters = False
|
||||
has_blanks = False
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def is_empty():
|
||||
return (Attr.has_blanks and not Attr.has_letters)
|
||||
|
||||
def is_partial():
|
||||
return (Attr.has_blanks and Attr.has_letters)
|
||||
|
||||
def is_full():
|
||||
return (not Attr.has_blanks and Attr.has_letters)
|
||||
|
||||
|
||||
## ----------------------------------------------------------------------------
|
||||
##-Grid
|
||||
class Grid:
|
||||
|
||||
def __init__(self, n):
|
||||
@ -153,12 +177,17 @@ class Grid:
|
||||
return p.row >= 0 and p.row < self.rows() and p.col >= 0 and p.col < self.cols()
|
||||
|
||||
# Fills in attributes of the string
|
||||
def GetString(self, sp):
|
||||
def GetString(self, sp, attr):
|
||||
len_ = sp.len
|
||||
temp = []
|
||||
for i in range(len_):
|
||||
p = sp.GetPoint(i)
|
||||
temp.append(self.box(p))
|
||||
c = self.box(p)
|
||||
if c == '-':
|
||||
attr.has_blanks = True
|
||||
elif c >= 'A' and c <= 'Z':
|
||||
attr.has_letters = True
|
||||
temp.append(c)
|
||||
return ''.join(temp)
|
||||
|
||||
# Next increments the point across the grid, one box at a time
|
||||
@ -176,6 +205,24 @@ class Grid:
|
||||
p.row += 1
|
||||
return self.in_bounds(p)
|
||||
|
||||
# NextStopAtWrap is like "Next" except it returns False at every wrap
|
||||
# Returns True if we stay in the same line
|
||||
def NextStopAtWrap(self, p, vert):
|
||||
wrap = False
|
||||
if vert:
|
||||
p.row += 1
|
||||
if p.row >= self.rows():
|
||||
p.row = 0
|
||||
p.col += 1
|
||||
wrap = True
|
||||
else:
|
||||
p.col += 1
|
||||
if p.col >= self.cols():
|
||||
p.col = 0
|
||||
p.row += 1
|
||||
wrap = True
|
||||
return not wrap
|
||||
|
||||
def FillSpans_(self, vert):
|
||||
p = Point()
|
||||
while (self.in_bounds(p)):
|
||||
@ -187,8 +234,9 @@ class Grid:
|
||||
#print(f"SPAN START: {startp}")
|
||||
|
||||
len_ = 0
|
||||
while (self.in_bounds(p) and not self.is_block(p)):
|
||||
self.Next(p, vert)
|
||||
keep_going = True
|
||||
while (keep_going and not self.is_block(p)):
|
||||
keep_going = self.NextStopAtWrap(p, vert)
|
||||
len_ += 1
|
||||
#print(f"END OF SPAN!!! len={len_}")
|
||||
self.sp.append(Spans(startp, len_, vert))
|
||||
@ -219,16 +267,83 @@ class Grid:
|
||||
def PrintSpans(self):
|
||||
print(f"Spans:")
|
||||
for span in self.sp:
|
||||
print(f" {span} {self.GetString(span)}")
|
||||
print(f" {span} {self.GetString(span, Attr())}")
|
||||
|
||||
## ----------------------------------------------------------------------------
|
||||
##-Slot
|
||||
class Slot:
|
||||
|
||||
slots = []
|
||||
|
||||
def __init__(self, s, p):
|
||||
self.span = s
|
||||
self.pattern = p
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.span} '{self.pattern}'"
|
||||
|
||||
|
||||
## ----------------------------------------------------------------------------
|
||||
##-Solver
|
||||
class Solver:
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def Solve(self, grid):
|
||||
print(f"Solving this grid")
|
||||
grid.Print()
|
||||
self.Loop(grid)
|
||||
|
||||
def Loop(self, grid):
|
||||
empty_slots = []
|
||||
partial_slots = [] # these are the ones we want to work on
|
||||
full_slots = []
|
||||
for s in grid.sp:
|
||||
attr = Attr
|
||||
temp = grid.GetString(s, attr)
|
||||
if attr.is_empty():
|
||||
empty_slots.append(Slot(s, temp))
|
||||
elif attr.is_partial():
|
||||
partial_slots.append(Slot(s, temp))
|
||||
elif attr.is_full():
|
||||
full_slots.append(Slot(s, temp))
|
||||
Attr.has_letters = False
|
||||
Attr.has_blanks = False
|
||||
num_empty = len(empty_slots)
|
||||
num_partial = len(partial_slots)
|
||||
num_full = len(full_slots)
|
||||
print(f"empty = {num_empty}")
|
||||
print(f"partial = {num_partial}")
|
||||
print(f"full = {num_full}")
|
||||
|
||||
if (num_partial == 0 and num_empty == 0):
|
||||
print("SOLUTION!!")
|
||||
# FIX what do we do here?
|
||||
|
||||
assert(num_partial > 0)
|
||||
self.CommitSlot(grid, partial_slots[0])
|
||||
|
||||
def CommitSlot(self, grid, slot):
|
||||
grid = deepcopy(grid)
|
||||
print(f"COMMIT slot {slot}")
|
||||
print(f"Possible word choices for this slot are:")
|
||||
|
||||
words = lib.FindWord(slot.pattern)
|
||||
if words:
|
||||
print(f"{' '.join(words)}")
|
||||
else:
|
||||
print("NO MATCHES to pattern")
|
||||
|
||||
## ----------------------------------------------------------------------------
|
||||
if __name__ == "__main__":
|
||||
grid = Grid("MY GRID")
|
||||
grid.LoadFromFile("test")
|
||||
grid.LoadFromFile('test')
|
||||
grid.Check()
|
||||
grid.Print()
|
||||
grid.FillSpans()
|
||||
grid.PrintSpans()
|
||||
|
||||
lib = Library()
|
||||
lib.ReadFromFile("top_12000.txt", grid.max_size())
|
||||
|
||||
|
||||
solver = Solver()
|
||||
solver.Solve(grid)
|
Loading…
x
Reference in New Issue
Block a user