Skip to content

Commit

Permalink
Add Wordle.import/2 to speed up setting up Wordles
Browse files Browse the repository at this point in the history
  • Loading branch information
idontwantcookies committed Jan 18, 2022
1 parent 86fa402 commit 0f41713
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 21 deletions.
11 changes: 11 additions & 0 deletions lib/wordle.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
58 changes: 39 additions & 19 deletions test/integration_test.exs
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
2 changes: 0 additions & 2 deletions test/parser_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions test/word_stats_test.exs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
defmodule WordStatsTest do
use ExUnit.Case, async: true

doctest WordStats

describe "letter_frequencies/1" do
Expand Down
2 changes: 2 additions & 0 deletions test/wordle/game_test.exs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
defmodule Wordle.GameTest do
use ExUnit.Case, async: true

alias Wordle.Game

doctest Game

describe "guess/2" do
Expand Down
1 change: 1 addition & 0 deletions test/wordle_test.exs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
defmodule WordleTest do
use ExUnit.Case, async: true

doctest Wordle

setup :words
Expand Down

0 comments on commit 0f41713

Please sign in to comment.