From 25d683ffef5bbe951b248e0a6f8a3a5e93512e9c Mon Sep 17 00:00:00 2001 From: daviddoji Date: Mon, 30 Aug 2021 15:04:53 +0200 Subject: [PATCH] Module 16: Solver Class (Python code) --- a.py | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 128 insertions(+), 13 deletions(-) diff --git a/a.py b/a.py index 9bd8948..451a6ec 100644 --- a/a.py +++ b/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) \ No newline at end of file