Created
June 9, 2022 07:03
-
-
Save Kenny2github/763e750656948bfd2b567f927db5a51e to your computer and use it in GitHub Desktop.
Generate words for Squaredle - https://squaredle.app
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Squaredle do | |
def find_word(row, col, word, board, past_path) do | |
coords = [ | |
{row + 1, col + 1}, | |
{row + 1, col + 0}, | |
{row + 1, col - 1}, | |
{row + 0, col + 1}, | |
{row + 0, col - 1}, | |
{row - 1, col + 1}, | |
{row - 1, col + 0}, | |
{row - 1, col - 1}, | |
] | |
found = Enum.find(coords, fn {srow, scol} -> | |
if Enum.member?(past_path, {srow, scol}) do | |
false | |
else | |
find_word_guarded(srow, scol, word, board, past_path) | |
end | |
end) | |
found != nil | |
end | |
def find_word_guarded(row, _col, _word, board, _past_path) | |
when row < 0 or row >= tuple_size(board), do: false | |
def find_word_guarded(row, col, _word, board, _past_path) | |
when col < 0 or col >= tuple_size(elem(board, row)), do: false | |
def find_word_guarded(row, col, [letter], board, _past_path) | |
when board |> elem(row) |> elem(col) == letter, do: true | |
def find_word_guarded(row, col, [letter | word], board, past_path) | |
when board |> elem(row) |> elem(col) == letter do | |
find_word(row, col, word, board, [{row, col}] ++ past_path) | |
end | |
def find_word_guarded(_, _, _, _, _), do: false | |
def word_ok([letter | word], board) do | |
dim = tuple_size(board) - 1 | |
found = Enum.find( | |
(for row <- 0..dim, col <- 0..dim, do: {row, col}), | |
fn {row, col} -> | |
if letter == board |> elem(row) |> elem(col) do | |
find_word(row, col, word, board, [{row, col}]) | |
else | |
false | |
end | |
end | |
) | |
found != nil | |
end | |
def word_ok(word, board) when is_binary(word) do | |
word_ok(String.codepoints(word), board) | |
end | |
def make_board(str) do | |
str | |
|> String.trim("\n") | |
|> String.upcase() | |
|> String.split(~r"\r?\n") | |
|> Enum.map(&(&1 |> String.codepoints() |> List.to_tuple())) | |
|> List.to_tuple() | |
end | |
def load_words() do | |
File.read!("all_words.txt") | |
|> String.trim() | |
|> String.split() | |
|> MapSet.new() | |
end | |
def valid_words(board, upto \\ nil) do | |
letters = board |> String.trim() |> String.upcase() | |
letters = Regex.replace(~r"\s*", letters, "") | |
len = upto || byte_size(letters) | |
all_words = load_words() | |
board_t = make_board(board) | |
for n <- 4..len do | |
words = all_words | |
|> Enum.filter(&(byte_size(&1) == n)) | |
|> Enum.map(&String.codepoints/1) | |
|> Enum.filter(&word_ok(&1, board_t)) | |
{n, words} | |
end | |
end | |
def print_valid_words(board, upto \\ nil) do | |
for {n, words} <- valid_words(board, upto) do | |
IO.puts("#{n} letters:") | |
for word <- words do | |
IO.puts(" #{word}") | |
end | |
end | |
end | |
end | |
defmodule I do | |
def gets(prompt \\ "") do | |
case IO.gets(prompt) do | |
:eof -> "" | |
str -> String.trim(str, "\n") | |
end | |
end | |
end | |
board = Enum.join( | |
Stream.unfold(I.gets( | |
"Enter the board, rows separated by line breaks. End with a blank line.\n" | |
), fn | |
"" -> nil | |
line -> {line, I.gets()} | |
end), "\n" | |
) | |
board_t = Squaredle.make_board(board) | |
num = I.gets("Enter number of letters to get to (0 to skip, blank for all): ") | |
num = if num != "" do | |
String.to_integer(num) | |
else | |
byte_size(Regex.replace(~r"\s*", board, "")) | |
end | |
if num > 0, do: Squaredle.print_valid_words(board, num) | |
Enum.find(Stream.cycle([1]), fn _ -> | |
word = I.gets("Enter a word to check (blank to stop): ") |> String.upcase() | |
if word == "" do | |
true | |
else | |
word |> Squaredle.word_ok(board_t) |> IO.inspect() | |
false | |
end | |
end) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment