advent-of-code/2022/elixir-livebook.livemd

1.9 KiB

Advent of Code 2022

defmodule AoC do
  def input_file_contents(n), do: File.read!(Path.expand("/aoc-input/#{n}.input"))
end

import Enum
Enum

Day 1

calories =
  AoC.input_file_contents(1)
  |> String.split("\n")
  |> reduce([0], fn
    "", l -> [0 | l]
    s, [n | l] -> [n + String.to_integer(s) | l]
  end)
  |> sort()
  |> reverse()

IO.puts("Part 1: #{hd(calories)}")
IO.puts("Part 2: #{Enum.take(calories, 3) |> Enum.sum()}")
Part 1: 71924
Part 2: 210406
:ok

Day 2

m = %{
  0 => %{0 => 4, 1 => 8, 2 => 3},
  1 => %{0 => 1, 1 => 5, 2 => 9},
  2 => %{0 => 7, 1 => 2, 2 => 6}
}

points = fn
  <<a, _, b, 0x0A, rest::binary>>, {p1, p2}, r ->
    {y, x} = {a - 65, b - 88}
    r.(rest, {p1 + m[y][x], p2 + m[y][rem(3 + x + y - 1, 3)]}, r)

  _, {p1, p2}, _ ->
    {p1, p2}
end

{p1, p2} =
  2
  |> AoC.input_file_contents()
  |> points.({0, 0}, points)

IO.puts("Part 1: #{p1}")
IO.puts("Part 2: #{p2}")
Part 1: 12535
Part 2: 15457
:ok

Day 3

priority = fn
  n when n >= 97 and n <= 122 -> n - 96
  n -> n - 38
end

lines =
  3
  |> AoC.input_file_contents()
  |> String.split("\n", trim: true)

lines
|> map(fn s ->
  <<a::binary-size(div(byte_size(s), 2)), b::binary>> = s

  MapSet.new(to_charlist(a))
  |> MapSet.intersection(MapSet.new(to_charlist(b)))
  |> MapSet.to_list()
  |> hd()
  |> priority.()
end)
|> sum()
|> IO.inspect()

lines
|> chunk_every(3)
|> map(fn t ->
  map(t, &(to_charlist(&1) |> MapSet.new()))
  |> reduce(&MapSet.intersection/2)
  |> MapSet.to_list()
  |> hd()
  |> priority.()
end)
|> sum()
|> IO.inspect()
7597
2607
2607