1। পরিচিতি
এই সমস্যাটি নিয়মতান্ত্রিকভাবে পৌঁছানোর জন্য এখানে একটি উপায়: আপনার যদি একটি অ্যালগরিদম থাকে যা হ্যাঙ্গম্যান ভালভাবে বাজায়, তবে আপনি প্রতিটি শব্দটির অসুবিধাকে সেই ভুল অনুমানের সংখ্যা হিসাবে নিতে পারেন যে শব্দটি অনুমান করে যদি আপনার প্রোগ্রামটি গ্রহণ করে।
২. হ্যাঙ্গম্যান কৌশল বাদে
কিছু অন্যান্য উত্তর এবং মন্তব্যে অন্তর্নিহিত একটি ধারণা রয়েছে যে দ্রোকারের অনুকূল কৌশলটি তাদের সিদ্ধান্তগুলি ইংরেজিতে বর্ণগুলির ফ্রিকোয়েন্সি বা কিছু কর্পাসের শব্দের ফ্রিকোয়েন্সি ভিত্তিতে করা উচিত। এটি একটি প্ররোচক ধারণা, তবে এটি একেবারেই সঠিক নয়। সমাধানকারীর দ্বারা নির্বাচিত শব্দের বন্টনকে সঠিকভাবে মডেল করা হলে সল্ভারটি সবচেয়ে ভাল কাজ করে এবং একটি মানব সেটার তাদের বিরলতা বা ঘন ঘন ব্যবহৃত অক্ষরের পরিহারের ভিত্তিতে শব্দগুলি বেছে নিতে পারে। উদাহরণ হিসেবে বলা যায়, যদিও Eইংরেজিতে সবচেয়ে ঘন ঘন ব্যবহৃত অক্ষর, যদি সেটার সবসময় শব্দ থেকে চয়ন করে JUGFUL, RHYTHM, SYZYGY, এবং ZYTHUMতারপর, একটি নিখুঁত সমাধানকারী মনন দ্বারা শুরু হয় না E!
সেটারের মডেলিংয়ের সর্বোত্তম পদ্ধতির প্রেক্ষাপটের উপর নির্ভর করে তবে আমি অনুমান করি যে এক প্রকার বায়েশিয়ান ইনডাকটিভ ইনফেরেন্স এমন প্রসঙ্গে ভাল কাজ করবে যেখানে সলভার একই সেটারের বিপরীতে বা একই রকম সেটটারগুলির একটি গ্রুপের বিরুদ্ধে অনেকগুলি খেলা খেলবে।
3. একটি হ্যাঙ্গম্যান অ্যালগরিদম
এখানে আমি একটি সলভার রূপরেখা করব যা বেশ ভাল (তবে নিখুঁত থেকে অনেক দূরে)। এটি একটি নির্দিষ্ট অভিধান থেকে অভিন্ন শব্দ চয়ন করার জন্য সেটারকে মডেল করে। এটি একটি লোভী অ্যালগরিদম : প্রতিটি পর্যায়ে এটি চিঠিটি অনুমান করে যা মিসের সংখ্যা হ্রাস করে, অর্থাত্ শব্দগুলি অনুমান করে না। উদাহরণস্বরূপ, যদি কোন অনুমান এতদূর করা হয়েছে, এবং সম্ভব শব্দ DEED, DEADএবং DARE, তারপর:
- যদি আপনি অনুমান করেন
Dবা E, কোনও মিস আছে;
- যদি আপনি অনুমান করেন
A, একটি মিস আছে ( DEED);
- যদি আপনি অনুমান করেন
Rতবে দুটি মিস ( DEEDএবং DEAD) রয়েছে;
- যদি আপনি অন্য কোনও চিঠিটি অনুমান করেন তবে তিনটি মিস আছে।
সুতরাং হয় Dবা Eহয় এই পরিস্থিতিতে একটি ভাল অনুমান।
( কর্নেল প্যানিককে মন্তব্যে ধন্যবাদ জানাতে যে হ্যাঙ্গম্যানে সঠিক অনুমানগুলি নিখরচায় — আমি আমার প্রথম প্রয়াসে এটি পুরোপুরি ভুলে গেছি!)
4. বাস্তবায়ন
পাইথনে এই অ্যালগরিদমের একটি বাস্তবায়ন এখানে দেওয়া হয়েছে:
from collections import defaultdict
from string import ascii_lowercase
def partition(guess, words):
"""Apply the single letter 'guess' to the sequence 'words' and return
a dictionary mapping the pattern of occurrences of 'guess' in a
word to the list of words with that pattern.
>>> words = 'deed even eyes mews peep star'.split()
>>> sorted(list(partition('e', words).items()))
[(0, ['star']), (2, ['mews']), (5, ['even', 'eyes']), (6, ['deed', 'peep'])]
"""
result = defaultdict(list)
for word in words:
key = sum(1 << i for i, letter in enumerate(word) if letter == guess)
result[key].append(word)
return result
def guess_cost(guess, words):
"""Return the cost of a guess, namely the number of words that don't
contain the guess.
>>> words = 'deed even eyes mews peep star'.split()
>>> guess_cost('e', words)
1
>>> guess_cost('s', words)
3
"""
return sum(guess not in word for word in words)
def word_guesses(words, wrong = 0, letters = ''):
"""Given the collection 'words' that match all letters guessed so far,
generate tuples (wrong, nguesses, word, guesses) where
'word' is the word that was guessed;
'guesses' is the sequence of letters guessed;
'wrong' is the number of these guesses that were wrong;
'nguesses' is len(guesses).
>>> words = 'deed even eyes heel mere peep star'.split()
>>> from pprint import pprint
>>> pprint(sorted(word_guesses(words)))
[(0, 1, 'mere', 'e'),
(0, 2, 'deed', 'ed'),
(0, 2, 'even', 'en'),
(1, 1, 'star', 'e'),
(1, 2, 'eyes', 'en'),
(1, 3, 'heel', 'edh'),
(2, 3, 'peep', 'edh')]
"""
if len(words) == 1:
yield wrong, len(letters), words[0], letters
return
best_guess = min((g for g in ascii_lowercase if g not in letters),
key = lambda g:guess_cost(g, words))
best_partition = partition(best_guess, words)
letters += best_guess
for pattern, words in best_partition.items():
for guess in word_guesses(words, wrong + (pattern == 0), letters):
yield guess
5. উদাহরণ ফলাফল
এই কৌশলটি ব্যবহার করে সংগ্রহের প্রতিটি শব্দ অনুমান করার অসুবিধাটি মূল্যায়ন করা সম্ভব। এখানে আমি আমার সিস্টেম অভিধানে ছয় অক্ষরের শব্দ বিবেচনা করছি:
>>> words = [w.strip() for w in open('/usr/share/dict/words') if w.lower() == w]
>>> six_letter_words = set(w for w in words if len(w) == 6)
>>> len(six_letter_words)
15066
>>> results = sorted(word_guesses(six_letter_words))
এই অভিধানে অনুমান করার সবচেয়ে সহজ শব্দগুলি (একত্রে সমাধানকারীকে অনুমান করার জন্য প্রয়োজনীয় অনুমানের অনুক্রমের সাথে একত্রে) নিম্নরূপ:
>>> from pprint import pprint
>>> pprint(results[:10])
[(0, 1, 'eelery', 'e'),
(0, 2, 'coneen', 'en'),
(0, 2, 'earlet', 'er'),
(0, 2, 'earner', 'er'),
(0, 2, 'edgrew', 'er'),
(0, 2, 'eerily', 'el'),
(0, 2, 'egence', 'eg'),
(0, 2, 'eleven', 'el'),
(0, 2, 'enaena', 'en'),
(0, 2, 'ennead', 'en')]
এবং সবচেয়ে শক্ত শব্দগুলি হল:
>>> pprint(results[-10:])
[(12, 16, 'buzzer', 'eraoiutlnsmdbcfg'),
(12, 16, 'cuffer', 'eraoiutlnsmdbpgc'),
(12, 16, 'jugger', 'eraoiutlnsmdbpgh'),
(12, 16, 'pugger', 'eraoiutlnsmdbpcf'),
(12, 16, 'suddle', 'eaioulbrdcfghmnp'),
(12, 16, 'yucker', 'eraoiutlnsmdbpgc'),
(12, 16, 'zipper', 'eraoinltsdgcbpjk'),
(12, 17, 'tuzzle', 'eaioulbrdcgszmnpt'),
(13, 16, 'wuzzer', 'eraoiutlnsmdbpgc'),
(13, 17, 'wuzzle', 'eaioulbrdcgszmnpt')]
এগুলি শক্ত হওয়ার কারণ হ'ল অনুমান করার -UZZLEপরেও আপনার কাছে এখনও সাতটি সম্ভাবনা রয়েছে:
>>> ' '.join(sorted(w for w in six_letter_words if w.endswith('uzzle')))
'buzzle guzzle muzzle nuzzle puzzle tuzzle wuzzle'
6. ওয়ার্ডলিস্ট পছন্দ
অবশ্যই আপনার বাচ্চার জন্য ওয়ার্ডলিস্টগুলি প্রস্তুত করার সময় আপনি আপনার কম্পিউটারের সিস্টেম অভিধান দিয়ে শুরু করবেন না, আপনি এমন শব্দের একটি তালিকা দিয়ে শুরু করবেন যা আপনি মনে করেন যে তারা সম্ভবত জানেন। উদাহরণস্বরূপ, আপনি বিভিন্ন ইংরেজি কর্পোরায় সর্বাধিক ব্যবহৃত শব্দগুলির উইকশনারি তালিকাগুলির উপর নজর রাখতে পারেন ।
উদাহরণস্বরূপ, ২০০ Gu সালের হিসাবে প্রজেক্ট গুটেনবার্গের ১০,০০০ সর্বাধিক প্রচলিত শব্দের মধ্যে ১,7০০ ছয় অক্ষরের শব্দের মধ্যে দশটি সবচেয়ে কঠিন দশটি হ'ল:
[(6, 10, 'losing', 'eaoignvwch'),
(6, 10, 'monkey', 'erdstaoync'),
(6, 10, 'pulled', 'erdaioupfh'),
(6, 10, 'slaves', 'erdsacthkl'),
(6, 10, 'supper', 'eriaoubsfm'),
(6, 11, 'hunter', 'eriaoubshng'),
(6, 11, 'nought', 'eaoiustghbf'),
(6, 11, 'wounds', 'eaoiusdnhpr'),
(6, 11, 'wright', 'eaoithglrbf'),
(7, 10, 'soames', 'erdsacthkl')]
(সোমস ফোর্সাইট হলেন ফোর্সাইট সাগায় একটি চরিত্র জন গ্যালসফায়াল ; শব্দ তালিকাটি লোয়ার-কেসে রূপান্তরিত হয়েছে সুতরাং আমার পক্ষে সঠিক নামগুলি দ্রুত সরিয়ে ফেলা সম্ভব হয়নি।)
f(w) = (# unique letters) * (7 - # vowels) * (sum of the positions of unique letters in a list, ordered by frequency)। সেখান থেকে, আপনি কেবলমাত্র ফাংশনটির ব্যাপ্তিটি তিনটি বিভাগে বিভক্ত করতে পারেন এবং তাদের আপনার অসুবিধা বলতে পারেন।