]> git.earman.xyz Git - sensor-watch.git/commitdiff
Added ability to find best starting word
authorDavid Volovskiy <devolov@gmail.com>
Tue, 3 Sep 2024 14:15:48 +0000 (10:15 -0400)
committerDavid Volovskiy <devolov@gmail.com>
Tue, 3 Sep 2024 20:11:54 +0000 (16:11 -0400)
utils/wordle_face/wordle_list.py

index ea2154c1cdd2df7caa97c644618682ac13c6a838..39e310c1c4c71ac1f8b190b8777c0465d6c328d8 100644 (file)
@@ -1,4 +1,4 @@
-import random, itertools, time, ast\r
+import random, itertools, time, numpy\r
 \r
 source_link = "https://matthewminer.name/projects/calculators/wordle-words-left/"\r
 valid_list = [\r
@@ -1091,12 +1091,12 @@ possible_list = [
 \r
 alphabet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']\r
 \r
-def most_used_letters(words=valid_list):\r
+def most_used_letters(words=valid_list, letters=alphabet, print_result=True):\r
     '''\r
     Outputs how many times each letter is used in the words array.\r
     '''\r
     use_each_letter = {}\r
-    for i in alphabet:\r
+    for i in letters:\r
         count = 0\r
         for word in words:\r
             for letter in word:\r
@@ -1105,10 +1105,11 @@ def most_used_letters(words=valid_list):
                     break\r
         use_each_letter[i] = count\r
     use_each_letter = dict(sorted(use_each_letter.items(), key=lambda item: item[1], reverse=True))\r
-    print("Letter |   Usage   | Percent")\r
-    print("----------------------------")\r
-    for k in use_each_letter:\r
-        print(f"{k.upper()}      | {use_each_letter[k]:5}     | {round((100 * use_each_letter[k]) / len(words)):2}%")\r
+    if print_result:\r
+        print("Letter |   Usage   | Percent")\r
+        print("----------------------------")\r
+        for k in use_each_letter:\r
+            print(f"{k.upper()}      | {use_each_letter[k]:5}     | {round((100 * use_each_letter[k]) / len(words)):2}%")\r
     return use_each_letter\r
 \r
 \r
@@ -1242,7 +1243,7 @@ def txt_of_all_letter_combos(num_letters_in_set, words=valid_list, min_letter_oc
     prev = time.time()\r
     start = prev\r
     letters_to_ignore = ['D','M']  # Don't diplay well on the watch\r
-    letter_usage = most_used_letters(words=words)\r
+    letter_usage = most_used_letters(words=words, print_result=False)\r
     for letter in letter_usage:\r
         if (100 * letter_usage[letter])/len(words) < min_letter_occ_percent_to_consider:\r
             letters_to_ignore.append(letter)\r
@@ -1276,7 +1277,7 @@ def txt_of_all_letter_combos(num_letters_in_set, words=valid_list, min_letter_oc
     dict_combos_counts = dict(sorted(dict_combos_counts.items(), key=lambda item: item[1], reverse=True))\r
     \r
     most_common_key = next(iter(dict_combos_counts))\r
-    print(f"The Most Common Combo is: {most_common_key} with {dict_combos_counts[most_common_key]} words.")\r
+    print(f"The Most Common Combo for {num_letters_in_set} letters is: {most_common_key} with {dict_combos_counts[most_common_key]} words.")\r
     # print_valid_words(ast.literal_eval(most_common_key))  # Uncomment to display the text it creates\r
     \r
     if txt_out:\r
@@ -1304,9 +1305,11 @@ def txt_of_all_letter_combos_differing_sizes(min=9, max=15, num_combos_print=20,
         print(f"{key}, {item}") \r
             \r
 \r
-def location_of_letters(letters=alphabet, list=valid_list):\r
-    print("        1      2      3      4       5   ")\r
-    print("-----------------------------------------")\r
+def location_of_letters(letters=alphabet, list=valid_list, print_result=True):\r
+    letter_location_percentages = {}\r
+    if print_result:\r
+        print("        1      2      3      4       5   ")\r
+        print("-----------------------------------------")\r
     letters = sorted(letters)\r
     for letter in letters:\r
         location = [0, 0, 0, 0, 0]\r
@@ -1314,15 +1317,62 @@ def location_of_letters(letters=alphabet, list=valid_list):
             for i, char in enumerate(word):\r
                 if char.upper() == letter.upper():\r
                     location[i]+=1\r
-        location = [f"{round((100 * x) / sum(location)):2}%" for x in location]\r
-        print(f"{letter} :   {location}")\r
+        location = [((100 * x) / sum(location)) for x in location]\r
+        letter_location_percentages[letter] = location\r
+        location_txt = [f"{round(x):2}%" for x in location]\r
+        if print_result:\r
+            print(f"{letter} :   {location_txt}")\r
+    return letter_location_percentages\r
+\r
+\r
+def best_first_word(letters=alphabet, list=valid_list, print_result=True, words_to_print=None):\r
+    '''\r
+    Word_good has every word with only unique letters as keys and that values are:\r
+        1. Take the usage of every letter, normalize the max to 100 and the min to 0.\r
+        2. Go through each letter in the word and see how often that letter appears in that exact location.\r
+        3. Multiply that occurrance in location with the normalized total usage.\r
+        4. Do this for each letter and add it all together.\r
+        \r
+        Ex: SLATE\r
+            Normalized usage: S=38, L=42, A=79, T=46, E=100\r
+            S in position 1: 55%\r
+            L in position 2: 27%\r
+            A in position 3: 31%\r
+            T in position 4: 19%\r
+            E in position 5: 34%\r
+        Total = (38*55) + (42*27) + (79*31) + (46*19) + (100*35) = 10047\r
+    '''    \r
+    valid_words = list_of_valid_words(letters, list)\r
+    letter_usage = most_used_letters(words=list, letters=letters, print_result=False)\r
+    a=[[max(letter_usage.values()),1],[min(letter_usage.values()),1]]\r
+    b=[100,0]\r
+    m,b = numpy.linalg.solve(a,b).tolist()\r
+    letter_usage_normalized = {key: ((m * value) + b) for key, value in letter_usage.items()}\r
+    loc_letters = location_of_letters(letters=letters, list=list, print_result=False)\r
+    word_good = {}\r
+    valid_words_unique = [word for word in valid_words if len(word) == len(set(word))]\r
+    for word in valid_words_unique:\r
+        usage = 0\r
+        for i, char in enumerate(word):\r
+            usage += loc_letters[char][i] * letter_usage_normalized[char]\r
+        word_good[word] = round(usage)\r
+    word_good = {k: v for k, v in sorted(word_good.items(), key=lambda item: item[1], reverse=True)}\r
+    if print_result:\r
+        print("Word,  Usage Value")\r
+        print("------------------")\r
+        for i,[k,v] in enumerate(word_good.items()):\r
+            if words_to_print is not None and i+1 > words_to_print:\r
+                break\r
+            print(f"{k}, {v}")\r
+    return word_good\r
 \r
 \r
 if __name__ == "__main__":\r
     my_letters = ['A', 'C', 'E', 'H', 'I', 'L', 'N', 'O', 'P', 'R', 'S', 'T']\r
     #print(f"{len(list_of_valid_words(my_letters, valid_list))} Words can be made with {my_letters}")\r
-    #most_used_letters()\r
-    #location_of_letters(my_letters)\r
+    #most_used_letters(letters=my_letters)\r
+    #location_of_letters(letters=my_letters)\r
     print_valid_words(my_letters)\r
     #txt_of_all_letter_combos_differing_sizes(max = 16, min=10)\r
-    #txt_of_all_letter_combos(14)
\ No newline at end of file
+    #txt_of_all_letter_combos(14)\r
+    #best_first_word(letters=my_letters, print_result=True, words_to_print=10)
\ No newline at end of file