14
14
import readline
15
15
import atexit
16
16
from wsutils import Pattern , Catalog
17
+ from time import perf_counter_ns
18
+
19
+ #---------------------------------------------------------------------------
20
+ def tictocDo (func , name , * args , ** kwargs ):
21
+ tic = perf_counter_ns ()
22
+ retval = func (* args , ** kwargs )
23
+ toc = perf_counter_ns ()
24
+ duration = (toc - tic ) / 10 ** 9
25
+ print (f"{ name :<42} took { duration :>2.4f} S" )
26
+ return retval
17
27
18
28
#---------------------------------------------------------------------------
19
29
class Letters :
@@ -103,7 +113,7 @@ def _bits(cls, letters):
103
113
104
114
#---------------------------------------------------------------------------
105
115
class Cipher :
106
- def __init__ (self , crypted , decrypted = "" ):
116
+ def __init__ (self , crypted , decrypted = "" , noLetterToItself = False ):
107
117
self .map = {}
108
118
processed = set ()
109
119
for cipherLetter , plainLetter in zip_longest (crypted , decrypted ):
@@ -112,7 +122,10 @@ def __init__(self, crypted, decrypted=""):
112
122
self .map [cipherLetter ] = Letters (plainLetter )
113
123
processed .add (cipherLetter )
114
124
else :
115
- self .map [cipherLetter ] = Letters .all ()
125
+ letters = Letters .all ()
126
+ if noLetterToItself :
127
+ letters .unset (cipherLetter )
128
+ self .map [cipherLetter ] = letters
116
129
if decrypted :
117
130
self .reduce ()
118
131
@@ -277,7 +290,11 @@ def sharedLetters(self, word2):
277
290
shared = self .cryptedLetters & word2 .cryptedLetters
278
291
return "" .join (sorted (shared ))
279
292
280
-
293
+ #---------------------------------------------------------------------------
294
+ #class SolveAttempt:
295
+ # def __init__(self, words):
296
+ # self.words = words
297
+ #
281
298
#---------------------------------------------------------------------------
282
299
class Solver :
283
300
def __init__ (self , catalog , crypted , known ):
@@ -289,7 +306,8 @@ def __init__(self, catalog, crypted, known):
289
306
self .cat = catalog
290
307
self .cryptedWords = cryptedWords
291
308
self .words = [Word (word ) for word in uniqueWords ]
292
- self .cipher = Cipher (cryptedLetters , knownLetters )
309
+ self .cipher = Cipher (cryptedLetters , knownLetters ,
310
+ noLetterToItself = True )
293
311
self .root = None
294
312
self .unlinked = []
295
313
@@ -348,17 +366,24 @@ def prepare(self):
348
366
word .guesses = self .cat .words (word .pattern , glob )
349
367
self .cipher .process (word .crypted , word .guesses )
350
368
words = deque (sorted (self .words , key = attrgetter ("count" )))
369
+ bestSort = (len (words )+ 1 , [])
351
370
for n in range (len (words )):
352
371
self ._buildTree (words )
353
- # try for no more than 2 unlinked words
354
- if len ( self . unlinked ) < 3 :
372
+ unlinkedCount = len ( self . unlinked )
373
+ if unlinkedCount == 0 :
355
374
break
375
+ elif unlinkedCount < bestSort [0 ]:
376
+ bestSort = (unlinkedCount , deque (words ))
377
+ # try for no more than 2 unlinked words
378
+ #if len(self.unlinked) < 3:
379
+ # break
356
380
for word in words :
357
381
word .links = []
358
382
words .rotate (- 1 )
359
383
else :
360
384
# back at the beginning
361
- self ._buildTree (self .words )
385
+ self ._buildTree (bestSort [1 ])
386
+ #self._buildTree(self.words)
362
387
363
388
def _buildTree (self , words ):
364
389
others = list (words )
@@ -436,7 +461,7 @@ def filter(self):
436
461
for word in self .words
437
462
if word .count ))
438
463
numReductions = self .cipher .reduce ()
439
- # print("Reduced {} possibles in go {}".format(numReductions, go))
464
+ print ("Reduced {} cipher possibles in go {}" .format (numReductions , go ))
440
465
else :
441
466
numReductions = 0
442
467
if numReductions :
@@ -618,7 +643,7 @@ def main():
618
643
known = cleanInput ("Enter any known letters: " )
619
644
with closing (Catalog (path )) as cat :
620
645
solver = Solver (cat , cryptogram , known )
621
- solver .solve ( )
646
+ tictocDo ( solver .solve , "solver.solve" )
622
647
solver .print ()
623
648
624
649
def cleanInput (prompt ):
0 commit comments