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

Day 03

2024/day_03.livemd

Day 03

Mix.install([:kino_aoc])

Kino.configure(inspect: [charlists: :as_lists])

Input

{:ok, puzzle_input} =
  KinoAOC.download_puzzle("2024", "3", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))

Part 1

# Regex version
Regex.scan(~r/mul\((\d+),(\d+)\)/, puzzle_input)
|> Enum.reduce(0, fn [_capture, l, r], acc -> 
    acc + String.to_integer(l) * String.to_integer(r)
  end)
# Pattern matching version
defmodule Part1 do
  def parse("", _state, parsed), do: parsed
  def parse("mul(" <> rest, _state, parsed), do: parse(rest, :left_arg, [{"", ""} | parsed])
  def parse(")" <> rest, :right_arg, parsed), do: parse(rest, :nil, parsed)
  def parse("," <> rest, :left_arg, parsed), do: parse(rest, :right_arg, parsed)
  def parse(<>, state, [{l, r} | tail] = parsed) when x in ?0..?9 do
    case state do
      :left_arg -> parse(rest, :left_arg, [{l <> <>, r} | tail])
      :right_arg -> parse(rest, :right_arg, [{l, r <> <>} | tail])
      _ -> parse(rest, state, parsed)
    end
  end
  def parse(<<_x, rest::binary>>, :left_arg, [_head | tail]), do: parse(rest, nil, tail)
  def parse(<<_x, rest::binary>>, :right_arg, [_head | tail]), do: parse(rest, nil, tail)
  def parse(<<_x, rest::binary>>, state, parsed), do: parse(rest, state, parsed)
end

Part1.parse(puzzle_input, nil, [])
|> Enum.reduce(0, fn {l, r}, acc -> acc + String.to_integer(l) * String.to_integer(r) end)

Part 2

Regex.scan(~r/mul\((\d+),(\d+)\)|do\(\)|don't\(\)/, puzzle_input)
|> Enum.reduce({true, 0}, fn 
  ["do()"], {_status, acc} -> {true, acc}
  ["don't()"], {_status, acc} -> {false, acc}
  [_capture, l, r], {true, acc} -> {true, acc + String.to_integer(l) * String.to_integer(r)}
  _, {false, acc} -> {false, acc}
  end)
|> elem(1)