fork(1) download
  1. from collections import defaultdict
  2. import re
  3. from math import factorial
  4.  
  5. class Word:
  6. def __init__(self, word):
  7. self.word = word
  8. self.r = ''
  9. self.x = ''
  10. self.guessed = ''
  11. self.mask = re.sub(r'[a-z]', '_', word)
  12. self.remaining = word
  13. self.index = 0
  14. self.won = False
  15. self.lost = False
  16. self.indexes = []
  17. def isEnded(self):
  18. return self.won or self.lost
  19. def move(self, d):
  20. while d[self.index] in self.guessed:
  21. if d[self.index] in self.r:
  22. self.index += 1
  23. else:
  24. R = 12-len(self.r)
  25. X = 6-len(self.x)
  26. try:
  27. self.index += factorial(X+R)/factorial(R)/factorial(X)
  28. except:
  29. print self.word, self.guessed, self.r, self.x, self.index, self.mask, self.remaining
  30. raise
  31. self.index = (self.index%len(d))
  32. def update(self, d):
  33. # bestLetter may already have been guessed for this word
  34. self.move(d)
  35. while d[self.index] != '.' and not self.isEnded():
  36. if d[self.index] in self.remaining:
  37. self.r += d[self.index]
  38. else:
  39. self.x += d[self.index]
  40. self.guessed += d[self.index]
  41. self.indexes.append(self.index)
  42. for letterIndex in range(len(self.mask)):
  43. if self.word[letterIndex] == d[self.index]:
  44. self.mask = self.mask[:letterIndex]+d[self.index]+self.mask[letterIndex+1:]
  45. self.remaining = self.remaining.replace(d[self.index], '_')
  46. if len(self.x) == 6:
  47. self.lost = True
  48. elif '_' not in self.mask:
  49. self.won = True
  50. else:
  51. self.move(d)
  52.  
  53. class Words:
  54. def __init__(self, words):
  55. self.words = []
  56. for word in words:
  57. self.words.append(Word(word))
  58. def allEnded(self):
  59. for word in self.words:
  60. if not word.isEnded():
  61. return False
  62. return True
  63. def getBestIndex(self):
  64. count = defaultdict(int)
  65. bestCount = 0
  66. bestIndex = 0
  67. for word in self.words:
  68. if not word.isEnded():
  69. count[word.index]+=1
  70. if count[word.index] > bestCount:
  71. bestCount = count[word.index]
  72. bestIndex = word.index
  73. return bestIndex
  74. def getBestLetter(self, index):
  75. count = defaultdict(int)
  76. bestCount = 0
  77. bestLetter = ''
  78. for word in self.words:
  79. if word.isEnded() or word.index != index:
  80. continue
  81. for letter in word.remaining.replace('_',''):
  82. count[letter] += 1
  83. if count[letter] > bestCount:
  84. bestCount = count[letter]
  85. bestLetter = letter
  86. return bestLetter
  87. def update(self, bestIndex, bestLetter, d):
  88. for word in self.words:
  89. if not word.isEnded():
  90. word.update(d)
  91. def wins(self):
  92. w = 0
  93. for word in self.words:
  94. if word.won:
  95. w+=1
  96. return w
  97.  
  98.  
  99. def is_prime(n):
  100. for i in range(3,n):
  101. if n%i == 0:
  102. return False
  103. return True
  104.  
  105. bestWins = 0
  106. bestD={}
  107.  
  108. for length in range(4001,1500,-2):
  109. if not is_prime(length):
  110. continue
  111. d = ['.']*length
  112.  
  113. fff = open('wordlist.txt')
  114. lines = fff.readlines()
  115. fff.close()
  116. ww = []
  117. for line in lines:
  118. w=line.strip()
  119. if re.match(r'^[a-z]*$', w):
  120. ww.append(w)
  121. words = Words(ww)
  122.  
  123. while not words.allEnded():
  124. bestIndex = words.getBestIndex()
  125. bestLetter = words.getBestLetter(bestIndex)
  126. # Update d
  127. d[bestIndex] = bestLetter
  128. # Move words
  129. words.update(bestIndex, bestLetter, d)
  130. wins = words.wins()
  131. counts = defaultdict(int)
  132. for l in d:
  133. if l != '.':
  134. counts[l]+=1
  135. if counts[l] == max(counts.values()):
  136. bestL=l
  137. encoded = ''.join(d).replace('.',bestL).encode('zip').encode('base64')
  138. newEntry = (len(encoded), length, encoded, ''.join(d).replace('.',bestL))
  139. toRemove = []
  140. include = True
  141. for oldWins, oldEntry in bestD.items():
  142. if oldWins < wins and oldEntry[0] >= newEntry[0]:
  143. toRemove.append(oldWins)
  144. if oldWins > wins and oldEntry[0] <= newEntry[0]:
  145. include = False
  146. for oldWins in toRemove:
  147. bestD.pop(oldWins)
  148. if include:
  149. bestD[wins] = newEntry
  150. print wins, len(encoded), length
  151. for k in sorted(bestD.keys()):
  152. print ' %d | %d | %s'%(k, bestD[k][0], bestD[k][3])
  153.  
Runtime error #stdin #stdout #stderr 0.01s 7860KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
Traceback (most recent call last):
  File "prog.py", line 113, in <module>
IOError: [Errno 2] No such file or directory: 'wordlist.txt'