Advent of Code 2023 Day 1 (Another Solution for Part 2)
Mix.install([
{:kino_aoc, "~> 0.1.5"}
])
Section
{:ok, puzzle_input} =
KinoAOC.download_puzzle("2023", "1", System.fetch_env!("LB_AOC_SESSION"))
reverse_puzzle_input = String.reverse(puzzle_input)
word_map =
~w[
one
two
three
four
five
six
seven
eight
nine
]
|> Enum.zip_with(1..9, fn w, n -> {w, n} end)
|> Map.new()
|> Map.merge(Map.new(0..9, &{to_string(&1), &1}))
reverse_word_map =
Map.new(word_map, fn {k, v} ->
{String.reverse(k), v}
end)
regex = word_map |> Map.keys() |> Enum.join("|") |> Regex.compile!()
reverse_regex = reverse_word_map |> Map.keys() |> Enum.join("|") |> Regex.compile!()
get_first_nums = fn input, word_map, regex ->
input
|> String.split("\n")
|> Stream.flat_map(fn line ->
Regex.run(regex, line)
end)
|> Enum.map(&word_map[&1])
end
first_digits = get_first_nums.(puzzle_input, word_map, regex)
last_digits = get_first_nums.(reverse_puzzle_input, reverse_word_map, reverse_regex)
first_digits
# ๐ Here's the interesting thing. You don't need to reverse `last_digits` before zipping.
|> Enum.zip_with(last_digits, &(&1 * 10 + &2))
|> Enum.sum()
# ๐ This works too.
Enum.sum(first_digits) * 10 + Enum.sum(last_digits)