From 0f41713e204c70a13b534f3f5be3487abb4b3ab8 Mon Sep 17 00:00:00 2001 From: Felipe Muniz <35815542+fpmuniz@users.noreply.github.com> Date: Tue, 18 Jan 2022 20:52:44 -0300 Subject: [PATCH] Add Wordle.import/2 to speed up setting up Wordles --- lib/wordle.ex | 11 ++++++++ test/integration_test.exs | 58 ++++++++++++++++++++++++++------------- test/parser_test.exs | 2 -- test/word_stats_test.exs | 1 + test/wordle/game_test.exs | 2 ++ test/wordle_test.exs | 1 + 6 files changed, 54 insertions(+), 21 deletions(-) diff --git a/lib/wordle.ex b/lib/wordle.ex index a419973..69c4410 100644 --- a/lib/wordle.ex +++ b/lib/wordle.ex @@ -14,6 +14,17 @@ defmodule Wordle do alias Wordle.{Game, Solver} + @spec import(:en | :pt_br, integer) :: [binary] + def import(language, n_letters) do + "dicts/#{language}.txt" + |> Parser.import_dictionary() + |> Parser.trim() + |> Language.normalize(language) + |> Parser.filter_valid() + |> WordStats.order_by_scores() + |> Parser.filter_number_of_letters(n_letters) + end + @spec solve([binary], binary) :: {:ok | :error, [binary]} def solve(wordlist, right_word) do solve(wordlist, right_word, [], wordlist) diff --git a/test/integration_test.exs b/test/integration_test.exs index 272e5f5..0a4930f 100644 --- a/test/integration_test.exs +++ b/test/integration_test.exs @@ -1,35 +1,55 @@ defmodule IntegrationTest do use ExUnit.Case, async: true - @max_attempts 11 + @language :pt_br @letter_count 5 @moduletag :integration + @moduletag timeout: :infinity setup :wordlist describe "Wordle.solve/2" do - test "solves every case in less than #{@max_attempts} attempts", %{words: words} do - words - |> Enum.with_index() - |> Enum.each(fn {right_word, index} -> - assert {:ok, guesses} = Wordle.solve(words, right_word), - "Could not solve for #{right_word} at position #{index}." - - assert length(guesses) <= @max_attempts, - "Expected to succeed with less than #{@max_attempts} attempts, got [#{guesses |> Enum.join(", ")}]. Failed with word #{right_word} at position #{index}." - end) + test "solves in an average number of guesses", %{words: words} do + solved = + words + |> Enum.with_index() + |> Enum.map(fn {right_word, index} -> + Task.async(fn -> + assert {:ok, guesses} = Wordle.solve(words, right_word), + "Could not solve for #{right_word} at position #{index}." + + {right_word, length(guesses)} + end) + end) + |> Task.await_many(:infinity) + |> Enum.group_by(&elem(&1, 1), &elem(&1, 0)) + |> Enum.map(fn {n_guesses, words} -> {n_guesses, length(words)} end) + |> Map.new() + + average = + Enum.reduce(solved, 0, fn {guesses, count}, acc -> acc + guesses * count end) / + length(words) + + assert average == 4.0650467289719625 + + assert solved == %{ + 1 => 1, + 2 => 185, + 3 => 1574, + 4 => 2088, + 5 => 980, + 6 => 335, + 7 => 125, + 8 => 47, + 9 => 10, + 10 => 3, + 11 => 2 + } end end defp wordlist(context) do - words = - "dicts/pt_br.txt" - |> Parser.import_dictionary() - |> Parser.trim() - |> Language.normalize(:pt_br) - |> Parser.filter_number_of_letters(@letter_count) - |> Parser.filter_valid() - |> WordStats.order_by_scores() + words = Wordle.import(@language, @letter_count) context |> Map.put(:words, words) diff --git a/test/parser_test.exs b/test/parser_test.exs index d57419a..12777a7 100644 --- a/test/parser_test.exs +++ b/test/parser_test.exs @@ -2,8 +2,6 @@ defmodule ParserTest do use ExUnit.Case, async: true doctest Parser - @moduletag :wip - describe "filter_number_of_letters/1" do test "only returns 5 letter words" do words = ~w(do you wanna see five letter words now) diff --git a/test/word_stats_test.exs b/test/word_stats_test.exs index 8c78964..d80cf69 100644 --- a/test/word_stats_test.exs +++ b/test/word_stats_test.exs @@ -1,5 +1,6 @@ defmodule WordStatsTest do use ExUnit.Case, async: true + doctest WordStats describe "letter_frequencies/1" do diff --git a/test/wordle/game_test.exs b/test/wordle/game_test.exs index edf4ff2..9139a22 100644 --- a/test/wordle/game_test.exs +++ b/test/wordle/game_test.exs @@ -1,6 +1,8 @@ defmodule Wordle.GameTest do use ExUnit.Case, async: true + alias Wordle.Game + doctest Game describe "guess/2" do diff --git a/test/wordle_test.exs b/test/wordle_test.exs index 0d39c2c..85979c1 100644 --- a/test/wordle_test.exs +++ b/test/wordle_test.exs @@ -1,5 +1,6 @@ defmodule WordleTest do use ExUnit.Case, async: true + doctest Wordle setup :words