AOC 2023 - Day 01
Mix.install([
{:kino_aoc, "~> 0.1"}
])
AOC Helper
{:ok, puzzle_input} =
KinoAOC.download_puzzle("2023", "1", System.fetch_env!("LB_AOC_SESSION"))
Part 1
Code
defmodule PartOne do
defp process_line(line) do
chars = String.graphemes(line)
start_num = find_number(chars)
end_num = chars |> Enum.reverse() |> find_number()
String.to_integer("#{start_num}#{end_num}")
end
defp find_number(chars) do
Enum.find(chars, fn char ->
case Integer.parse(char) do
{value, _} -> value
:error -> nil
end
end)
end
def solve(input) do
IO.puts("--- Part One ---")
IO.puts("Result: #{run(input)}")
end
def run(input) do
input
|> String.split("\n")
|> Enum.map(&process_line/1)
|> Enum.sum()
end
end
Test
ExUnit.start(autorun: false)
defmodule PartOneTest do
use ExUnit.Case, async: true
import PartOne
@input "1abc2
pqr3stu8vwx
a1b2c3d4e5f
treb7uchet"
@expected 142
test "part one" do
actual = run(@input)
assert actual == @expected
end
end
ExUnit.run()
Solution
PartOne.solve(puzzle_input)
Part 2
Code
defmodule PartTwo do
@num_words %{
"one" => 1,
"two" => 2,
"three" => 3,
"four" => 4,
"five" => 5,
"six" => 6,
"seven" => 7,
"eight" => 8,
"nine" => 9
}
defp process_line(line) do
chars = String.graphemes(line)
start_num = find_number(chars)
end_num = chars |> Enum.reverse() |> find_number()
String.to_integer("#{start_num}#{end_num}")
end
defp find_number(chars) do
chars
|> Enum.with_index()
|> Enum.find_value(fn {char, index} ->
case Integer.parse(char) do
{value, _} -> value
:error -> chars |> Enum.slice(0..index) |> Enum.join("") |> num_word()
end
end)
end
defp num_word(word) do
Enum.find_value(@num_words, fn {key, value} ->
cond do
String.ends_with?(word, key) -> value
word |> String.reverse() |> String.starts_with?(key) -> value
true -> nil
end
end)
end
def solve(input) do
IO.puts("--- Part Two ---")
IO.puts("Result: #{run(input)}")
end
def run(input) do
input
|> String.split("\n")
|> Enum.map(&process_line/1)
|> Enum.sum()
end
end
Test
ExUnit.start(autorun: false)
defmodule PartTwoTest do
use ExUnit.Case, async: true
import PartTwo
@input "two1nine
eightwothree
abcone2threexyz
xtwone3four
4nineeightseven2
zoneight234
7pqrstsixteen"
@expected 281
test "part two" do
actual = run(@input)
assert actual == @expected
end
end
ExUnit.run()
Solution
PartTwo.solve(puzzle_input)