aoc2022/day1.livemd
2022-12-09 17:12:53 +01:00

1.7 KiB

AOC 2022 - Day 1

Mix.install([
  {:req, "~> 0.3.3"}
])

Puzzle description

Day 1: Calorie Counting.

Input

defmodule Load do
  def input do
    aoc_session = System.fetch_env!("LB_AOC_SESSION")
    input_url = "https://adventofcode.com/2022/day/1/input"
    Req.get!(input_url, headers: [cookie: "session=#{aoc_session}"]).body
  end
end

Solution

defmodule Util do
  def create_chunk(val, acc) do
    if val == "" do
      {:cont, Enum.reverse(acc), []}
    else
      val = String.to_integer(val)
      {:cont, [val | acc]}
    end
  end

  def process_chunks([]), do: {:cont, []}
  def process_chunks(acc), do: {:cont, Enum.reverse(acc), []}

  def process(input) do
    input
    |> String.trim()
    |> String.split("\n")
    |> Enum.chunk_while([], &Util.create_chunk/2, &Util.process_chunks/1)
    |> Enum.map(&Enum.sum/1)
  end
end

defmodule Part1 do
  def run(input) do
    input
    |> Util.process()
    |> Enum.max()
  end
end

defmodule Part2 do
  def run(input) do
    input
    |> Util.process()
    |> Enum.sort(:desc)
    |> Enum.take(3)
    |> Enum.sum()
  end
end

ExUnit.start(autorun: false)

defmodule Test do
  use ExUnit.Case, async: true
  @example_input ~s(
1000
2000
3000

4000

5000
6000

7000
8000
9000

10000
)
  @input Load.input()

  test "it loads the input" do
    assert String.length(@input) > 0
  end

  test "part 1 example" do
    assert Part1.run(@example_input) === 24000
  end

  test "part 1" do
    assert Part1.run(@input) === 68442
  end

  test "part 2 example" do
    assert Part2.run(@example_input) === 45000
  end

  test "part 2" do
    assert Part2.run(@input) === 204_837
  end
end

ExUnit.run()