Day 3
Mix.install([
{:kino_aoc, "~> 0.1"}
])
Input
{:ok, puzzle_input} =
KinoAOC.download_puzzle("2024", "3", System.fetch_env!("LB_SESSION"))
test input
test_input = """
xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))
"""
Token parser
defmodule Token do
def parse(input) do
input
|> tokenize()
|> Enum.reduce(0, fn [a, b], acc ->
acc + String.to_integer(a) * String.to_integer(b)
end)
end
def tokenize(input) do
~r/mul\((\d+),(\d+)\)/
|> Regex.scan(input, capture: :all_but_first)
# |> IO.inspect(chars: :as_list)
end
end
test_input
|> Token.parse()
defmodule TokenTwo do
def parse(input, enable \\ :enable, acc \\ 0)
def parse(input, :enable, acc) do
Regex.split(~r/don't\(\)/, input, parts: 2)
|> case do
[valid, rest] -> parse(rest, :disable, acc + Token.parse(valid))
[valid] -> acc + Token.parse(valid)
end
end
def parse(input, :disable, acc) do
Regex.split(~r/do\(\)/, input, parts: 2)
|> case do
[_invalid, rest] -> parse(rest, :enable, acc)
[_invalid] -> acc
end
end
end
test_input
# puzzle_input
|> TokenTwo.parse()
test parser
ExUnit.start(autorun: false)
defmodule TokenTest do
use ExUnit.Case, async: true
@test_input """
xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))
"""
test "tokenize" do
assert Token.tokenize(@test_input) == [["2", "4"], ["5", "5"], ["11", "8"], ["8", "5"]]
end
end
ExUnit.run()
part 1
defmodule PartOne do
def solve(input) do
IO.puts("--- Part One ---")
IO.puts("Result: #{run(input)}")
end
def run(input) do
Token.parse(input)
end
end
test_input
# puzzle_input
|> PartOne.run()
part 1 - test
ExUnit.start(autorun: false)
defmodule PartOneTest do
use ExUnit.Case
@input puzzle_input
test "part one" do
assert PartOne.run(@input) == 187_833_789
end
end
ExUnit.run()
part 2
defmodule PartTwo do
def solve(input) do
IO.puts("--- Part Two ---")
IO.puts("Result: #{run(input)}")
end
def run(input) do
TokenTwo.parse(input)
end
end
# test_input
puzzle_input
|> PartTwo.run()
part 2 - test
ExUnit.start(autorun: false)
defmodule PartTwoTest do
use ExUnit.Case
@input puzzle_input
test "part two" do
assert PartTwo.run(@input) == 94_455_185
end
end
ExUnit.run()