From 32055baff47d87ca5d1653405692f1d1c1ef73bb Mon Sep 17 00:00:00 2001 From: Caleb Webber Date: Sun, 1 Dec 2024 21:09:25 -0500 Subject: [PATCH] add 2022 day 11 --- elixir/livebook/2022/aoc_day_11.livemd | 113 +++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 elixir/livebook/2022/aoc_day_11.livemd diff --git a/elixir/livebook/2022/aoc_day_11.livemd b/elixir/livebook/2022/aoc_day_11.livemd new file mode 100644 index 0000000..c71cea9 --- /dev/null +++ b/elixir/livebook/2022/aoc_day_11.livemd @@ -0,0 +1,113 @@ +# Year 2022 Day11 + +## Section + +```elixir +parse_op = fn + "Operation: new = " <> z, f, s -> f.(z, f, s) + "old " <> z, f, s -> f.(z, f, [:old | s]) + "old" <> z, f, s -> f.(z, f, [:old | s]) + "+ " <> z, f, s -> f.(z, f, [:plus | s]) + "- " <> z, f, s -> f.(z, f, [:minus | s]) + "* " <> z, f, s -> f.(z, f, [:mul | s]) + "/ " <> z, f, s -> f.(z, f, [:div | s]) + "", _, s -> s |> Enum.reverse() + n, f, s -> + [a | b] = String.split( n, " ") + a = String.trim(a) |> String.to_integer() + f.(b |> Enum.join(" "), f, [a | s]) +end +``` + +```elixir +subs = fn b, a -> if b == :old, do: a, else: b end +``` + +```elixir +resolve_stack = fn + old, [a, :plus, b] -> subs.(a, old) + subs.(b, old) + old, [a, :minus, b] -> subs.(a, old) - subs.(b, old) + old, [a, :mul, b] -> subs.(a, old) * subs.(b, old) + old, [a, :div, b] -> subs.(a, old) / subs.(b, old) +end +``` + +```elixir +defmodule Monkey do + defstruct id: nil, items: nil, op: nil, mod: nil, if_true: nil, if_false: nil, inspections: 0 +end +``` + +```elixir +defmodule MonkeyMachine do + + def load(instructions) do + + {barrel, _} = for instruction <- instructions, reduce: {%{}, nil} do + {barrel, monkey} -> + (fn + {:break} -> + {barrel |> Map.put(monkey.id, monkey), nil} + {:add_monkey, id} -> {barrel, %Monkey{id: id}} + {:starting_items, i} -> {barrel, %{monkey | items: i }} + {a, o} -> {barrel, %{monkey | a => o }} + end).(instruction) + end + + barrel + end + + def run(barrel) do + run(barrel, 0, (Map.keys(barrel) |> Enum.count()) - 1) # Map.values(barrel) |> Stream.map(&(&1.mod)) |> Enum.product()) + end + + defp run(barrel, i, n) when i > n do + barrel + end + + defp run(barrel, id, n) do + monkey = Map.get(barrel, id) + barrel = for item <- monkey.items, reduce: barrel do + b -> + + r = div(monkey.op.(item), 3) + dest = if rem(r, monkey.mod) == 0, do: monkey.if_true, else: monkey.if_false + + b + |> Map.update!(dest, fn d -> %{d | items: [r | d.items]} end) + |> Map.update!(id, fn m -> Map.update!(m, :inspections, &(&1 + 1)) end) + end |> Map.update!(id, fn m -> %{m | items: []} end) + + run(barrel, id + 1, n) + end +end +``` + +```elixir +barrel = input +|> String.split("\n") +|> Stream.map(&String.trim/1) +|> Enum.map( + fn + "Monkey " <> z -> {:add_monkey, z |> String.split(":") |> Enum.at(0) |> String.to_integer()} + "Starting items: " <> i -> {:starting_items, i |> String.split(",", trim: true) |> Enum.map(&String.to_integer(String.trim(&1)))} + "Operation: " <> _ = u -> {:op, fn o -> resolve_stack.(o, parse_op.(u, parse_op, [])) end} + "Test: divisible by " <> n -> {:mod, String.to_integer(n)} + "If true: throw to monkey " <> n -> {:if_true, String.to_integer(n)} + "If false: throw to monkey " <> n -> {:if_false, String.to_integer(n)} + "" -> {:break} + u -> u + end +) +|> MonkeyMachine.load() + +for _ <- 1..20, reduce: barrel do + b -> + MonkeyMachine.run(b) +end +|> Map.values() +|> Stream.map(&(&1.inspections)) +|> Enum.sort(:desc) +|> Enum.take(2) +|> Enum.product() +```