Powered by AppSignal & Oban Pro

Day 3

day3.livemd

Day 3

Mix.install([:kino])

Read Input

file_input = Kino.Input.file("Please Select Input File")
file_info = Kino.Input.read(file_input)
file_path = Kino.Input.file_path(file_info.file_ref)
contents = File.read!(file_path)
parse_mul = fn instruction ->
  ~r/mul\((?<a>\d{1,3}),(?<b>\d{1,3})\)/
  |> Regex.named_captures(instruction)
  |> Map.values()
  |> Enum.map(&String.to_integer/1)
  |> List.to_tuple()
end

Part 1

instructions = ~r/mul\(\d{1,3},\d{1,3}\)/
  |> Regex.scan(contents)
  |> Enum.reject(&Enum.empty?/1)
  |> List.flatten()
  |> Enum.map(&(parse_mul.(&1)))
  |> Enum.reduce(0, fn({a, b}, sum) -> sum + (a * b) end)

Part 2

parse_instruction = fn 
  "do()"      -> :include
  "don't()"   -> :exclude
  instruction -> parse_mul.(instruction)
end

instructions = ~r/(mul\(\d{1,3},\d{1,3}\))|(do\(\))|(don't\(\))/
  |> Regex.scan(contents)
  |> Enum.map(&List.last/1)
  |> Enum.map(&(parse_instruction.(&1)))

result = instructions
  |> Enum.reduce({0, :include}, fn
    ({a, b}, {sum, :include}) -> {sum + (a * b), :include}
    (mode, {sum, _})          -> {sum, mode}
  end)
  |> elem(0)