これは、子供向けの一連のアクティビティカードからの単語ゲームです。ルールの下には、/ usr / share / dict / wordsを使用して最適なトリプレットを見つけるためのコードがあります。私はそれが面白い最適化問題だと思い、人々が改善を見つけることができるかどうか疑問に思っています。
ルール
- 以下の各セットから1つの文字を選択します。
- 選択した文字(およびその他の文字)を使用して単語を選択します。
- 単語を採点します。
- 選択したセットの各文字には、セットに表示されている番号が付けられます(繰り返しが含まれます)。
AEIOU
カウント0- 他のすべての文字は-2
- 上記の手順1〜3(手順1で文字を再利用しない)をさらに2回繰り返します。
- 最終スコアは、3つの単語スコアの合計です。
セット
(1点を1点に設定、2点を2点に設定など)
- LTN
- RDS
- GBM
- CHP
- FWV
- YKJ
- QXZ
コード:
from itertools import permutations
import numpy as np
points = {'LTN' : 1,
'RDS' : 2,
'GBM' : 3,
'CHP' : 4,
'FWV' : 5,
'YKJ' : 6,
'QXZ' : 7}
def tonum(word):
word_array = np.zeros(26, dtype=np.int)
for l in word:
word_array[ord(l) - ord('A')] += 1
return word_array.reshape((26, 1))
def to_score_array(letters):
score_array = np.zeros(26, dtype=np.int) - 2
for v in 'AEIOU':
score_array[ord(v) - ord('A')] = 0
for idx, l in enumerate(letters):
score_array[ord(l) - ord('A')] = idx + 1
return np.matrix(score_array.reshape(1, 26))
def find_best_words():
wlist = [l.strip().upper() for l in open('/usr/share/dict/words') if l[0].lower() == l[0]]
wlist = [l for l in wlist if len(l) > 4]
orig = [l for l in wlist]
for rep in 'AEIOU':
wlist = [l.replace(rep, '') for l in wlist]
wlist = np.hstack([tonum(w) for w in wlist])
best = 0
ct = 0
bestwords = ()
for c1 in ['LTN']:
for c2 in permutations('RDS'):
for c3 in permutations('GBM'):
for c4 in permutations('CHP'):
for c5 in permutations('FWV'):
for c6 in permutations('YJK'):
for c7 in permutations('QZX'):
vals = [to_score_array(''.join(s)) for s in zip(c1, c2, c3, c4, c5, c6, c7)]
ct += 1
print ct, 6**6
scores1 = (vals[0] * wlist).A.flatten()
scores2 = (vals[1] * wlist).A.flatten()
scores3 = (vals[2] * wlist).A.flatten()
m1 = max(scores1)
m2 = max(scores2)
m3 = max(scores3)
if m1 + m2 + m3 > best:
print orig[scores1.argmax()], orig[scores2.argmax()], orig[scores3.argmax()], m1 + m2 + m3
best = m1 + m2 + m3
bestwords = (orig[scores1.argmax()], orig[scores2.argmax()], orig[scores3.argmax()])
return bestwords, best
if __name__ == '__main__':
import timeit
print timeit.timeit('print find_best_words()', 'from __main__ import find_best_words', number=1)
マトリックスバージョンは、純粋なpythonで1つ(辞書を使用して各単語を個別に採点)を作成し、numpyで別の1つを作成し、マトリックス乗算ではなくインデックスを使用して作成したものです。
次の最適化は、スコアリングから母音を完全に削除することです(そして修正されたord()
関数を使用します)が、もっと速いアプローチがあるのではないかと思います。
編集:timeit.timeitコードを追加
編集:私は賞金を追加します。これは、私が最も好きな改善に与えます(または複数の回答がありますが、その場合はより多くの評判を獲得する必要があります)。