this repo has no description
at master 10 kB view raw
1<!-- livebook:{"persist_outputs":true} --> 2 3# Day 19 4 5```elixir 6Mix.install([ 7 {:kino_aoc, git: "https://github.com/ljgago/kino_aoc"} 8]) 9``` 10 11<!-- livebook:{"output":true} --> 12 13``` 14:ok 15``` 16 17## Section 18 19<!-- livebook:{"attrs":{"day":"19","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} --> 20 21```elixir 22{:ok, puzzle_input} = 23 KinoAOC.download_puzzle("2022", "19", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION")) 24``` 25 26<!-- livebook:{"output":true} --> 27 28``` 29{:ok, 30 "Blueprint 1: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 15 clay. Each geode robot costs 2 ore and 8 obsidian.\nBlueprint 2: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 17 clay. Each geode robot costs 3 ore and 10 obsidian.\nBlueprint 3: Each ore robot costs 2 ore. Each clay robot costs 2 ore. Each obsidian robot costs 2 ore and 20 clay. Each geode robot costs 2 ore and 14 obsidian.\nBlueprint 4: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 14 clay. Each geode robot costs 4 ore and 15 obsidian.\nBlueprint 5: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 13 clay. Each geode robot costs 3 ore and 15 obsidian.\nBlueprint 6: Each ore robot costs 2 ore. Each clay robot costs 2 ore. Each obsidian robot costs 2 ore and 15 clay. Each geode robot costs 2 ore and 7 obsidian.\nBlueprint 7: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 9 clay. Each geode robot costs 3 ore and 7 obsidian.\nBlueprint 8: Each ore robot costs 4 ore. Each clay robot costs 2 ore. Each obsidian robot costs 2 ore and 16 clay. Each geode robot costs 2 ore and 8 obsidian.\nBlueprint 9: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 20 clay. Each geode robot costs 4 ore and 18 obsidian.\nBlueprint 10: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 11 clay. Each geode robot costs 2 ore and 19 obsidian.\nBlueprint 11: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 7 clay. Each geode robot costs 3 ore and 10 obsidian.\nBlueprint 12: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 11 clay. Each geode robot costs 2 ore and 16 obsidian.\nBlueprint 13: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 16 clay. Each geode robot costs 3 ore and 15 obsidian.\nBlueprint 14: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 3 ore and 13 obsidian.\nBlueprint 15: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 13 clay. Each geode robot costs 2 ore and 20 obsidian.\nBlueprint 16: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 14 clay. Each geode robot costs 4 ore and 10 obsidian.\nBlueprint 17: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 17 clay. Each geode robot costs 3 ore and 16 obsidian.\nBlueprint 18: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 20 clay. Each geode robot costs 2 ore and 17 obsidian.\nBlueprint 19: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 16 clay. Each geode robot costs 4 ore and 12 obsidian.\nBlueprint 20: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 16 clay. Each geode robot costs 3 ore and 20 obsidian.\nBlueprint 21: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 4 ore and 12 obsidian.\nBlueprint 22: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 13 clay. Each geode robot costs 3 ore and 19 obsidian.\nBlueprint 23: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 3 ore and 8 obsidian.\nBlueprint 24: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 13 clay. Each geode robot costs 2 ore and 9 obsidian.\nBlueprint 25: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 5 clay. Each geode robot costs 3 ore and 15 obsidian.\nBlueprint 26: Each ore robot costs 4 ore. Each clay robot costs " <> ...} 31``` 32 33```elixir 34puzzle_input = """ 35Blueprint 1: Each ore robot costs 4 ore. Each clay robot costs 2 ore. Each obsidian robot costs 3 ore and 14 clay. Each geode robot costs 2 ore and 7 obsidian. 36Blueprint 2: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 8 clay. Each geode robot costs 3 ore and 12 obsidian. 37""" 38``` 39 40<!-- livebook:{"output":true} --> 41 42``` 43"Blueprint 1: Each ore robot costs 4 ore. Each clay robot costs 2 ore. Each obsidian robot costs 3 ore and 14 clay. Each geode robot costs 2 ore and 7 obsidian.\nBlueprint 2: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 8 clay. Each geode robot costs 3 ore and 12 obsidian.\n" 44``` 45 46```elixir 47regex = 48 ~r/ore robot.*(?<ore_ore>\d+) ore.*clay robot.*(?<clay_ore>\d+) ore.*obsidian robot.*(?<obsidian_ore>\d+) ore and (?<obsidian_clay>\d+) clay.*geode robot.*(?<geode_ore>\d+) ore and (?<geode_obsidian>\d+) obsidian/ 49 50plans = 51 puzzle_input 52 |> String.split("\n", trim: true) 53 |> Kino.render() 54 |> Enum.map(fn line -> 55 blueprint = 56 Regex.named_captures(regex, line) 57 |> Map.new(fn {k, v} -> 58 {String.to_atom(k), String.to_integer(v)} 59 end) 60 61 %{ 62 ore: %{ore: blueprint.ore_ore}, 63 clay: %{ore: blueprint.clay_ore}, 64 obsidian: %{ore: blueprint.obsidian_ore, clay: blueprint.obsidian_clay}, 65 geode: %{ore: blueprint.geode_ore, obsidian: blueprint.geode_obsidian}, 66 max: %{ 67 ore: 68 Enum.max([ 69 blueprint.ore_ore, 70 blueprint.clay_ore, 71 blueprint.obsidian_ore, 72 blueprint.geode_ore 73 ]), 74 clay: blueprint.obsidian_clay, 75 obsidian: blueprint.geode_obsidian 76 } 77 } 78 end) 79``` 80 81<!-- livebook:{"output":true} --> 82 83``` 84["Blueprint 1: Each ore robot costs 4 ore. Each clay robot costs 2 ore. Each obsidian robot costs 3 ore and 14 clay. Each geode robot costs 2 ore and 7 obsidian.", 85 "Blueprint 2: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 8 clay. Each geode robot costs 3 ore and 12 obsidian."] 86``` 87 88<!-- livebook:{"output":true} --> 89 90``` 91[ 92 %{ 93 clay: %{ore: 2}, 94 geode: %{obsidian: 7, ore: 2}, 95 max: %{clay: 14, obsidian: 7, ore: 4}, 96 obsidian: %{clay: 14, ore: 3}, 97 ore: %{ore: 4} 98 }, 99 %{ 100 clay: %{ore: 3}, 101 geode: %{obsidian: 12, ore: 3}, 102 max: %{clay: 8, obsidian: 12, ore: 3}, 103 obsidian: %{clay: 8, ore: 3}, 104 ore: %{ore: 2} 105 } 106] 107``` 108 109```elixir 110defmodule Blueprint do 111 def produce(plan, time, machines) do 112 produce(plan, time, machines, %{ore: 0, clay: 0, obsidian: 0, geode: 0}) 113 end 114 115 def produce(_plan, 0, machines, stash) do 116 %{machines: machines, stash: stash} 117 end 118 119 def produce(plan, time_left, machines, stash) do 120 do_shopping(plan, stash) 121 |> Enum.filter(fn {k, _} -> (machines[k] || 0) < plan.max[k] end) 122 |> Enum.flat_map(fn {machine, new_stash} -> 123 # if machine in [:obsidian, :geode], do: IO.inspect(new_stash) 124 [ 125 produce( 126 plan, 127 time_left - 1, 128 add_machine(machine, machines), 129 update_stash(machines, new_stash) 130 ) 131 ] 132 end) 133 # |> tap(fn list -> 134 # Enum.filter(list, & &1.obsidian > 0) 135 # |> Enum.map(&IO.inspect/1) 136 # end) 137 |> Enum.max_by(& &1.stash.geode) 138 end 139 140 defp add_machine(nil, machines), do: machines 141 defp add_machine(name, machines), do: Map.update(machines, name, 1, &(&1 + 1)) 142 143 defp update_stash(machines, stash) do 144 Enum.reduce(machines, stash, fn {k, v}, acc -> 145 Map.update(acc, k, v, &(&1 + v)) 146 end) 147 end 148 149 def do_shopping(plan, stash) 150 when stash.ore >= plan.geode.ore and stash.obsidian >= plan.geode.obsidian, 151 do: [{:geode, buy(plan.geode, stash)}] 152 153 def do_shopping(plan, stash) 154 when stash.ore >= plan.obsidian.ore and stash.clay >= plan.obsidian.clay, 155 do: [{:obsidian, buy(plan.obsidian, stash)}, {nil, stash}] 156 157 def do_shopping(plan, stash) do 158 [ 159 {nil, stash} 160 | Enum.flat_map([:ore, :clay], fn k -> 161 if stash.ore >= plan[k].ore do 162 [{k, %{stash | ore: stash.ore - plan[k].ore}}] 163 else 164 [] 165 end 166 end) 167 ] 168 end 169 170 defp buy(price, stash) do 171 Map.merge(stash, price, fn _k, v1, v2 -> v1 - v2 end) 172 end 173end 174``` 175 176<!-- livebook:{"output":true} --> 177 178``` 179{:module, Blueprint, <<70, 79, 82, 49, 0, 0, 22, ...>>, {:buy, 2}} 180``` 181 182```elixir 183plan = hd(plans) |> Kino.inspect() 184stash = %{clay: 35, geode: 0, obsidian: 0, ore: 4} 185 186Blueprint.do_shopping(plan, stash) 187``` 188 189<!-- livebook:{"output":true} --> 190 191``` 192%{ 193 clay: %{ore: 2}, 194 geode: %{obsidian: 7, ore: 2}, 195 max: %{clay: 14, obsidian: 7, ore: 4}, 196 obsidian: %{clay: 14, ore: 3}, 197 ore: %{ore: 4} 198} 199``` 200 201<!-- livebook:{"output":true} --> 202 203``` 204[ 205 obsidian: %{clay: 21, geode: 0, obsidian: 0, ore: 1}, 206 nil: %{clay: 35, geode: 0, obsidian: 0, ore: 4} 207] 208``` 209 210```elixir 211plans 212# |> Enum.drop(1) 213|> Enum.take(1) 214|> Kino.inspect() 215|> Enum.map(fn plan -> Blueprint.produce(plan, 24, %{ore: 1}) end) 216``` 217 218<!-- livebook:{"output":true} --> 219 220``` 221[ 222 %{ 223 clay: %{ore: 2}, 224 geode: %{obsidian: 7, ore: 2}, 225 max: %{clay: 14, obsidian: 7, ore: 4}, 226 obsidian: %{clay: 14, ore: 3}, 227 ore: %{ore: 4} 228 } 229] 230```