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

AoC 2024/03

aoc-2024-03.livemd

AoC 2024/03

Mix.install([
  {:kino, "~> 0.14.2"}
])

Section

input = Kino.Input.textarea("input")
defmodule Day3 do
  defp parse_input(input) do
    input
  end

  def solve1(input) do
    parse_input(input)
    |> get_matches1()
    |> Enum.map(fn [match] -> 
      get_params(match)
    end)
    |> calc_sum_of_products1()
  end

  defp get_matches1(input) do
    Regex.scan(~r/mul\([0-9]+,[0-9]+\)/, input)
  end

  defp get_params(match) do
    [params_str] = Regex.run(~r/[0-9]+,[0-9]+/, match)
    [x,y] = String.split(params_str, ",")
    {String.to_integer(x), String.to_integer(y)}
  end

  defp calc_sum_of_products1(params) do
    Enum.reduce(params, 0, fn {x,y}, acc -> 
      acc + x * y
    end)
  end
  
  def solve2(input) do
    input
    |> parse_input()
    |> get_matches2()
    |> Enum.map(fn [match] -> 
      get_commands_params(match)
    end)
    |> calc_sum_of_products2()
  end

  defp get_matches2(input) do
    Regex.scan(~r/mul\([0-9]+,[0-9]+\)|do\(\)|don't\(\)/, input)
  end

  defp get_commands_params(match) do
    cond do
      match == "don't()" -> :mul_disabled
      match == "do()" -> :mul_enabled
      String.starts_with?(match, "mul(") -> get_params(match)
    end
  end

  defp calc_sum_of_products2(params) do
    Enum.reduce(params, {0, :mul_enabled}, fn command, {acc_sum, acc_mul_state} -> 
      case command do
        :mul_enabled -> {acc_sum, :mul_enabled}
        :mul_disabled -> {acc_sum, :mul_disabled}
        _ -> {x,y} = command
          if acc_mul_state == :mul_disabled, do:
            {acc_sum, acc_mul_state}, else:
            {acc_sum + x * y, acc_mul_state}
      end
    end)
    |> elem(0)
  end
end
{:module, Day3, <<70, 79, 82, 49, 0, 0, 18, ...>>, {:calc_sum_of_products2, 1}}

solve1

Kino.Input.read(input)
|> Day3.solve1()
161289189
matches = Regex.scan(~r/mul\([0-9]+,[0-9]+\)/, "xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))")
[["mul(2,4)"], ["mul(5,5)"], ["mul(11,8)"], ["mul(8,5)"]]
params = Regex.run(~r/[0-9]+,[0-9]+/, "mul(2,4)")
["2,4"]

solve2

Kino.Input.read(input)
|> Day3.solve2()
83595109
Regex.scan(~r/mul\([0-9]+,[0-9]+\)|do\(\)|don't\(\)/, "xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))")
[["mul(2,4)"], ["don't()"], ["mul(5,5)"], ["mul(11,8)"], ["do()"], ["mul(8,5)"]]