{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from wordle_assistant_functions import *" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2310\n" ] }, { "data": { "text/plain": [ "['wince', 'thyme', 'mower', 'horde', 'heard']" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "### Official list\n", "official_words = []\n", "\n", "with open(\"../data/official_words_processed.txt\", \"r\", encoding = \"utf-8\") as f:\n", " for word in f.read().split(\"\\n\"):\n", " official_words.append(word)\n", "\n", "f.close() # closes connection to file\n", "\n", "print(len(official_words))\n", "official_words[:5]" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# test_1 = wordle_wizard(word_list = official_words, max_guesses = 6, \n", "# guess = \"paint\", target = \"force\",\n", "# random_guess = False, random_target = False, \n", "# verbose = True, drama = 0, return_stats = False, record = False)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "def wordle_wizard_cheat_local(guesses: list, word_list: list, max_guesses: int = None, \n", " # guess: str = None, target: str = None,\n", " target: str = None,\n", " random_guess: bool = False, random_target: bool = False, \n", " verbose: bool = False, drama: float = None, \n", " return_stats: bool = False, record: bool = False):\n", " \"\"\"\n", " Mimicking the popular web game, this function matches a current word to a target word automatically, in the most statistically optimal way possible.\n", "\n", " Parameters:\n", " ------\n", " `word_list`: list\n", " list of valid words to be considered\n", " `guess`: str\n", " a string -- must be the same length as `target_word`\n", " `target`: str\n", " a string -- must be the same length as `opening_word`\n", " `max_guesses`: int\n", " the maximum number of attempts allowed to solve the Wordle\n", " `random_guess`: bool\n", " if True, randomly chooses a starting word from all words within `word_list`. If False, passed starting word must be used instead\n", " `random_target`: bool\n", " if True, randomly chooses a target word from all words within `word_list`. If False, passed target word must be used instead\n", " `verbose`: bool\n", " if True, # prints progress and explanation of how function solves the puzzle. If False, # prints only the guessed word at each guess.\n", " `drama`: float or int\n", " if int provided, each guess' output is delayed by that number of seconds, else each output is shown as quickly as possible. For ~dRaMaTiC eFfEcT~\n", " `return_stats`: bool\n", " if True, # prints nothing and returns a dictionary of various statistics about the function's performance trying to solve the puzzle\n", " `record`: bool\n", " if True, creates a .txt file with the same information # printed according to the indicated verbosity\n", "\n", " Returns:\n", " ------\n", " `stats_dict`: dict\n", " dictionary containing various statistics about the function's performance trying to solve the puzzle\n", " \"\"\"\n", "\n", " # guess = guess.lower()\n", " target = target.lower()\n", "\n", " if target not in word_list:\n", " word_list.append(target)\n", "\n", " sugg_words = []\n", "\n", " for i in range(0, 20):\n", " ran_int = random.randint(0, len(word_list) - 1)\n", " word = word_list[ran_int]\n", " sugg_words.append(word)\n", "\n", " guess = guesses[0]\n", "\n", " stats_dict = {}\n", " stats_dict['first_guess'] = guess\n", " stats_dict['target_word'] = target\n", " stats_dict['first_guess_vowels'] = float(count_vows_cons(guess, y_vow = True)['vows'])\n", " stats_dict['first_guess_consonants'] = float(count_vows_cons(guess, y_vow = True)['cons'])\n", " stats_dict['target_vowels'] = float(count_vows_cons(target, y_vow = True)['vows'])\n", " stats_dict['target_consonants'] = float(count_vows_cons(target, y_vow = True)['cons'])\n", " \n", " # get rating of the first guess word and target word in the entire word_list\n", " for tup in get_word_rating(word_list, word_list, normalized = True):\n", " if tup[0] == guess:\n", " stats_dict['first_guess_rating'] = tup[1]\n", " if tup[0] == target:\n", " stats_dict['target_rating'] = tup[1]\n", "\n", " guess_entropies = []\n", " guess_entropies.append(stats_dict['first_guess_rating'])\n", "\n", " # luck_guess_1 = round(1 - ((1 / len(word_list)) * guess_entropies[0] / 100), 2) * 100\n", "\n", " english_alphabet = \"abcdefghijklmnopqrstuvwxyz\"\n", "\n", " # word_list_sorted_counts = get_letter_counts(english_alphabet, word_list, sort = \"descending\")\n", " word_list_sorted_counts = get_letter_counts(word_list = word_list, letters = english_alphabet, sort = \"descending\", unique = True)\n", "\n", " wordlen = len(guesses[0])\n", " letter_positions = set(i for i in range(0, wordlen))\n", "\n", " guess_set = set()\n", " perfect_dict = {}\n", " wrong_pos_dict = {}\n", " wrong_pos_set = set()\n", " dont_guess_again = set()\n", "\n", " guessed_words = [] # running set of guessed words\n", " guess_num = 0 # baseline for variable\n", " dont_guess_words = set()\n", " incorrect_positions = []\n", " reduction_per_guess = []\n", "\n", " if max_guesses == None: # if no value is passed, default is len(guess)\n", " max_guesses = wordlen\n", " else: # else it is the value passed\n", " max_guesses = max_guesses\n", "\n", " perfect_letts_per_guess = []\n", " wrong_pos_per_guess = []\n", " wrong_letts_per_guess = []\n", "\n", " # while guess: # while there is any guess -- there are conditions to break it at the bottom\n", "\n", " for guess_num, guess in enumerate(guesses):\n", "\n", " guess_num += 1\n", "\n", " guessed_words.append(guess)\n", "\n", " if drama:\n", " time.sleep(drama)\n", "\n", " # guess_num += 1 # each time the guess is processed\n", " if return_stats == False:\n", " if guess_num == 1:\n", " print(\"-----------------------------\\n\")\n", "\n", " if guess == target:\n", " stats_dict['target_guessed'] = True\n", " if return_stats == False:\n", " if guess_num == 1:\n", " # print(f\"Congratulations! The Wordle has been solved in {guess_num} guess, that's amazingly lucky!\")\n", " print(f\"The starting word and target word are the same. Try entering two different words to see how the puzzle can be solved.\")\n", " # print(f\"The target word was {target}\")\n", " \n", " \n", " perfect_letts_per_guess.append(5)\n", " wrong_pos_per_guess.append(0)\n", " wrong_letts_per_guess.append(0)\n", " break\n", " \n", " if return_stats == False:\n", " print(f\"**Guess {guess_num}: '{guess}'**\")\n", "\n", " guess_set = set()\n", " wrong_pos_set = set()\n", "\n", " #### Step 2 -- ALL PERFECT\n", " for i in letter_positions: # number of letters in each word (current word and target word)\n", " guess_set.add(guess[i])\n", "\n", " if guess[i] not in perfect_dict:\n", " perfect_dict[guess[i]] = set()\n", " if guess[i] not in wrong_pos_dict:\n", " wrong_pos_dict[guess[i]] = set()\n", "\n", " ### EVALUATE CURRENT GUESS\n", " if guess[i] == target[i]: # letter == correct and position == correct\n", " perfect_dict[guess[i]].add(i)\n", "\n", " if (guess[i] != target[i] and guess[i] in target): # letter == correct and position != correct\n", " wrong_pos_dict[guess[i]].add(i)\n", " wrong_pos_set.add(guess[i])\n", "\n", " if guess[i] not in target: # if letter is not relevant at all\n", " dont_guess_again.add(guess[i])\n", "\n", " #### Step 3 -- ALL PERFECT\n", " next_letters = set()\n", " for letter, positions in perfect_dict.items():\n", " if len(positions) > 0:\n", " next_letters.add(letter)\n", "\n", " for letter, positions in wrong_pos_dict.items():\n", " if len(positions) > 0:\n", " next_letters.add(letter)\n", "\n", " #### List of tuples of correct letter positions in new valid words. Eg: [('e', 2), ('a', 3)]\n", " perfect_letters = []\n", " for letter, positions in perfect_dict.items():\n", " for pos in positions:\n", " if len(positions) > 0:\n", " perfect_letters.append((letter, pos))\n", "\n", " #### all words that have correct letters in same spots\n", " words_matching_correct_all = []\n", " for word in word_list:\n", " word_set = set()\n", " for letter, pos in perfect_letters:\n", " if pos < len(word):\n", " if word[pos] == letter:\n", " words_matching_correct_all.append(word)\n", "\n", " #### excluding words with letters in known incorrect positions\n", " for letter, positions in wrong_pos_dict.items():\n", " for pos in positions:\n", " if len(positions) > 0:\n", " if (letter, pos) not in incorrect_positions:\n", " incorrect_positions.append((letter, pos))\n", "\n", " # sorting lists of tuples just to make them look nice in the # printout\n", " incorrect_positions = sorted(incorrect_positions, key = operator.itemgetter(1), reverse = False)\n", " perfect_letters = sorted(perfect_letters, key = operator.itemgetter(1), reverse = False)\n", "\n", " #### all words that have correct letters in incorrect spots -- so they can be excluded efficiently\n", " \n", " # print(incorrect_positions)\n", " \n", " for word in word_list:\n", " word_set = set()\n", " for letter, pos in incorrect_positions:\n", " if pos < len(word):\n", " if word[pos] == letter:\n", " dont_guess_words.add(word)\n", " for word in word_list:\n", " word_set = set()\n", " for letter, pos in incorrect_positions:\n", " if pos < len(word):\n", " if word[pos] == letter:\n", " dont_guess_words.add(word)\n", "\n", " for bad_letter in dont_guess_again:\n", " for word in word_list:\n", " if (bad_letter in word and word not in dont_guess_words):\n", " dont_guess_words.add(word)\n", "\n", " if return_stats == False:\n", " if verbose == True:\n", " print(f\"Letters in correct positions:\\n\\t{perfect_letters}\\n\")\n", " print(f\"Letters in incorrect positions:\\n\\t{incorrect_positions}\\n\")\n", " # print (f\"Letters to guess again:\\n\\t{sorted(list(next_letters), reverse = False)}\\n\")\n", " print(f\"Letters to not guess again:\\n\\t{sorted(list(dont_guess_again), reverse = False)}\\n\") # works\n", "\n", " # Returns True\n", " # print(A.issubset(B)) # \"if everything in A is in B\", returns Bool\n", "\n", " perfect_letts_per_guess.append(len(perfect_letters))\n", " wrong_pos_per_guess.append(len(incorrect_positions))\n", " wrong_letts_per_guess.append(len(dont_guess_again))\n", "\n", " potential_next_guesses = set()\n", " middle_set = set()\n", "\n", " if len(perfect_letters) == 0 and len(incorrect_positions) == 0: # if there are NEITHER perfect letters, NOR incorrect positions, ....\n", " for word in word_list:\n", " if word not in dont_guess_words:\n", " if word not in guessed_words:\n", " potential_next_guesses.add(word)\n", " \n", " # print(f\"GUESS {guess_num} : TEST 1-1\")\n", "\n", " if len(perfect_letters) == 0 and len(incorrect_positions) != 0: # if there are no perfect letters whatsoever, but there ARE incorrect positions ....\n", " for word in word_list:\n", " for incor_letter, incor_pos in incorrect_positions:\n", " if incor_pos < len(word):\n", " if word[incor_pos] != incor_letter:\n", " if word not in dont_guess_words: # just in case\n", " word_set = set()\n", " for letter in word:\n", " word_set.add(letter)\n", " \n", " if next_letters.issubset(word_set):\n", " if word not in guessed_words:\n", " if len(dont_guess_again) > 0:\n", " for bad_letter in dont_guess_again:\n", " if bad_letter not in word:\n", " # potential_next_guesses.append(word)\n", " potential_next_guesses.add(word)\n", " else:\n", " potential_next_guesses.add(word)\n", " \n", " # print(f\"GUESS {guess_num} : TEST 2-1\")\n", "\n", " else:\n", " for word in word_list:\n", " if word not in dont_guess_words: # just in case\n", " word_set = set()\n", " for letter in word:\n", " word_set.add(letter)\n", " if next_letters.issubset(word_set):\n", " if word not in guessed_words:\n", " # # print (\"TEST 3-2\")\n", "\n", " if len(dont_guess_again) > 0:\n", " for bad_letter in dont_guess_again:\n", " if bad_letter not in word:\n", " middle_set.add(word)\n", " else:\n", " middle_set.add(word)\n", " for word in middle_set:\n", " dummy_list = []\n", " for good_lett, good_pos in perfect_letters:\n", " if word[good_pos] == good_lett:\n", " dummy_list.append(1)\n", " if len(dummy_list) == len(perfect_letters):\n", " potential_next_guesses.add(word)\n", " for word in middle_set:\n", " dummy_list = []\n", " for bad_lett, bad_pos in incorrect_positions:\n", " if bad_pos < len(word):\n", " if word[bad_pos] == bad_lett:\n", " dummy_list.append(1)\n", " if len(dummy_list) > 0:\n", " potential_next_guesses.remove(word)\n", " \n", " # print(f\"GUESS {guess_num} : TEST 3-1\")\n", "\n", " if return_stats == False:\n", " if verbose == True:\n", " if len(potential_next_guesses) > 1:\n", " # print(f\"At this point:\")\n", " print(f\"\\t{len(word_list) - len(potential_next_guesses)}, {round((len(word_list) - len(potential_next_guesses)) / len(word_list) * 100, 2)}% of total words have been eliminated, and\")\n", " print(f\"\\t{len(potential_next_guesses)}, {round(len(potential_next_guesses) / len(word_list) * 100, 2)}% of total words remain possible.\\n\")\n", " \n", " else:\n", " # print(f\"At this point:\")\n", " print(f\"\\t{len(word_list) - len(potential_next_guesses)}, {round((len(word_list) - len(potential_next_guesses)) / len(word_list) * 100, 2)}% of total words have been eliminated, and\")\n", " print(f\"\\t{len(potential_next_guesses)}, {round(len(potential_next_guesses) / len(word_list) * 100, 2)}% of total words remain possible.\\n\")\n", " \n", " reduction_per_guess.append(len(potential_next_guesses))\n", " \n", " #### Guessing next word\n", " if len(potential_next_guesses) == 1:\n", "\n", " if return_stats == False:\n", " if verbose == True:\n", " print(f\"All potential next guesses:\\n\\t{get_word_rating(words_to_rate = list(potential_next_guesses), word_list = word_list)}\\n\")\n", " print(f\"Words guessed so far:\\n\\t{guessed_words}.\\n\")\n", " \n", " print(f\"The only remaining possible word is:\\n\\t'{list(potential_next_guesses)[0]}'\")\n", " \n", " # guess = list(potential_next_guesses)[0]\n", " if guess_num < len(guesses):\n", " guess = guesses[guess_num]\n", " guess_entropies.append(get_word_rating([guess], word_list, normalized = False, ascending = False)[0][1])\n", "\n", " else:\n", "\n", " best_next_guesses = list(potential_next_guesses) \n", " # # print (best_next_guesses)\n", " word_ratings = get_word_rating(best_next_guesses, word_list, normalized = False, ascending = False) # \"internal\" ratings\n", " \n", " # Get max rating of all words\n", " max_rating = -np.inf\n", " for word, rating in word_ratings:\n", " if rating > max_rating:\n", " max_rating = rating\n", "\n", " # add best rated words (all equally best rating in next guess list) to set\n", " best_of_the_best_1 = []\n", " for word, rating in word_ratings:\n", " if rating == max_rating:\n", " best_of_the_best_1.append(word)\n", "\n", " # only using top ten most frequent prefixes suffixes to bias. After that it the impact is especially negligible\n", " test_starts = get_gram_freq(word_list = word_list, letters_length = 1, position = \"start\", search = None)[:10]\n", " test_ends = get_gram_freq(word_list = word_list, letters_length = 1, position = \"end\", search = None)[:10]\n", "\n", " # list of the best words that also have the most frequent starting and ending letters (suffixes and prefixes didn't have an impact)\n", " best_of_the_best_2 = []\n", " for start_gram, start_count in test_starts:\n", " for end_gram, end_count in test_ends:\n", " for word in best_of_the_best_1:\n", " if word[:1] == start_gram and word[-1:] == end_gram:\n", " best_of_the_best_2.append(word)\n", "\n", " # if len(best_of_the_best_2) > 0:\n", " # guess = best_of_the_best_2[0]\n", " # else:\n", " # guess = best_of_the_best_1[0] # they're all equally the best of the best possible guesses so just pick the first\n", "\n", " if guess_num < len(guesses):\n", " guess = guesses[guess_num]\n", " \n", " # guess_entropies.append(get_word_rating([guess], word_list, normalized = False, ascending = False)[0][1])\n", "\n", " if return_stats == False:\n", " if verbose == True:\n", " if len(word_ratings) <= 40:\n", " print(f\"All potential next guesses:\\n\\t{word_ratings}\\n\")\n", " print(f\"Words guessed so far:\\n\\t{guessed_words}.\\n\")\n", " else:\n", " print(f\"The top 40 potential next guesses are:\\n\\t{word_ratings[:40]}\\n\")\n", " print(f\"Words guessed so far:\\n\\t{guessed_words}.\\n\")\n", "\n", " guess_entropies.append(get_word_rating([guess], word_list, normalized = False, ascending = False)[0][1])\n", "\n", " #### Guess has now been made -- what to do next\n", " if guess_num == max_guesses: # if at max guesses allowed\n", " guessed_words.append(guess)\n", " stats_dict['target_guessed'] = False\n", " if return_stats == False:\n", " if verbose == True:\n", " print(\"-----------------------------\\n\")\n", " print(f\"\\nUnfortunately, the puzzle was not solved in {max_guesses} guesses. Better luck next time!\")\n", " print(f\"The target word was '{target}'.\\n\")\n", " print(\"-----------------------------\\n\")\n", " else:\n", " print(f\"\\nUnfortunately, the puzzle was not solved in {max_guesses} guesses. Better luck next time!\")\n", " print(f\"The target word was '{target}'.\\n\")\n", " break\n", " else: # if not at max guesses yet allowed\n", " # stats_dict['target_guessed'] = False\n", " if return_stats == False:\n", " if verbose == True:\n", " if len(potential_next_guesses) > 1:\n", " print(f\"Recommended next guess:\\n\\t'{word_ratings[0][0]}'\")\n", " \n", " # print(f\"Next guess:\\n\\t'{guess}'\")\n", " print(\"\\n-----------------------------\\n\")\n", "\n", " if guess == target:\n", " guess_num += 1\n", " guessed_words.append(guess)\n", " stats_dict['target_guessed'] = True\n", "\n", " if return_stats == False:\n", " print(f\"**Guess {guess_num}: '{guess}'**\\n\")\n", " print(f\"You solved the puzzle in {guess_num} guesses!\")\n", "\n", " if max_guesses - guess_num == 1:\n", " print(f\"There was only {max_guesses - guess_num} guess remaining.\")\n", " else:\n", " print(f\"There were still {max_guesses - guess_num} guesses remaining.\")\n", "\n", " if return_stats == False: \n", " # stats_dict['target_guessed'] = True \n", " print(f\"\\nThe target word was **'{target}'**.\")\n", " print(\"\\n-----------------------------\")\n", " break\n", "\n", " #### STATS STUFF \n", " mid_guesses_vows = 0\n", " mid_guesses_cons = 0\n", " avg_perf_letters = 0\n", " avg_wrong_pos_letters = 0\n", " avg_wrong_letters = 0\n", "\n", " for i, word in enumerate(guessed_words):\n", " mid_guesses_vows += count_vows_cons(word, y_vow = True)['vows']\n", " mid_guesses_cons += count_vows_cons(word, y_vow = True)['cons']\n", " \n", " for i in range(0, len(guessed_words) - 1):\n", " avg_perf_letters += perfect_letts_per_guess[i]\n", " avg_wrong_pos_letters += wrong_pos_per_guess[i]\n", " avg_wrong_letters += wrong_letts_per_guess[i]\n", "\n", " stats_dict['mid_guesses_avg_vows'] = float(round(mid_guesses_vows / len(guessed_words), 2))\n", " stats_dict['mid_guesses_avg_cons'] = float(round(mid_guesses_cons / len(guessed_words), 2))\n", "\n", " stats_dict['avg_perf_letters'] = float(round(np.mean(avg_perf_letters), 2))\n", " stats_dict['avg_wrong_pos_letters'] = float(round(np.mean(avg_wrong_pos_letters), 2))\n", " stats_dict['avg_wrong_letters'] = float(round(np.mean(avg_wrong_letters), 2))\n", " \n", " # average number of words remaining after each guess -- the higher this is, the luckier the person got (the lower, the more guesses it took)\n", " stats_dict['avg_remaining'] = float(round(np.mean(reduction_per_guess), 2))\n", "\n", " # avg rating of each guessed word relative to all other words possible at that moment -- this should consistently be 100 for the algorithm, but will be different for user\n", " if len(guess_entropies) > 1: # in case of guessing it correctly on the first try\n", " sum_entropies = 0\n", " for rating in guess_entropies:\n", " sum_entropies += rating\n", "\n", " average_rating = float(round(sum_entropies / len(guess_entropies), 2))\n", " stats_dict['avg_intermediate_guess_rating'] = average_rating\n", " else:\n", " stats_dict['avg_intermediate_guess_rating'] = float(100)\n", "\n", " expected_guesses = 3.85\n", "\n", " # guess_num = 3\n", " # average_rating = 95\n", " luck = round(1 - ((((guess_num / expected_guesses) * (stats_dict['avg_intermediate_guess_rating'] / 100)) / max_guesses) * 5), 2)\n", " stats_dict['luck'] = luck\n", "\n", " if record == True:\n", " if verbose == True:\n", " with open(f\"solutions/{guessed_words[0]}_{target}_wizard_detailed.txt\", \"w\") as fout:\n", " \n", " fout.write(line + \"\\n\") # write each line of list of # printed text to .txt file\n", " else:\n", " with open(f\"solutions/{guessed_words[0]}_{target}_wizard_summary.txt\", \"w\") as fout:\n", " \n", " fout.write(line + \"\\n\") # write\n", "\n", " if guess_num <= 6:\n", " stats_dict['valid_success'] = True\n", " else:\n", " stats_dict['valid_success'] = False\n", "\n", " stats_dict['num_guesses'] = float(guess_num)" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [], "source": [ "def wordle_wizard_cheat(guesses: list, word_list: list, max_guesses: int = None, \n", " target: str = None,\n", " random_guess: bool = False, random_target: bool = False, \n", " verbose: bool = False, drama: float = None, \n", " return_stats: bool = False, record: bool = False):\n", " \"\"\"\n", " Mimicking the popular web game, this function matches a current word to a target word automatically, in the most statistically optimal way possible.\n", "\n", " Parameters:\n", " ------\n", " `word_list`: list\n", " list of valid words to be considered\n", " `guess`: str\n", " a string -- must be the same length as `target_word`\n", " `target`: str\n", " a string -- must be the same length as `opening_word`\n", " `max_guesses`: int\n", " the maximum number of attempts allowed to solve the Wordle\n", " `random_guess`: bool\n", " if True, randomly chooses a starting word from all words within `word_list`. If False, passed starting word must be used instead\n", " `random_target`: bool\n", " if True, randomly chooses a target word from all words within `word_list`. If False, passed target word must be used instead\n", " `verbose`: bool\n", " if True, # st.writes progress and explanation of how function solves the puzzle. If False, # st.writes only the guessed word at each guess.\n", " `drama`: float or int\n", " if int provided, each guess' output is delayed by that number of seconds, else each output is shown as quickly as possible. For ~dRaMaTiC eFfEcT~\n", " `return_stats`: bool\n", " if True, # st.writes nothing and returns a dictionary of various statistics about the function's performance trying to solve the puzzle\n", " `record`: bool\n", " if True, creates a .txt file with the same information # st.writeed according to the indicated verbosity\n", "\n", " Returns:\n", " ------\n", " `stats_dict`: dict\n", " dictionary containing various statistics about the function's performance trying to solve the puzzle\n", " \"\"\"\n", "\n", " # guess = guess.lower()\n", " target = target.lower()\n", "\n", " sugg_words = []\n", "\n", " for i in range(0, 20):\n", " ran_int = random.randint(0, len(word_list) - 1)\n", " word = word_list[ran_int]\n", " sugg_words.append(word)\n", "\n", " guess = guesses[0]\n", "\n", " stats_dict = {}\n", " stats_dict['first_guess'] = guess\n", " stats_dict['target_word'] = target\n", " stats_dict['first_guess_vowels'] = float(count_vows_cons(guess, y_vow = True)['vows'])\n", " stats_dict['first_guess_consonants'] = float(count_vows_cons(guess, y_vow = True)['cons'])\n", " stats_dict['target_vowels'] = float(count_vows_cons(target, y_vow = True)['vows'])\n", " stats_dict['target_consonants'] = float(count_vows_cons(target, y_vow = True)['cons'])\n", " \n", " # get rating of the first guess word and target word in the entire word_list\n", " for tup in get_word_rating(word_list, word_list, normalized = True):\n", " if tup[0] == guess:\n", " stats_dict['first_guess_rating'] = tup[1]\n", " if tup[0] == target:\n", " stats_dict['target_rating'] = tup[1]\n", "\n", " guess_entropies = []\n", " guess_entropies.append(stats_dict['first_guess_rating'])\n", "\n", " # luck_guess_1 = round(1 - ((1 / len(word_list)) * guess_entropies[0] / 100), 2) * 100\n", "\n", " english_alphabet = \"abcdefghijklmnopqrstuvwxyz\"\n", "\n", " # word_list_sorted_counts = get_letter_counts(english_alphabet, word_list, sort = \"descending\")\n", " word_list_sorted_counts = get_letter_counts(word_list = word_list, letters = english_alphabet, sort = \"descending\", unique = True)\n", "\n", " wordlen = len(guesses[0])\n", " letter_positions = set(i for i in range(0, wordlen))\n", "\n", " guess_set = set()\n", " perfect_dict = {}\n", " wrong_pos_dict = {}\n", " wrong_pos_set = set()\n", " dont_guess_again = set()\n", "\n", " guessed_words = [] # running set of guessed words\n", " guess_num = 0 # baseline for variable\n", " dont_guess_words = set()\n", " incorrect_positions = []\n", " reduction_per_guess = []\n", "\n", " if max_guesses == None: # if no value is passed, default is len(guess)\n", " max_guesses = wordlen\n", " else: # else it is the value passed\n", " max_guesses = max_guesses\n", "\n", " perfect_letts_per_guess = []\n", " wrong_pos_per_guess = []\n", " wrong_letts_per_guess = []\n", "\n", " # while guess: # while there is any guess -- there are conditions to break it at the bottom\n", "\n", " for guess_num, guess in enumerate(guesses):\n", "\n", " guess_num += 1\n", "\n", " guessed_words.append(guess)\n", "\n", " if drama:\n", " time.sleep(drama)\n", "\n", " # guess_num += 1 # each time the guess is processed\n", " if return_stats == False:\n", " if guess_num == 1:\n", " st.write(\"-----------------------------\\n\")\n", "\n", " if guess == target:\n", " stats_dict['target_guessed'] = True\n", " if return_stats == False:\n", " if guess_num == 1:\n", " # st.write(f\"Congratulations! The Wordle has been solved in {guess_num} guess, that's amazingly lucky!\")\n", " st.write(f\"The starting word and target word are the same. Try entering two different words to see how the puzzle can be solved.\")\n", " # st.write(f\"The target word was {target}\")\n", " \n", " \n", " perfect_letts_per_guess.append(5)\n", " wrong_pos_per_guess.append(0)\n", " wrong_letts_per_guess.append(0)\n", " break\n", " \n", " if return_stats == False:\n", " st.write(f\"**Guess {guess_num}: '{guess}'**\")\n", "\n", " guess_set = set()\n", " wrong_pos_set = set()\n", "\n", " #### Step 2 -- ALL PERFECT\n", " for i in letter_positions: # number of letters in each word (current word and target word)\n", " guess_set.add(guess[i])\n", "\n", " if guess[i] not in perfect_dict:\n", " perfect_dict[guess[i]] = set()\n", " if guess[i] not in wrong_pos_dict:\n", " wrong_pos_dict[guess[i]] = set()\n", "\n", " ### EVALUATE CURRENT GUESS\n", " if guess[i] == target[i]: # letter == correct and position == correct\n", " perfect_dict[guess[i]].add(i)\n", "\n", " if (guess[i] != target[i] and guess[i] in target): # letter == correct and position != correct\n", " wrong_pos_dict[guess[i]].add(i)\n", " wrong_pos_set.add(guess[i])\n", "\n", " if guess[i] not in target: # if letter is not relevant at all\n", " dont_guess_again.add(guess[i])\n", "\n", " #### Step 3 -- ALL PERFECT\n", " next_letters = set()\n", " for letter, positions in perfect_dict.items():\n", " if len(positions) > 0:\n", " next_letters.add(letter)\n", "\n", " for letter, positions in wrong_pos_dict.items():\n", " if len(positions) > 0:\n", " next_letters.add(letter)\n", "\n", " #### List of tuples of correct letter positions in new valid words. Eg: [('e', 2), ('a', 3)]\n", " perfect_letters = []\n", " for letter, positions in perfect_dict.items():\n", " for pos in positions:\n", " if len(positions) > 0:\n", " perfect_letters.append((letter, pos))\n", "\n", " #### all words that have correct letters in same spots\n", " words_matching_correct_all = []\n", " for word in word_list:\n", " word_set = set()\n", " for letter, pos in perfect_letters:\n", " if pos < len(word):\n", " if word[pos] == letter:\n", " words_matching_correct_all.append(word)\n", "\n", " #### excluding words with letters in known incorrect positions\n", " for letter, positions in wrong_pos_dict.items():\n", " for pos in positions:\n", " if len(positions) > 0:\n", " if (letter, pos) not in incorrect_positions:\n", " incorrect_positions.append((letter, pos))\n", "\n", " # sorting lists of tuples just to make them look nice in the # st.writeout\n", " incorrect_positions = sorted(incorrect_positions, key = operator.itemgetter(1), reverse = False)\n", " perfect_letters = sorted(perfect_letters, key = operator.itemgetter(1), reverse = False)\n", "\n", " #### all words that have correct letters in incorrect spots -- so they can be excluded efficiently\n", " \n", " # st.write(incorrect_positions)\n", " \n", " for word in word_list:\n", " word_set = set()\n", " for letter, pos in incorrect_positions:\n", " if pos < len(word):\n", " if word[pos] == letter:\n", " dont_guess_words.add(word)\n", " for word in word_list:\n", " word_set = set()\n", " for letter, pos in incorrect_positions:\n", " if pos < len(word):\n", " if word[pos] == letter:\n", " dont_guess_words.add(word)\n", "\n", " for bad_letter in dont_guess_again:\n", " for word in word_list:\n", " if (bad_letter in word and word not in dont_guess_words):\n", " dont_guess_words.add(word)\n", "\n", " if return_stats == False:\n", " if verbose == True:\n", " st.write(f\"Letters in correct positions:\\n\\t{perfect_letters}\\n\")\n", " st.write(f\"Letters in incorrect positions:\\n\\t{incorrect_positions}\\n\")\n", " # st.write (f\"Letters to guess again:\\n\\t{sorted(list(next_letters), reverse = False)}\\n\")\n", " st.write(f\"Letters to not guess again:\\n\\t{sorted(list(dont_guess_again), reverse = False)}\\n\") # works\n", "\n", " # Returns True\n", " # st.write(A.issubset(B)) # \"if everything in A is in B\", returns Bool\n", "\n", " perfect_letts_per_guess.append(len(perfect_letters))\n", " wrong_pos_per_guess.append(len(incorrect_positions))\n", " wrong_letts_per_guess.append(len(dont_guess_again))\n", "\n", " potential_next_guesses = set()\n", " middle_set = set()\n", "\n", " if len(perfect_letters) == 0 and len(incorrect_positions) == 0: # if there are NEITHER perfect letters, NOR incorrect positions, ....\n", " for word in word_list:\n", " if word not in dont_guess_words:\n", " if word not in guessed_words:\n", " potential_next_guesses.add(word)\n", " \n", " # st.write(f\"GUESS {guess_num} : TEST 1-1\")\n", "\n", " if len(perfect_letters) == 0 and len(incorrect_positions) != 0: # if there are no perfect letters whatsoever, but there ARE incorrect positions ....\n", " for word in word_list:\n", " for incor_letter, incor_pos in incorrect_positions:\n", " if incor_pos < len(word):\n", " if word[incor_pos] != incor_letter:\n", " if word not in dont_guess_words: # just in case\n", " word_set = set()\n", " for letter in word:\n", " word_set.add(letter)\n", " \n", " if next_letters.issubset(word_set):\n", " if word not in guessed_words:\n", " if len(dont_guess_again) > 0:\n", " for bad_letter in dont_guess_again:\n", " if bad_letter not in word:\n", " # potential_next_guesses.append(word)\n", " potential_next_guesses.add(word)\n", " else:\n", " potential_next_guesses.add(word)\n", " \n", " # st.write(f\"GUESS {guess_num} : TEST 2-1\")\n", "\n", " else:\n", " for word in word_list:\n", " if word not in dont_guess_words: # just in case\n", " word_set = set()\n", " for letter in word:\n", " word_set.add(letter)\n", " if next_letters.issubset(word_set):\n", " if word not in guessed_words:\n", " # # st.write (\"TEST 3-2\")\n", "\n", " if len(dont_guess_again) > 0:\n", " for bad_letter in dont_guess_again:\n", " if bad_letter not in word:\n", " middle_set.add(word)\n", " else:\n", " middle_set.add(word)\n", " for word in middle_set:\n", " dummy_list = []\n", " for good_lett, good_pos in perfect_letters:\n", " if word[good_pos] == good_lett:\n", " dummy_list.append(1)\n", " if len(dummy_list) == len(perfect_letters):\n", " potential_next_guesses.add(word)\n", " for word in middle_set:\n", " dummy_list = []\n", " for bad_lett, bad_pos in incorrect_positions:\n", " if bad_pos < len(word):\n", " if word[bad_pos] == bad_lett:\n", " dummy_list.append(1)\n", " if len(dummy_list) > 0:\n", " potential_next_guesses.remove(word)\n", " \n", " # st.write(f\"GUESS {guess_num} : TEST 3-1\")\n", "\n", " if return_stats == False:\n", " if verbose == True:\n", " if len(potential_next_guesses) > 1:\n", " # st.write(f\"At this point:\")\n", " st.write(f\"\\t{len(word_list) - len(potential_next_guesses)}, {round((len(word_list) - len(potential_next_guesses)) / len(word_list) * 100, 2)}% of total words have been eliminated, and\")\n", " st.write(f\"\\t{len(potential_next_guesses)}, {round(len(potential_next_guesses) / len(word_list) * 100, 2)}% of total words remain possible.\\n\")\n", " \n", " else:\n", " # st.write(f\"At this point:\")\n", " st.write(f\"\\t{len(word_list) - len(potential_next_guesses)}, {round((len(word_list) - len(potential_next_guesses)) / len(word_list) * 100, 2)}% of total words have been eliminated, and\")\n", " st.write(f\"\\t{len(potential_next_guesses)}, {round(len(potential_next_guesses) / len(word_list) * 100, 2)}% of total words remain possible.\\n\")\n", " \n", " reduction_per_guess.append(len(potential_next_guesses))\n", " \n", " #### Guessing next word\n", " if len(potential_next_guesses) == 1:\n", "\n", " if return_stats == False:\n", " if verbose == True:\n", " st.write(f\"All potential next guesses:\\n\\t{get_word_rating(words_to_rate = list(potential_next_guesses), word_list = word_list)}\\n\")\n", " st.write(f\"Words guessed so far:\\n\\t{guessed_words}.\\n\")\n", " \n", " st.write(f\"The only remaining possible word is:\\n\\t'{list(potential_next_guesses)[0]}'\")\n", " \n", " # guess = list(potential_next_guesses)[0]\n", " if guess_num < len(guesses):\n", " guess = guesses[guess_num]\n", " guess_entropies.append(get_word_rating([guess], word_list, normalized = False, ascending = False)[0][1])\n", "\n", " else:\n", "\n", " best_next_guesses = list(potential_next_guesses) \n", " # # st.write (best_next_guesses)\n", " word_ratings = get_word_rating(best_next_guesses, word_list, normalized = False, ascending = False) # \"internal\" ratings\n", " \n", " # Get max rating of all words\n", " max_rating = -np.inf\n", " for word, rating in word_ratings:\n", " if rating > max_rating:\n", " max_rating = rating\n", "\n", " # add best rated words (all equally best rating in next guess list) to set\n", " best_of_the_best_1 = []\n", " for word, rating in word_ratings:\n", " if rating == max_rating:\n", " best_of_the_best_1.append(word)\n", "\n", " # only using top ten most frequent prefixes suffixes to bias. After that it the impact is especially negligible\n", " test_starts = get_gram_freq(word_list = word_list, letters_length = 1, position = \"start\", search = None)[:10]\n", " test_ends = get_gram_freq(word_list = word_list, letters_length = 1, position = \"end\", search = None)[:10]\n", "\n", " # list of the best words that also have the most frequent starting and ending letters (suffixes and prefixes didn't have an impact)\n", " best_of_the_best_2 = []\n", " for start_gram, start_count in test_starts:\n", " for end_gram, end_count in test_ends:\n", " for word in best_of_the_best_1:\n", " if word[:1] == start_gram and word[-1:] == end_gram:\n", " best_of_the_best_2.append(word)\n", "\n", " # if len(best_of_the_best_2) > 0:\n", " # guess = best_of_the_best_2[0]\n", " # else:\n", " # guess = best_of_the_best_1[0] # they're all equally the best of the best possible guesses so just pick the first\n", "\n", " if guess_num < len(guesses):\n", " guess = guesses[guess_num]\n", " \n", " # guess_entropies.append(get_word_rating([guess], word_list, normalized = False, ascending = False)[0][1])\n", "\n", " if return_stats == False:\n", " if verbose == True:\n", " if len(word_ratings) <= 40:\n", " st.write(f\"All potential next guesses:\\n\\t{word_ratings}\\n\")\n", " st.write(f\"Words guessed so far:\\n\\t{guessed_words}.\\n\")\n", " else:\n", " st.write(f\"The top 40 potential next guesses are:\\n\\t{word_ratings[:40]}\\n\")\n", " st.write(f\"Words guessed so far:\\n\\t{guessed_words}.\\n\")\n", "\n", " guess_entropies.append(get_word_rating([guess], word_list, normalized = False, ascending = False)[0][1])\n", "\n", " #### Guess has now been made -- what to do next\n", " if guess_num == max_guesses: # if at max guesses allowed\n", " guessed_words.append(guess)\n", " stats_dict['target_guessed'] = False\n", " if return_stats == False:\n", " if verbose == True:\n", " st.write(\"-----------------------------\\n\")\n", " st.write(f\"\\nUnfortunately, the puzzle was not solved in {max_guesses} guesses. Better luck next time!\")\n", " st.write(f\"The target word was '{target}'.\\n\")\n", " st.write(\"-----------------------------\\n\")\n", " else:\n", " st.write(f\"\\nUnfortunately, the puzzle was not solved in {max_guesses} guesses. Better luck next time!\")\n", " st.write(f\"The target word was '{target}'.\\n\")\n", " break\n", " else: # if not at max guesses yet allowed\n", " # stats_dict['target_guessed'] = False\n", " if return_stats == False:\n", " if verbose == True:\n", " if len(potential_next_guesses) > 1:\n", " st.write(f\"Recommended next guess:\\n\\t'{word_ratings[0][0]}'\")\n", " \n", " # st.write(f\"Next guess:\\n\\t'{guess}'\")\n", " st.write(\"\\n-----------------------------\\n\")\n", "\n", " if guess == target:\n", " guess_num += 1\n", " guessed_words.append(guess)\n", " stats_dict['target_guessed'] = True\n", "\n", " if return_stats == False:\n", " st.write(f\"**Guess {guess_num}: '{guess}'**\\n\")\n", " st.write(f\"You solved the puzzle in {guess_num} guesses!\")\n", "\n", " if max_guesses - guess_num == 1:\n", " st.write(f\"There was only {max_guesses - guess_num} guess remaining.\")\n", " else:\n", " st.write(f\"There were still {max_guesses - guess_num} guesses remaining.\")\n", "\n", " if return_stats == False: \n", " # stats_dict['target_guessed'] = True \n", " st.write(f\"\\nThe target word was **'{target}'**.\")\n", " st.write(\"\\n-----------------------------\")\n", " break\n", "\n", " #### STATS STUFF \n", " mid_guesses_vows = 0\n", " mid_guesses_cons = 0\n", " avg_perf_letters = 0\n", " avg_wrong_pos_letters = 0\n", " avg_wrong_letters = 0\n", "\n", " for i, word in enumerate(guessed_words):\n", " mid_guesses_vows += count_vows_cons(word, y_vow = True)['vows']\n", " mid_guesses_cons += count_vows_cons(word, y_vow = True)['cons']\n", " \n", " for i in range(0, len(guessed_words) - 1):\n", " avg_perf_letters += perfect_letts_per_guess[i]\n", " avg_wrong_pos_letters += wrong_pos_per_guess[i]\n", " avg_wrong_letters += wrong_letts_per_guess[i]\n", "\n", " stats_dict['mid_guesses_avg_vows'] = float(round(mid_guesses_vows / len(guessed_words), 2))\n", " stats_dict['mid_guesses_avg_cons'] = float(round(mid_guesses_cons / len(guessed_words), 2))\n", "\n", " stats_dict['avg_perf_letters'] = float(round(np.mean(avg_perf_letters), 2))\n", " stats_dict['avg_wrong_pos_letters'] = float(round(np.mean(avg_wrong_pos_letters), 2))\n", " stats_dict['avg_wrong_letters'] = float(round(np.mean(avg_wrong_letters), 2))\n", " \n", " # average number of words remaining after each guess -- the higher this is, the luckier the person got (the lower, the more guesses it took)\n", " stats_dict['avg_remaining'] = float(round(np.mean(reduction_per_guess), 2))\n", "\n", " # avg rating of each guessed word relative to all other words possible at that moment -- this should consistently be 100 for the algorithm, but will be different for user\n", " if len(guess_entropies) > 1: # in case of guessing it correctly on the first try\n", " sum_entropies = 0\n", " for rating in guess_entropies:\n", " sum_entropies += rating\n", "\n", " average_rating = float(round(sum_entropies / len(guess_entropies), 2))\n", " stats_dict['avg_intermediate_guess_rating'] = average_rating\n", " else:\n", " stats_dict['avg_intermediate_guess_rating'] = float(100)\n", "\n", " expected_guesses = 3.85\n", "\n", " # guess_num = 3\n", " # average_rating = 95\n", " luck = round(1 - ((((guess_num / expected_guesses) * (stats_dict['avg_intermediate_guess_rating'] / 100)) / max_guesses) * 5), 2)\n", " stats_dict['luck'] = luck\n", "\n", " if record == True:\n", " if verbose == True:\n", " with open(f\"solutions/{guessed_words[0]}_{target}_wizard_detailed.txt\", \"w\") as fout:\n", " \n", " fout.write(line + \"\\n\") # write each line of list of # st.writeed text to .txt file\n", " else:\n", " with open(f\"solutions/{guessed_words[0]}_{target}_wizard_summary.txt\", \"w\") as fout:\n", " \n", " fout.write(line + \"\\n\") # write\n", "\n", " if guess_num <= 6:\n", " stats_dict['valid_success'] = True\n", " else:\n", " stats_dict['valid_success'] = False\n", "\n", " stats_dict['num_guesses'] = float(guess_num)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-----------------------------\n", "\n", "**Guess 1: 'tried'**\n", "Letters in correct positions:\n", "\t[('t', 0)]\n", "\n", "Letters in incorrect positions:\n", "\t[('e', 3)]\n", "\n", "Letters to not guess again:\n", "\t['d', 'i', 'r']\n", "\n", "\t2293, 99.22% of total words have been eliminated, and\n", "\t18, 0.78% of total words remain possible.\n", "\n", "All potential next guesses:\n", "\t[('table', 32.95), ('teach', 32.13), ('those', 31.55), ('taste', 30.22), ('tease', 30.22), ('tempo', 28.27), ('tweak', 28.14), ('theta', 27.97), ('tense', 26.89), ('tulle', 26.28), ('thyme', 26.19), ('testy', 25.66), ('these', 25.29), ('tenth', 24.64), ('theme', 22.31), ('tests', 21.78), ('theft', 21.46), ('teeth', 19.54)]\n", "\n", "Words guessed so far:\n", "\t['tried'].\n", "\n", "Recommended next guess:\n", "\t'table'\n", "\n", "-----------------------------\n", "\n", "**Guess 2: 'score'**\n", "Letters in correct positions:\n", "\t[('t', 0)]\n", "\n", "Letters in incorrect positions:\n", "\t[('s', 0), ('e', 3), ('e', 4)]\n", "\n", "Letters to not guess again:\n", "\t['c', 'd', 'i', 'o', 'r']\n", "\n", "\t2309, 99.91% of total words have been eliminated, and\n", "\t2, 0.09% of total words remain possible.\n", "\n", "All potential next guesses:\n", "\t[('testy', 25.66), ('tests', 21.78)]\n", "\n", "Words guessed so far:\n", "\t['tried', 'score'].\n", "\n", "Recommended next guess:\n", "\t'testy'\n", "\n", "-----------------------------\n", "\n", "**Guess 3: 'messy'**\n", "Letters in correct positions:\n", "\t[('t', 0), ('e', 1), ('s', 2)]\n", "\n", "Letters in incorrect positions:\n", "\t[('s', 0), ('e', 3), ('s', 3), ('e', 4)]\n", "\n", "Letters to not guess again:\n", "\t['c', 'd', 'i', 'm', 'o', 'r', 'y']\n", "\n", "\t2310, 99.96% of total words have been eliminated, and\n", "\t1, 0.04% of total words remain possible.\n", "\n", "All potential next guesses:\n", "\t[('tests', 100.0)]\n", "\n", "Words guessed so far:\n", "\t['tried', 'score', 'messy'].\n", "\n", "The only remaining possible word is:\n", "\t'tests'\n", "\n", "-----------------------------\n", "\n" ] } ], "source": [ "guesses = [\n", " \"tried\",\n", " # \"tried\",\n", " \"score\",\n", " \"messy\",\n", " # \"traps\",\n", " # \"bummy\",\n", " # \"chore\"\n", "]\n", "\n", "wordle_wizard_cheat_local(guesses = guesses, word_list = official_words, max_guesses = 6, \n", " target = \"tests\",\n", " random_guess = False, random_target = False, \n", " verbose = True, drama = 0, return_stats = False, record = False)\n", "\n", "# wordle_wizard_cheat(guesses = guesses, word_list = official_words, max_guesses = 6, \n", "# target = \"force\",\n", "# random_guess = False, random_target = False, \n", "# verbose = True, drama = 0, return_stats = False, record = False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Testing Scraping + Assistant" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "2023-07-17 11:37:27.782 INFO selenium.webdriver.common.selenium_manager: Executing: /opt/miniconda3/lib/python3.10/site-packages/selenium/webdriver/common/macos/selenium-manager --browser chrome --output json\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "droop\n" ] } ], "source": [ "# import requests\n", "from bs4 import BeautifulSoup\n", "\n", "# !pip install selenium\n", "from selenium import webdriver\n", "from selenium.webdriver.common.keys import Keys\n", "from selenium.webdriver.chrome.options import Options\n", "\n", "# Configure ChromeOptions\n", "chrome_options = Options()\n", "chrome_options.add_argument(\"--headless\") # Run Chrome in headless mode\n", "\n", "# driver = webdriver.Chrome()\n", "driver = webdriver.Chrome(options = chrome_options)\n", "\n", "url = \"https://screenrant.com/wordle-answers-updated-word-puzzle-guide/\"\n", "\n", "# Navigate to the URL\n", "driver.get(url)\n", "\n", "# Get the page source\n", "html_content = driver.page_source\n", " \n", "soup = BeautifulSoup(html_content, \"html.parser\")\n", "for item in soup.find_all('a'):\n", " \n", " item_link = item['href']\n", "\n", " link_prefix = \"https://screenrant.com/todays-wordle-answer-hints\"\n", "\n", " if item_link:\n", " \n", " if link_prefix in item_link:\n", " good_item = item\n", " break\n", "\n", "good_text = good_item.text\n", "target_word = good_text.split(\" - \")[-1].lower() # something like \"topaz\"\n", "print(target_word)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-----------------------------\n", "\n", "**Guess 1: 'arose'**\n", "Letters in correct positions:\n", "\t[('r', 1), ('o', 2)]\n", "\n", "Letters in incorrect positions:\n", "\t[]\n", "\n", "Letters to not guess again:\n", "\t['a', 'e', 's']\n", "\n", "\t2273, 98.36% of total words have been eliminated, and\n", "\t38, 1.64% of total words remain possible.\n", "\n", "All potential next guesses:\n", "\t[('droit', 29.71), ('irony', 29.02), ('broil', 28.52), ('groin', 27.93), ('grout', 27.28), ('front', 27.27), ('crony', 27.16), ('troll', 26.25), ('broth', 26.23), ('froth', 25.67), ('croup', 25.64), ('prong', 25.13), ('crown', 25.08), ('prowl', 25.04), ('proud', 24.93), ('growl', 24.61), ('trout', 24.49), ('frond', 24.49), ('drown', 24.37), ('group', 24.27), ('wrong', 23.71), ('grown', 23.71), ('droll', 23.48), ('drool', 23.48), ('troop', 23.46), ('crowd', 23.42), ('brown', 23.4), ('frown', 22.84), ('frock', 21.98), ('proxy', 21.46), ('droop', 20.69), ('crook', 20.06), ('crock', 20.06), ('brood', 19.95), ('groom', 19.59), ('broom', 19.28), ('proof', 19.16), ('brook', 18.39)]\n", "\n", "Words guessed so far:\n", "\t['arose'].\n", "\n", "Recommended next guess:\n", "\t'droit'\n", "\n", "-----------------------------\n", "\n", "**Guess 2: 'droit'**\n", "Letters in correct positions:\n", "\t[('d', 0), ('r', 1), ('o', 2)]\n", "\n", "Letters in incorrect positions:\n", "\t[]\n", "\n", "Letters to not guess again:\n", "\t['a', 'e', 'i', 's', 't']\n", "\n", "\t2307, 99.83% of total words have been eliminated, and\n", "\t4, 0.17% of total words remain possible.\n", "\n", "All potential next guesses:\n", "\t[('drown', 24.37), ('drool', 23.48), ('droll', 23.48), ('droop', 20.69)]\n", "\n", "Words guessed so far:\n", "\t['arose', 'droit'].\n", "\n", "Recommended next guess:\n", "\t'drown'\n", "\n", "-----------------------------\n", "\n", "**Guess 3: 'drown'**\n", "Letters in correct positions:\n", "\t[('d', 0), ('r', 1), ('o', 2)]\n", "\n", "Letters in incorrect positions:\n", "\t[]\n", "\n", "Letters to not guess again:\n", "\t['a', 'e', 'i', 'n', 's', 't', 'w']\n", "\n", "\t2308, 99.87% of total words have been eliminated, and\n", "\t3, 0.13% of total words remain possible.\n", "\n", "All potential next guesses:\n", "\t[('drool', 23.48), ('droll', 23.48), ('droop', 20.69)]\n", "\n", "Words guessed so far:\n", "\t['arose', 'droit', 'drown'].\n", "\n", "Recommended next guess:\n", "\t'drool'\n", "\n", "-----------------------------\n", "\n", "**Guess 4: 'drool'**\n", "Letters in correct positions:\n", "\t[('d', 0), ('r', 1), ('o', 2), ('o', 3)]\n", "\n", "Letters in incorrect positions:\n", "\t[]\n", "\n", "Letters to not guess again:\n", "\t['a', 'e', 'i', 'l', 'n', 's', 't', 'w']\n", "\n", "\t2310, 99.96% of total words have been eliminated, and\n", "\t1, 0.04% of total words remain possible.\n", "\n", "All potential next guesses:\n", "\t[('droop', 100.0)]\n", "\n", "Words guessed so far:\n", "\t['arose', 'droit', 'drown', 'drool'].\n", "\n", "The only remaining possible word is:\n", "\t'droop'\n", "\n", "-----------------------------\n", "\n" ] } ], "source": [ "guesses = [\n", " 'arose',\n", " 'droit',\n", " 'drown',\n", " 'drool'\n", "]\n", "\n", "wordle_wizard_cheat_local(guesses = guesses, word_list = official_words, max_guesses = 6, \n", " target = target_word,\n", " random_guess = False, random_target = False, \n", " verbose = True, drama = 0, return_stats = False, record = False)" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [], "source": [ "# import streamlit as st\n", "# # import random\n", "# import plotly.express as px\n", "# from bs4 import BeautifulSoup\n", "# from selenium import webdriver\n", "# from selenium.webdriver.common.keys import Keys\n", "# from selenium.webdriver.chrome.options import Options\n", "# import bs4\n", "\n", "# # Since we can't import from streamlit_extras.stateful_button, wordle_assistant_functions, and plots directly, \n", "# # you should replace the placeholders with the correct modules.\n", "# # import streamlit_extras\n", "# # import wordle_assistant_functions\n", "# # import plots\n", "\n", "# print(\"streamlit:\", st.__version__)\n", "# # print(\"streamlit_extras:\", streamlit_extras.__version__)\n", "# print(\"random: This is a built-in module, so it doesn't have a version.\")\n", "# # print(\"wordle_assistant_functions:\", wordle_assistant_functions.__version__)\n", "# # print(\"plotly:\", plotly.version)\n", "# # print(\"plots:\", plots.__version__)\n", "# print(\"BeautifulSoup:\", bs4.__version__)\n", "# print(\"selenium:\", webdriver.__version__)" ] } ], "metadata": { "kernelspec": { "display_name": "base", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.2" }, "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2 }