Advent of Code 2023 - Day 15

Greetings, coding virtuosos! Ukrainian Erlanger here :metal:, and it’s a fantastic Friday. Today unfolds as Day 15 in our epic adventure through Advent of Code, introducing a new puzzle for your coding prowess. Embrace the challenge, unravel the mystery, and share your brilliant solutions in the comments below. Let’s cap off the week with a coding crescendo and turn this Friday into a day of triumph! Happy coding, folks! :blush:

4 Likes

Easy day today, probably means that tomorrow going to be very hard :slight_smile:

defmodule Aoc.Fifteen do
  def parse(string) do
    string
    |> String.split(",", trim: true)
  end

  def part_one(input) do
    input
    |> Enum.map(&hash/1)
    |> Enum.sum()
  end

  def part_two(input) do
    input
    |> Enum.map(&String.split(&1, ["=", "-"], trim: true))
    |> Enum.reduce(%{}, &reduce/2)
    |> Enum.map(&power/1)
    |> Enum.sum()
  end

  defp power({k, kv}) do
    for {{_, f}, i} <- Enum.with_index(kv, 1) do
      (k + 1) * i * String.to_integer(f)
    end
    |> Enum.sum()
  end

  defp reduce([k], acc) do
    acc
    |> Map.update(hash(k), [], &List.keydelete(&1, k, 0))
  end

  defp reduce([k, v], acc) do
    acc
    |> Map.update(hash(k), [{k, v}], fn kv ->
      if List.keymember?(kv, k, 0) do
        List.keyreplace(kv, k, 0, {k, v})
      else
        kv ++ [{k, v}]
      end
    end)
  end

  defp hash(string) do
    string
    |> String.to_charlist()
    |> Enum.reduce(0, fn char, acc -> rem((acc + char) * 17, 256) end)
  end
end

input = File.read!("priv/15.txt") |> Aoc.Fifteen.parse()

input |> Aoc.Fifteen.part_one() |> IO.inspect(label: "part 1")
input |> Aoc.Fifteen.part_two() |> IO.inspect(label: "part 2")
2 Likes
2 Likes