Đây là một trò chơi chữ từ một bộ thẻ hoạt động cho trẻ em. Bên dưới các quy tắc là mã để tìm bộ ba tốt nhất bằng cách sử dụng / usr / share / dict / words. Tôi nghĩ rằng đó là một vấn đề tối ưu hóa thú vị, và tự hỏi liệu mọi người có thể tìm thấy sự cải thiện.
Quy tắc
- Chọn một chữ cái từ mỗi bộ dưới đây.
- Chọn một từ bằng cách sử dụng các chữ cái đã chọn (và bất kỳ từ nào khác).
- Điểm số từ.
- Mỗi chữ cái từ bộ được chọn sẽ có số được hiển thị cùng với bộ (bao gồm lặp lại).
AEIOU
đếm 0- Tất cả các chữ cái khác là -2
- Lặp lại các bước 1-3 ở trên (không sử dụng lại các chữ cái trong bước 1) hai lần nữa.
- Điểm cuối cùng là tổng của ba điểm số từ.
Bộ
(đặt 1 điểm 1 điểm, đặt 2 điểm 2 điểm, v.v.)
- LTN
- RDS
- GBM
- CHP
- FWV
- YKJ
- QXZ
Mã số:
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)
Phiên bản ma trận là những gì tôi nghĩ ra sau khi viết một bản bằng python thuần (sử dụng từ điển và chấm điểm từng từ một cách độc lập), và một bản khác trong numpy nhưng sử dụng lập chỉ mục thay vì nhân ma trận.
Tối ưu hóa tiếp theo sẽ là loại bỏ hoàn toàn các nguyên âm khỏi việc chấm điểm (và sử dụng ord()
chức năng đã được sửa đổi ), nhưng tôi tự hỏi liệu có những cách tiếp cận nào nhanh hơn không.
EDIT : thêm mã timeit.timeit
EDIT : Tôi đang thêm một tiền thưởng, mà tôi sẽ đưa ra bất kỳ cải thiện nào tôi thích nhất (hoặc có thể là nhiều câu trả lời, nhưng tôi sẽ phải tích lũy thêm một số danh tiếng nếu đó là trường hợp).