Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

--- Day 5: Print Queue ---

2024/day_5.livemd

— Day 5: Print Queue —

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

Setup

{:ok, puzzle_input} =
  KinoAOC.download_puzzle("2024", "5", System.fetch_env!("LB_AOC_SESSION_COOKIE"))
test_input = Kino.Input.textarea("test_input")
defmodule PrintQueue do
  def parse(input) do
    input
    |> String.split("\n\n")
    |> Enum.map(&String.split(&1, "\n"))
  end

  def rule_set(rules) do
    Enum.reduce(rules, %{}, fn rule, acc ->
      [before_page, after_page] = String.split(rule, "|")

      Map.update(acc, before_page, MapSet.new([after_page]), fn set ->
        MapSet.put(set, after_page)
      end)
    end)
  end

  def valid_update?(update, rule_set) do
    Enum.reduce_while(update, MapSet.new(), fn page, acc ->
      if rule_set |> Map.get(page, MapSet.new()) |> MapSet.disjoint?(acc) do
        {:cont, MapSet.put(acc, page)}
      else
        {:halt, false}
      end
    end)
  end

  # def fix_update(update, rule_set) do
    
  # end
end

Part 1

import PrintQueue

# test_input = Kino.Input.read(test_input)

[rules, updates] = parse(puzzle_input)
rule_set = rule_set(rules)

updates
|> Enum.map(&String.split(&1, ","))
|> Enum.filter(fn update -> valid_update?(update, rule_set) end)
|> Enum.map(fn pages ->
  pages
  |> Enum.at(pages |> length() |> div(2))
  |> String.to_integer()
end)
|> Enum.sum()

Part 2

test_input = Kino.Input.read(test_input)

[rules, updates] = parse(test_input)
rule_set = rule_set(rules)

all_pages = Enum.map(updates, &String.split(&1, ","))
valid_pages = Enum.filter(all_pages, fn update -> valid_update?(update, rule_set) end)
invalid_pages = all_pages -- valid_pages

fix_update = fn update, _rule_set ->
  # pages =
  for {page, i} <- Enum.with_index(update), reduce: %{} do
    acc -> Map.put(acc, i, page)
  end
end

# idk
fix_update.(["97", "13", "75", "29", "47"], rule_set)