Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Advent of Code 2024 - Day 3

2024/03.livemd

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(&amp;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, [])