Powered by AppSignal & Oban Pro

AOC 2022 - Day 01

aoc2022/day01.livemd

AOC 2022 - Day 01

Mix.install([
  {:kino_aoc, "~> 0.1"}
])

AOC Helper

{:ok, puzzle_input} =
  KinoAOC.download_puzzle("2022", "1", System.fetch_env!("LB_AOC_SESSION"))

Part 1

Code

defmodule PartOne do
  def solve(input) do
    IO.puts("--- Part One ---")
    IO.puts("Result: #{run(input)}")
  end

  def run(input) do
    input
    |> String.split("\n")
    |> Enum.reduce({0, 0}, fn line, {leader, count} ->
      with {value, _} <- Integer.parse(line) do
        {leader, count + value}
      else
        :error -> if count > leader, do: {count, 0}, else: {leader, 0}
      end
    end)
    |> elem(0)
  end
end

Test

ExUnit.start(autorun: false)

defmodule PartOneTest do
  use ExUnit.Case, async: true
  import PartOne

  @input """
  1000
  2000
  3000

  4000

  5000
  6000

  7000
  8000
  9000

  10000
  """
  @expected 24000

  test "part one" do
    actual = run(@input)
    assert actual == @expected
  end
end

ExUnit.run()

Solution

PartOne.solve(puzzle_input)

Part 2

Code

defmodule PartTwo do
  def solve(input) do
    IO.puts("--- Part Two ---")
    IO.puts("Result: #{run(input)}")
  end

  def run(input) do
    input
    |> String.split("\n")
    |> Enum.reduce({[0, 0, 0], 0}, fn line, {leaders, count} ->
      with :error <- Integer.parse(line) do
        if count > Enum.at(leaders, -1) do
          {leaders |> List.replace_at(-1, count) |> Enum.sort() |> Enum.reverse(), 0}
        else
          {leaders, 0}
        end
      else
        {value, _} -> {leaders, count + value}
      end
    end)
    |> elem(0)
    |> Enum.sum()
  end
end

Test

ExUnit.start(autorun: false)

defmodule PartTwoTest do
  use ExUnit.Case, async: true
  import PartTwo

  @input """
  1000
  2000
  3000

  4000

  5000
  6000

  7000
  8000
  9000

  10000
  """
  @expected 45000

  test "part two" do
    actual = run(@input)
    assert actual == @expected
  end
end

ExUnit.run()

Solution

PartTwo.solve(puzzle_input)