this repo has no description
at master 4.8 kB view raw
1<!-- vim:ft=markdown --> 2 3<!-- livebook:{"persist_outputs":true} --> 4 5# Day 22 6 7## Input 8 9```elixir 10input = 11 File.stream!("day22.txt") 12 |> Stream.map(&String.trim/1) 13 |> Stream.map(&String.split(&1, [" "])) 14 |> Enum.map(fn [action, rest] -> 15 {_, bindings} = 16 rest 17 |> String.replace(",", ";") 18 |> Code.eval_string() 19 20 {String.to_atom(action), Map.new(bindings)} 21 end) 22``` 23 24<!-- livebook:{"output":true} --> 25 26``` 27[ 28 on: %{x: -40..7, y: -3..49, z: -48..6}, 29 on: %{x: -38..10, y: -11..37, z: -30..19}, 30 on: %{x: -43..1, y: -16..30, z: -38..13}, 31 on: %{x: -10..44, y: -8..46, z: -41..4}, 32 on: %{x: -27..19, y: -2..45, z: -33..12}, 33 on: %{x: -41..4, y: -18..32, z: -34..19}, 34 on: %{x: -43..9, y: -20..27, z: -34..20}, 35 on: %{x: -47..-2, y: -5..49, z: -20..32}, 36 on: %{x: -20..33, y: -40..6, z: -16..33}, 37 on: %{x: -25..24, y: -47..-2, z: -46..6}, 38 off: %{x: -28..-9, y: -6..4, z: 22..37}, 39 on: %{x: -34..14, y: -16..32, z: -43..3}, 40 off: %{x: -36..-18, y: -44..-33, z: 5..16}, 41 on: %{x: -23..22, y: -34..11, z: -38..12}, 42 off: %{x: -24..-15, y: 26..39, z: -18..-9}, 43 on: %{x: -23..22, y: -31..20, z: -38..13}, 44 off: %{x: -16..-6, y: 7..19, z: -44..-30}, 45 on: %{x: -8..45, y: -18..28, z: -27..18}, 46 off: %{x: -24..-8, y: -3..7, z: 33..45}, 47 on: %{x: -28..18, y: -15..39, z: -18..35}, 48 on: %{x: 52706..68579, y: -51721..-24984, z: -29134..-4745}, 49 on: %{x: 19158..43390, y: 48482..62915, z: 36278..51760}, 50 on: %{x: 33529..54535, y: 41410..44729, z: 35536..62066}, 51 on: %{x: 39279..54831, y: -54196..-35294, z: -46321..-19146}, 52 on: %{x: -49951..-33034, y: -75783..-65241, z: -32974..-9141}, 53 on: %{x: 16267..33862, y: 32962..38520, z: 55102..80003}, 54 on: %{x: 28231..33305, y: -13203..11551, z: -82121..-71765}, 55 on: %{x: -3880..15012, y: -97354..-71276, z: -32509..-10704}, 56 on: %{x: -59644..-43923, y: -56932..-39976, z: -46680..-24924}, 57 on: %{x: -22171..6559, y: 59909..65127, z: 51012..71854}, 58 on: %{x: -35278..-11377, y: -90913..-54535, z: 15441..29860}, 59 on: %{x: 42440..47504, y: -77130..-54916, z: -5117..22780}, 60 on: %{x: -23382..-925, y: -96268..-67199, z: -1408..16864}, 61 on: %{x: 46073..66555, y: 2178..6843, z: -72379..-46993}, 62 on: %{x: -7367..16256, y: 27822..35444, z: -81222..-57262}, 63 on: %{x: 70121..85076, y: -2405..20765, z: -25162..-6383}, 64 on: %{x: -38188..-8731, y: 303..24311, z: -85237..-74901}, 65 on: %{x: 9308..35679, y: 72560..89334, z: -12862..6802}, 66 on: %{x: 19088..20550, y: -54261..-29941, z: -66813..-56094}, 67 on: %{x: 58563..67361, y: 32116..50251, z: -40547..-22471}, 68 on: %{x: 63946..72885, y: -45525..-32975, z: 6297..33150}, 69 on: %{x: 35523..45582, y: -46123..-39187, z: -62601..-55854}, 70 on: %{x: -45263..-16076, y: 66141..71305, z: 24152..51511}, 71 on: %{x: -56833..-39277, y: -61785..-39127, z: 20400..30866}, 72 on: %{x: -64099..-47168, y: -14802..-10218, z: 59578..78286}, 73 on: %{x: 54485..79540, y: -9884..13564, z: -33614..-29502}, 74 on: %{x: -56136..-41543, y: 40175..50868, z: 18766..46233}, 75 on: %{x: -29888..-22443, y: 56778..79471, ...}, 76 on: %{x: 57940..83198, ...}, 77 on: %{...}, 78 ... 79] 80``` 81 82## Implementation 83 84```elixir 85defmodule Day22 do 86 def volume(%{x: x, y: y, z: z}), 87 do: Range.size(x) * Range.size(y) * Range.size(z) 88 89 def volume(list), do: list |> Enum.map(&volume/1) |> Enum.sum() 90 91 def apply({action, new}, cuboids) do 92 cuboids = Enum.flat_map(cuboids, fn old -> sub(old, new) end) 93 94 case action do 95 :on -> [new | cuboids] 96 :off -> cuboids 97 end 98 end 99 100 defp sub(%{x: ax, y: ay, z: az} = a, %{x: bx, y: by, z: bz} = b) do 101 if overlap?(a, b) do 102 rx = split(ax, bx) 103 ry = split(ay, by) 104 rz = split(az, bz) 105 106 for x <- rx, 107 y <- ry, 108 z <- rz, 109 cube = cube(x, y, z), 110 overlap?(cube, a), 111 not overlap?(cube, b), 112 do: cube 113 else 114 [a] 115 end 116 end 117 118 defp overlap?(%{x: ax, y: ay, z: az}, %{x: bx, y: by, z: bz}) do 119 not (Range.disjoint?(ax, bx) or 120 Range.disjoint?(ay, by) or 121 Range.disjoint?(az, bz)) 122 end 123 124 defp cube(x, y, z), do: %{x: x, y: y, z: z} 125 126 # `b` is "whithin" `a` 127 defp split(a1..a2, b1..b2) do 128 [ 129 a1..(b1 - 1)//1, 130 max(a1, b1)..min(a2, b2)//1, 131 (min(a2, b2) + 1)..a2//1 132 ] 133 |> Enum.reject(&(Range.size(&1) == 0)) 134 end 135end 136``` 137 138<!-- livebook:{"output":true} --> 139 140``` 141{:module, Day22, <<70, 79, 82, 49, 0, 0, 18, ...>>, {:split, 2}} 142``` 143 144## Task 1 145 146```elixir 147range = -50..50 148 149input 150|> Enum.reject(fn {_, v} -> 151 Enum.any?(Map.values(v), &Range.disjoint?(&1, range)) 152end) 153|> Enum.reduce([], &Day22.apply/2) 154|> Day22.volume() 155``` 156 157<!-- livebook:{"output":true} --> 158 159``` 160556501 161``` 162 163## Task 2 164 165```elixir 166input 167|> Enum.reduce([], &Day22.apply/2) 168|> Day22.volume() 169``` 170 171<!-- livebook:{"output":true} --> 172 173``` 1741217140271559773 175```