aoc2022/day3.livemd
2022-12-11 23:02:36 +01:00

2.8 KiB

AOC 2022 - Day 3

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

Puzzle description

Day 3: Rucksack Reorganization.

Input

defmodule Load do
  def input do
    aoc_session = System.fetch_env!("LB_AOC_SESSION")
    input_url = "https://adventofcode.com/2022/day/3/input"
    Req.get!(input_url, headers: [cookie: "session=#{aoc_session}"]).body
  end
end
defmodule A do
  def intersection(str1, str2) do
    str1_set = MapSet.new(String.graphemes(str1))
    str2_set = MapSet.new(String.graphemes(str2))
    MapSet.intersection(str1_set, str2_set)
  end
end

A.intersection("hello", "world")

Solution

defmodule Util do
  @items String.split("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", "", trim: true)

  def value_of(item) do
    Enum.find_index(@items, fn c -> c == item end) + 1
  end

  def process(input) do
    input
    |> String.trim()
    |> String.split("\n", trim: true)
  end

  def intersection(str1, str2) do
    str1_set = MapSet.new(String.graphemes(str1))
    str2_set = MapSet.new(String.graphemes(str2))
    MapSet.intersection(str1_set, str2_set)
  end

  def intersection(str1, str2, str3) do
    str1_set = MapSet.new(String.graphemes(str1))
    str2_set = MapSet.new(String.graphemes(str2))
    str3_set = MapSet.new(String.graphemes(str3))
    intersection = MapSet.intersection(str1_set, str2_set)
    MapSet.intersection(intersection, str3_set)
  end
end
defmodule Part1 do
  def run(input) do
    input
    |> Util.process()
    |> Enum.map(&String.split_at(&1, div(String.length(&1), 2)))
    |> Enum.reduce(0, fn {first, second}, acc ->
      priority =
        Util.intersection(first, second)
        |> MapSet.to_list()
        |> List.first()
        |> Util.value_of()

      acc + priority
    end)
  end
end

defmodule Part2 do
  def run(input) do
    input
    |> Util.process()
    |> Enum.chunk_every(3)
    |> Enum.map(fn [items1, items2, items3] ->
      Util.intersection(items1, items2, items3)
      |> MapSet.to_list()
      |> List.first()
      |> Util.value_of()
    end)
    |> Enum.reduce(&+/2)
  end
end

ExUnit.start(autorun: false)

defmodule Test do
  use ExUnit.Case, async: true
  @example_input ~s(vJrwpWtwJgWrhcsFMMfFFhFp
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
PmmdzqPrVvPwwTWBwg
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
ttgJtRGJQctTZtZT
CrZsJsPPZsGzwwsLwLmpwMDw)
  @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) === 157
  end

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

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

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

ExUnit.run()