Powered by AppSignal & Oban Pro

--- Day 7: Laboratories ---

2025/day_7.livemd

— Day 7: Laboratories —

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

Setup

{:ok, puzzle_input} =
  KinoAOC.download_puzzle("2025", "7", System.fetch_env!("LB_AOC_SESSION_COOKIE"))
test_input = Kino.Input.textarea("test_input")
test_input = Kino.Input.read(test_input)
defmodule Laboratories do
  def parse_manifold(input) do
    String.split(input)
  end
end

Part 1

import Laboratories
[first_row | rows] = parse_manifold(puzzle_input)
[{starting_index, _}] = Regex.run(~r(S), first_row, return: :index)

rows
|> Enum.map(fn row ->
  ~r/\^/
  |> Regex.scan(row, return: :index)
  |> Enum.map(fn [{index, _}] -> index end)
  |> MapSet.new()
end)
|> Enum.reject(&(MapSet.size(&1) == 0))
|> Enum.reduce({MapSet.new([starting_index]), 0}, fn next_splitter_row, {beam_paths, splits} ->
  beam_collisions = MapSet.intersection(beam_paths, next_splitter_row)
  new_splitter_paths = beam_collisions |> Enum.flat_map(&[&1 - 1, &1 + 1]) |> MapSet.new()

  new_beam_paths =
    beam_paths |> MapSet.difference(next_splitter_row) |> MapSet.union(new_splitter_paths)

  {new_beam_paths, splits + MapSet.size(beam_collisions)}
end)
|> elem(1)

Part 2