Advent of Code 2024 - Day 3
Mix.install([
{:kino_aoc, "~> 0.1"}
])
Problem
https://adventofcode.com/2024/day/3
I could have used regular expressions for part two also and things may have been easier or shorter. I wanted to learn pattern matching in Elixir function parameters.
{:ok, puzzle_input} =
KinoAOC.download_puzzle("2024", "3", System.fetch_env!("LB_AOC_SESSION"))
defmodule Day3 do
def compute(str) do
Regex.scan(~r/mul\(\d+,\d+\)/, str)
|> Enum.flat_map(fn str ->
str
end)
|> Enum.map(fn str ->
[a, b] = str |> String.replace("mul(", "") |> String.replace(")", "") |> String.split(",") |> Enum.map(&String.to_integer/1)
a * b
end) |> Enum.sum
end
def p(<<"don't()", rest::bitstring>>, _should_multiply, acc) do
p(rest, false, acc)
end
def p(<<"do()", rest::bitstring>>, _should_multiply, acc) do
p(rest, true, acc)
end
def p(<<"mul(", rest::bitstring>>, false, acc) do
p(rest, false, acc)
end
def p(<<"mul(", rest::bitstring>>, true, acc) do
found = Regex.scan(~r/^\d+,\d+\)/, rest) |> Enum.at(0)
if found do
[nums, _] = found |> Enum.at(0) |> String.split(")", parts: 2)
[a, b ] = nums |> String.split(",", parts: 2) |> Enum.map(&String.to_integer/1)
p(rest, true, [a*b | acc])
else
p(rest, true, acc)
end
end
def p("", _should_multiply, acc) do
IO.inspect(acc)
Enum.sum(acc)
end
def p(<<_a::utf8, rest::bitstring>>, should_multiply, acc) do
p(rest, should_multiply, acc)
end
end
example_input = "xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))"
Day3.compute(example_input)
Day3.compute(puzzle_input)
example_input2 = "xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))"
Day3.p(example_input2, true, [])
Day3.p(puzzle_input, true, [])