this repo has no description

2024 day 12

Changed files
+811
2024
+811
2024/day12.livemd
··· 1 + <!-- livebook:{"persist_outputs":true} --> 2 + 3 + # Day 12 4 + 5 + ```elixir 6 + Mix.install([:kino_aoc, :range_set]) 7 + ``` 8 + 9 + ## Section 10 + 11 + <!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIxMiIsInNlc3Npb25fc2VjcmV0IjoiQURWRU5UX09GX0NPREVfU0VTU0lPTiIsInllYXIiOiIyMDI0In0","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} --> 12 + 13 + ```elixir 14 + {:ok, puzzle_input} = 15 + KinoAOC.download_puzzle("2024", "12", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION")) 16 + ``` 17 + 18 + <!-- livebook:{"output":true} --> 19 + 20 + ``` 21 + {:ok, 22 + "KKKKKKZZZZZZZZDDQQQQXXXXXXXXXXXXTTTTTTTTTTTTDHHHHHHHHHHHHHHHHHGGGGGGPPPGUUGGXXGGGGGGJJJJJJJJJIIIIIIIIIIIIIIIIIIIIDIIIIIIIIIIIKIIIIIIIIIIIIIM\nKKKKKKZZZZZZZDDDQQQQXXCXXXXXXXXXTTTTTTTTTTTTTHHHHHHHHHHHHHHHHHGGGGGGGGPGUUGGGGGGGGGJJJJJJJJIIIIIIIIIIIIIIIIIIVVVIDDIIIIIIIKKKKIIIIIIIIIIIIMM\nKKKKKZZZZZZZZZZQQQQQQXCCCXXXXXXTTTTTTTTTTTTTTTHHHHHHHHHHHHHHHGGGGGGGGGGGGGGGGGGGGJJJJJJJJJJIIIIIIIIIIIIIIIIIIVIIIIDIHIIIIIIIKKIIIIIIIIIIIIMM\nKKKKKZZZZZZZZEEHQQQYQQZCCCCXXXTTTTTTTTTTTTTTHHHIIIIHHHHHHHHHHGGGGGGGGGGGGGGGGGGGGGJJJJJJJJIIIIIIIIKKKKKKIIIIIVIIIIDHHIIIIIIIIKIIIIIIIIIIIIIM\nKKKKKKOOEZEEEEHHQQQYYCCCCCCTTTTTTTTTTTTTTTTTVVVIIIIHHHHHHBBBBGGGGGGGGGGGGGGGGGGGGJJJJJJJJJIIIIIIIBCKKKKKIIIIIIIIHHHHHIIIIIIIIIIIIIIIIIIIMMMM\nKKKKKOOEEEEEEEHHHQQYYCCCCCCCCCTTTTTTTTTTTOOTTIIIIIHHHHHHHHHBBBGGGGGGGGGGGGGGGGGGGJJJJJJJJJIIIIIBBBCKKKKKKKIIIIIHHHHHIIIIIIIIIIIIIIIIIIIIIIMM\nKKKKKKOGGEEEGHHHHQDDYYCCCCCCCOOTTTTTTTTTTTIDIIIIIIIHHHHHHBBBBBGGGGGGGGGGGGGGGGGGGGJJJJJJJJIIIIBBBBKKKKKKKKIKIIIBHHHHHIIIIIIIIIIIIIIIIIIIIIIM\nKKKKTKOOGEGGGHGHDDDDDYYYCCCCCOOTTTTTTTTTTIIIIIIIIIIHHHHHBBBBBBGGGGGJGGGQGGLGGGGGGJJJJJJRRJJJBBBBKKKKKKKKKKKKKKFHHHHHHHIHHIIIIIRIIIIIIIIIIMMM\nKRRRVOOGGGGGGGGGDDDDPDDYDSSCCCOOOTTOTTTTTIIIIIIIIIIHHHBHBBBBBBGGGGGJGJJGGGGGGGGGGJJJJJRRRRRWBBBBBBVKKKKKKKKKKTHHHHHHHHHHIIIIIIIIIIIIIIGIIMMM\nYVRVVOOGGGGGGGDDDDDDDDDDDSSCCOOOOOOOTOOOIIIIIIIIIIIHHBBBBBBBBBGGGGGJJJJJGGGCGGFFGFFJRRRRRRRWWBBBBBBKKKKKKKKKKKHHHHHHHHHFFIIIIIIIIIIIIIGIVVMM\nYVRVVVVGGGGGGGDDDDDDDDDDDDDCCOOOOOOOOOOOIIIIIIIIIIIHHHBBBBBBBBBBGGJJJJJJJJJGGGFFFFRRRRRRRRRRRBBBBBKKKKKKKKKKKKKHHHHHHHHFIIIIIIIIIIIIIIIIVVVM\nYVVVVVVVVGGGGGGDDDDDDDDDDDDOOOOOOOOOOOOOOIIIIIIEEIIHHHOBBBBBBBBBBGJJJJJJJJJFFFFFFFFFRRRRRRRRRRBBBBKBKKKKKKKKKKKHHHHHHFFFFIIFIIIIZIIAIIIIVVMM\nVVVVVVVVVGGGGGGDDDDDDDDDDDOOOOOOOOOOOOOOOOOOOIOOEJJHHHOBBBBBBBBBBEEJEEEEEFFFFFFFFFFFRRRRRRRNBBBBBBBBKKKKKKKKKKRHHHHHHFFFFFFFIIIIIIIIBBIIVMMM\nVVVVVVVVVGGGGGDDDDDDDDDDDDEOOOOOOOOOOOOOOOOOOOOOEEJHHOOOBBBBGGGGBEEEHEEXFFFFFFFFFFFFRRRRRRBNBBBBBBBBKKKKKKKKKKHHHHHHHFFFFFFFIIIIIIIIBBVVVMMM\nVVVVVVVVGGGGGDPDDDDDDDDDDDEEOOOOOOOOOOOOOOOOOOOOEEJEOOOOBGGGGGGGHEEEEEEFFFLFFFFFFFFRRRRRRRBBBBBBBBBBBKKKKKKKKFHHHHHFFFFFFFFIIIIIIIIIIVVVVVMM\nVVVVVVVVGGGGGDDDDDDDDDDDDDDEOOOOOOOOGOOOOOEOIIOOEEEEOOOOOGGGGGGGEEEEEEEFFFFFFFFFFFFFRDRRXXBBBBBBBBBBBKKKKKKKKKBBHHHHFFFFFFFIIIIIIIIIVVVVVVLM\nVVVVVVVVWGGGGDDDDDDDDDDDDEEEOOOOOOGGGOOOOOOIIIIIEEOOOOBOOGGGGGGGUEEEEEGUFFFFFFFFFFFFDDDDMMSBBBBBBBBBBBBBKKKKKKBBBHHFFFFFFFFIIIIINNWIVVVVVVLL\nVVVVVVZZZFGGGRDDDDDDDDDDDEOOOOOOOFFFGOGOOIIIBIBBBEOBBBBBBGGGGGGGEEEEEGGUUFFFFFFFFFFFDDDDDMMMBBBBBBBBBBBKKKKKKBBBBHHFFFFFFFFFIINNNNNPPVVVVLLL\nVVVZZZZZZZIGRRADADDDDDDDDEOEEOYYGFFGGOGGGIIIBBBBBEBBBBBBBGGGGGGGFEEEGGGGUUFFFFFFFFFHDVVVVVVMBBBBBBBBBBBKKKKBBBBBBBBBFFFFFFFRRRRNNNNPPVVLLLLL\nVVZZZZZZZZZRRRADAADEEEDDDEEEEOYYGGGGGGGGGGIBBBBBBBBBBBBBBGGGGGGGEEEEBGGGUUFFFFFFFFFHHVVVVVVMBBBBBBBBBPBKKBBBBBBBBBBFFFFFFFFFRBRNNNNNNNVLLLLL\nVZZZZZBZZZNAAAAAAAAEEEEEEEEEGGYYGGGGGGGGGIIBBBBBBBBBBBBBBGGGGGFFFEEBBGGGGCFFFFFFFFFHHVVVVVVMBBBBBBBMMMMMBBBBBBBGBBBFFFFFFFGGBBBNNNNNLLLLLLLL\nBBBBBBBZZNNNAAAAAAEEEEEEGEEEEGYYGGGGGGGIIIIBBBBBBBBBBBBBBGGGGGFFCCCBGGGCCCFCCWWWWWWWHVVVVVVMMBBBMMMMMMMMBBBBBBBGBGGTTFFFFFFFFBBNNNNNLLLLLLLL\nJBBBBBBBZZNAAAAAAAAAAGGGGGGEGGGGGGGGGGGGGIHDBBBBBBBBBBBBBBFFFFFCCCCCGGGCCKCCCWHHHHHHHVVVVVVMMVVVVVVMMMMMBBBBBBGGBGGTFFFFTFFFFBBBBBBBBBLLLLLL\nJJJBBBBBBAAAAAAAAAAAGGGGGGGEGGGGGGGGGGGGIIHDBBBBBBBBBBBBBBBBFFFCZCCCCCCCCCCCCHHHHHHHHVVVVVVMMVVVVVVMMMMMBBBBBBGGGGGTTFFTTFFFBBBBBBBBBBLLLLLL\nJJJBBBBAAAAAAAAAAAAAGGGGGGGGGGGGGGGGGGGGIHHDHHHHBBBBBBSSSSFFFFFCCCCCCCCCCCCCCHHHHHHHHVVVVVVHHVVVVVVMMMMMBBBBBBGGGGGTTTTTTFHFBBBBBBBBBBBLBBLV\nJJJJJJAAAAAAAAAAAAAAGGGGGGGGGGGGGGGGGGGHHHHHHHHHHIJJJJJSSSSFFFCCFFCCCCCCCCCCCHHHHHHHHVVVVVVVVVVVVVVMMMMMMBBBBGGGGGGGGGTTTLLBBBBBBBBBBBBBBBBV\nJJJJJJAAAAAAAAAAAAAAGAAGGGGGGGGGGGGGGGGHHHHHHHHHHJJJHJSSSSSFFFFFFCCCCCCCCCCCCHRHHHHHHVVVVVVVVVVVVVVGMMMMMBBBBGGGGGGGGGTTLLLLLLBBBBBBBBBBBBBB\nJJJJJJAAAAAAAAAAAAAAAAGGGGGGGGHGGGGGGGGHHHHHHHHHHJJJJJJJSJSFFFFFCCCCCCCCCCCCCCHHHHHHHVVVVVVVVVVVVVVGGMMCMBBBGGGGGGGGPGGGLLZLLLBBBBBBBBBBBBBB\nJJJJJJAAAAAAAAAAAAAAGAGGGGGGGGGGGGZZGHGHHHHHHHHHJJJJJJJJJJSFFFFFCCCCCCCCCCCCCCHHHHHHHHHOHHOOMVVVVVVGGJGGIBBBTGGGGGGTGGGLLLLLLLLBBBBBBBBBBBBB\nJJJJJAA" <> ...} 23 + ``` 24 + 25 + ```elixir 26 + map = 27 + puzzle_input 28 + |> String.split("\n", trim: true) 29 + |> Enum.with_index() 30 + |> Enum.flat_map(fn {row, y} -> 31 + row 32 + |> String.split("", trim: true) 33 + |> Enum.with_index() 34 + |> Enum.map(fn {plant, x} -> {{x, y}, plant} end) 35 + end) 36 + |> Map.new() 37 + ``` 38 + 39 + <!-- livebook:{"output":true} --> 40 + 41 + ``` 42 + %{ 43 + {18, 103} => "H", 44 + {76, 13} => "F", 45 + {61, 121} => "X", 46 + {112, 138} => "T", 47 + {37, 47} => "U", 48 + {65, 63} => "G", 49 + {77, 129} => "E", 50 + {120, 47} => "L", 51 + {38, 2} => "T", 52 + {1, 26} => "J", 53 + {116, 69} => "W", 54 + {124, 56} => "O", 55 + {83, 76} => "N", 56 + {117, 125} => "Q", 57 + {100, 134} => "W", 58 + {78, 139} => "D", 59 + {32, 15} => "O", 60 + {103, 106} => "N", 61 + {30, 113} => "J", 62 + {123, 104} => "W", 63 + {68, 134} => "Q", 64 + {124, 60} => "O", 65 + {89, 14} => "R", 66 + {35, 30} => "E", 67 + {37, 53} => "H", 68 + {77, 130} => "E", 69 + {2, 132} => "Q", 70 + {4, 5} => "K", 71 + {8, 50} => "X", 72 + {78, 98} => "Y", 73 + {101, 62} => "X", 74 + {98, 136} => "W", 75 + {95, 56} => "D", 76 + {74, 12} => "F", 77 + {17, 138} => "F", 78 + {102, 74} => "S", 79 + {11, 39} => "P", 80 + {131, 5} => "I", 81 + {65, 43} => "S", 82 + {22, 38} => "R", 83 + {14, 86} => "N", 84 + {139, 46} => "U", 85 + {12, 135} => "Q", 86 + {65, 131} => "A", 87 + {49, 117} => "O", 88 + {20, 41} => "D", 89 + {29, 25} => "G", 90 + {86, 10} => "R", 91 + {83, ...} => "I", 92 + {...} => "G", 93 + ... 94 + } 95 + ``` 96 + 97 + ```elixir 98 + defmodule Garden do 99 + def plots(map) do 100 + map 101 + |> Enum.group_by(&elem(&1, 1), &elem(&1, 0)) 102 + |> Enum.flat_map(fn {kind, pts} -> 103 + for parcel <- parcels(MapSet.new(pts), []) do 104 + {kind, parcel} 105 + end 106 + end) 107 + end 108 + 109 + def parcels(set, acc) do 110 + case Enum.take(set, 1) do 111 + [] -> 112 + acc 113 + 114 + [p] -> 115 + {parcel, rest} = flood(p, MapSet.new(), set) 116 + 117 + parcels(rest, [parcel | acc]) 118 + end 119 + end 120 + 121 + def flood({x, y} = curr, visited, potential) do 122 + visited = MapSet.put(visited, curr) 123 + potential = MapSet.delete(potential, curr) 124 + 125 + for next <- [ 126 + {x - 1, y}, 127 + {x + 1, y}, 128 + {x, y - 1}, 129 + {x, y + 1} 130 + ], 131 + next in potential, 132 + reduce: {visited, potential} do 133 + {v, p} -> flood(next, v, p) 134 + end 135 + end 136 + 137 + def as_int(false), do: 0 138 + def as_int(true), do: 1 139 + end 140 + ``` 141 + 142 + <!-- livebook:{"output":true} --> 143 + 144 + ``` 145 + {:module, Garden, <<70, 79, 82, 49, 0, 0, 15, ...>>, {:as_int, 1}} 146 + ``` 147 + 148 + ```elixir 149 + plots = Garden.plots(map) 150 + ``` 151 + 152 + <!-- livebook:{"output":true} --> 153 + 154 + ``` 155 + [ 156 + {"A", MapSet.new([{131, 11}])}, 157 + {"A", 158 + MapSet.new([ 159 + {54, 38}, 160 + {54, 39}, 161 + {55, 38}, 162 + {56, 36}, 163 + {56, 37}, 164 + {56, 38}, 165 + {57, 37}, 166 + {57, 38}, 167 + {57, 39}, 168 + {57, 40}, 169 + {58, 36}, 170 + {58, 37}, 171 + {58, 38}, 172 + {58, 39}, 173 + {58, 40}, 174 + {59, 36}, 175 + {59, 37}, 176 + {59, 38}, 177 + {60, 36}, 178 + {60, 37}, 179 + {60, 38}, 180 + {61, 36}, 181 + {61, 37}, 182 + {61, 38}, 183 + {62, 38}, 184 + {63, 38} 185 + ])}, 186 + {"A", MapSet.new([{18, 56}])}, 187 + {"A", 188 + MapSet.new([ 189 + {93, 86}, 190 + {94, 86}, 191 + {95, 86}, 192 + {95, 87}, 193 + {95, 88}, 194 + {96, 86}, 195 + {96, 87}, 196 + {97, 80}, 197 + {97, 81}, 198 + {97, 82}, 199 + {97, 83}, 200 + {97, 84}, 201 + {97, 85}, 202 + {97, 86}, 203 + {97, 87}, 204 + {98, 80}, 205 + {98, 81}, 206 + {98, 82}, 207 + {98, 83}, 208 + {98, 84}, 209 + {98, 85}, 210 + {99, 81}, 211 + {99, 82}, 212 + {99, 84} 213 + ])}, 214 + {"A", 215 + MapSet.new([ 216 + {35, 102}, 217 + {42, 111}, 218 + {38, 112}, 219 + {38, 108}, 220 + {39, 111}, 221 + {35, 106}, 222 + {41, 105}, 223 + {36, 105}, 224 + {36, 108}, 225 + {42, 110}, 226 + {35, 104}, 227 + {36, 109}, 228 + {43, 111}, 229 + {42, 107}, 230 + {41, 107}, 231 + {37, 108}, 232 + {41, 111}, 233 + {42, 108}, 234 + {39, 107}, 235 + {35, 103}, 236 + {36, 111}, 237 + {37, 113}, 238 + {37, 105}, 239 + {40, 110}, 240 + {38, 107}, 241 + {43, 107}, 242 + {38, 105}, 243 + {41, 110}, 244 + {34, 108}, 245 + {37, 109}, 246 + {35, 108}, 247 + {36, 106}, 248 + {42, 109}, 249 + {38, 114}, 250 + {37, 112}, 251 + {39, 110}, 252 + {39, 109}, 253 + {36, 103}, 254 + {38, 110}, 255 + {37, 111}, 256 + {39, 108}, 257 + {38, ...}, 258 + {...}, 259 + ... 260 + ])}, 261 + {"A", MapSet.new([{70, 115}, {70, 116}, {70, 117}, {71, 116}, {71, 117}, {72, 116}, {72, 117}])}, 262 + {"A", 263 + MapSet.new([ 264 + {85, 84}, 265 + {88, 82}, 266 + {87, 83}, 267 + {83, 84}, 268 + {87, 79}, 269 + {86, 82}, 270 + {86, 84}, 271 + {83, 85}, 272 + {87, 78}, 273 + {87, 84}, 274 + {85, 79}, 275 + {87, 81}, 276 + {85, 80}, 277 + {88, 83}, 278 + {84, 84}, 279 + {86, 81}, 280 + {86, 80}, 281 + {82, 85}, 282 + {85, 82}, 283 + {82, 84}, 284 + {82, 86}, 285 + {88, 81}, 286 + {87, 82}, 287 + {86, 83}, 288 + {85, 81}, 289 + {83, 83}, 290 + {84, 80}, 291 + {88, 84}, 292 + {83, 86}, 293 + {87, 80}, 294 + {87, 77}, 295 + {81, 85}, 296 + {85, 83}, 297 + {84, 85}, 298 + {84, 82}, 299 + {84, 81}, 300 + {84, 83} 301 + ])}, 302 + {"A", 303 + MapSet.new([ 304 + {19, 22}, 305 + {10, 25}, 306 + {16, 24}, 307 + {10, 32}, 308 + {17, 30}, 309 + {6, 29}, 310 + {18, 29}, 311 + {17, 22}, 312 + {13, 25}, 313 + {14, 24}, 314 + {10, 23}, 315 + {8, 29}, 316 + {13, 22}, 317 + {14, 28}, 318 + {6, 26}, 319 + {18, 26}, 320 + {16, 23}, 321 + {21, 26}, 322 + {19, 30}, 323 + {13, 27}, 324 + {16, 18}, 325 + {18, 23}, 326 + {9, 25}, 327 + {16, 29}, 328 + {7, 26}, 329 + {12, 27}, 330 + {16, 30}, 331 + {17, 24}, 332 + {18, 24}, 333 + {18, 22}, 334 + {6, 28}, 335 + {13, 20}, 336 + {9, 26}, 337 + {7, 27}, 338 + {11, 22}, 339 + {8, 25}, 340 + {17, 23}, 341 + {13, 23}, 342 + {20, ...}, 343 + {...}, 344 + ... 345 + ])}, 346 + {"A", 347 + MapSet.new([ 348 + {111, 103}, 349 + {107, 102}, 350 + {110, 102}, 351 + {110, 106}, 352 + {112, 103}, 353 + {114, 103}, 354 + {112, 100}, 355 + {108, 97}, 356 + {103, 96}, 357 + {109, 104}, 358 + {103, 99}, 359 + {108, 95}, 360 + {110, 104}, 361 + {113, 101}, 362 + {105, 105}, 363 + {108, 108}, 364 + {106, 105}, 365 + {111, 100}, 366 + {104, 98}, 367 + {109, 101}, 368 + {111, 104}, 369 + {107, 100}, 370 + {106, 102}, 371 + {112, 106}, 372 + {105, 95}, 373 + {104, 104}, 374 + {112, 97}, 375 + {108, 94}, 376 + {104, 97}, 377 + {111, 99}, 378 + {108, 102}, 379 + {108, 109}, 380 + {101, 97}, 381 + {104, 103}, 382 + {102, 96}, 383 + {112, 101}, 384 + {113, 97}, 385 + {100, ...}, 386 + {...}, 387 + ... 388 + ])}, 389 + {"A", 390 + MapSet.new([ 391 + {132, 99}, 392 + {136, 110}, 393 + {137, 104}, 394 + {139, 106}, 395 + {134, 98}, 396 + {139, 101}, 397 + {136, 102}, 398 + {139, 104}, 399 + {136, 96}, 400 + {134, 107}, 401 + {132, 100}, 402 + {138, 96}, 403 + {138, 102}, 404 + {135, 109}, 405 + {137, 107}, 406 + {133, 97}, 407 + {135, 107}, 408 + {137, 101}, 409 + {139, 97}, 410 + {137, 100}, 411 + {139, 109}, 412 + {135, 100}, 413 + {137, 97}, 414 + {132, 97}, 415 + {138, 105}, 416 + {137, 106}, 417 + {138, 99}, 418 + {136, 100}, 419 + {135, 98}, 420 + {139, 98}, 421 + {138, 103}, 422 + {138, 107}, 423 + {136, 108}, 424 + {139, 99}, 425 + {133, 96}, 426 + {139, 105}, 427 + {132, ...}, 428 + {...}, 429 + ... 430 + ])}, 431 + {"A", 432 + MapSet.new([ 433 + {84, 102}, 434 + {82, 100}, 435 + {86, 101}, 436 + {82, 91}, 437 + {86, 93}, 438 + {90, 93}, 439 + {88, 93}, 440 + {86, 96}, 441 + {82, 95}, 442 + {84, 93}, 443 + {85, 97}, 444 + {87, 95}, 445 + {81, 95}, 446 + {83, 100}, 447 + {87, 93}, 448 + {81, 100}, 449 + {84, 96}, 450 + {88, 95}, 451 + {81, 98}, 452 + {84, 100}, 453 + {85, 102}, 454 + {84, 91}, 455 + {82, 97}, 456 + {85, 99}, 457 + {83, 95}, 458 + {89, 96}, 459 + {88, 94}, 460 + {84, 104}, 461 + {86, 102}, 462 + {80, 92}, 463 + {89, 94}, 464 + {86, 103}, 465 + {83, 92}, 466 + {83, 96}, 467 + {82, 102}, 468 + {84, ...}, 469 + {...}, 470 + ... 471 + ])}, 472 + {"A", 473 + MapSet.new([ 474 + {65, 131}, 475 + {65, 129}, 476 + {74, 135}, 477 + {72, 134}, 478 + {71, 133}, 479 + {66, 130}, 480 + {73, 135}, 481 + {69, 130}, 482 + {74, 134}, 483 + {66, 132}, 484 + {68, 132}, 485 + {67, 128}, 486 + {69, 133}, 487 + {71, 132}, 488 + {70, 134}, 489 + {72, 132}, 490 + {72, 133}, 491 + {69, 132}, 492 + {71, 130}, 493 + {74, 136}, 494 + {73, 136}, 495 + {70, 128}, 496 + {68, 130}, 497 + {69, 129}, 498 + {73, 133}, 499 + {69, 131}, 500 + {70, 129}, 501 + {70, 130}, 502 + {67, 133}, 503 + {68, 131}, 504 + {68, 129}, 505 + {72, 135}, 506 + {68, 128}, 507 + {73, 134}, 508 + {66, ...}, 509 + {...}, 510 + ... 511 + ])}, 512 + {"B", MapSet.new([{132, 12}, {132, 13}, {133, 12}, {133, 13}])}, 513 + {"B", MapSet.new([{111, 6}])}, 514 + {"B", MapSet.new([{104, 115}])}, 515 + {"B", MapSet.new([{83, 87}, {84, 87}, {84, 88}])}, 516 + {"B", MapSet.new([{83, 82}])}, 517 + {"B", MapSet.new([{71, 79}])}, 518 + {"B", 519 + MapSet.new([ 520 + {69, 112}, 521 + {70, 109}, 522 + {70, 111}, 523 + {70, 112}, 524 + {71, 108}, 525 + {71, 109}, 526 + {71, 110}, 527 + {71, 111}, 528 + {72, 108} 529 + ])}, 530 + {"B", MapSet.new([{67, 20}, {67, 21}, {68, 19}, {68, 20}])}, 531 + {"B", MapSet.new([{63, 100}])}, 532 + {"B", MapSet.new([{44, 121}, {44, 122}])}, 533 + {"B", MapSet.new([{41, 45}])}, 534 + {"B", MapSet.new([{30, 54}])}, 535 + {"B", MapSet.new([{18, 90}])}, 536 + {"B", MapSet.new([{10, 127}])}, 537 + {"B", MapSet.new([{9, 126}])}, 538 + {"B", 539 + MapSet.new([ 540 + {37, 75}, 541 + {39, 77}, 542 + {42, 73}, 543 + {35, 75}, 544 + {39, 81}, 545 + {40, 75}, 546 + {41, 75}, 547 + {40, 77}, 548 + {40, 81}, 549 + {40, 76}, 550 + {32, 78}, 551 + {33, 78}, 552 + {32, 77}, 553 + {37, 80}, 554 + {35, 79}, 555 + {34, 75}, 556 + {30, 78}, 557 + {39, 76}, 558 + {34, ...}, 559 + {...}, 560 + ... 561 + ])}, 562 + {"B", MapSet.new([{42, 69}])}, 563 + {"B", 564 + MapSet.new([ 565 + {0, 21}, 566 + {1, 21}, 567 + {1, 22}, 568 + {2, 21}, 569 + {2, 22}, 570 + {3, 21}, 571 + {3, 22}, 572 + {3, 23}, 573 + {3, 24}, 574 + {4, 21}, 575 + {4, 22}, 576 + {4, 23}, 577 + {4, 24}, 578 + {5, 21}, 579 + {5, 22}, 580 + {5, 23}, 581 + {5, ...}, 582 + {...}, 583 + ... 584 + ])}, 585 + {"B", MapSet.new([{100, 130}])}, 586 + {"B", 587 + MapSet.new([ 588 + {108, 25}, 589 + {108, 21}, 590 + {104, 24}, 591 + {104, 21}, 592 + {109, 18}, 593 + {107, 25}, 594 + {107, 18}, 595 + {109, 17}, 596 + {107, 27}, 597 + {106, 22}, 598 + {113, 20}, 599 + {112, 17}, 600 + {106, 26}, 601 + {108, 24}, 602 + {105, ...}, 603 + {...}, 604 + ... 605 + ])}, 606 + {"B", 607 + MapSet.new([ 608 + {15, 93}, 609 + {18, 93}, 610 + {17, 93}, 611 + {19, 97}, 612 + {13, 98}, 613 + {16, 93}, 614 + {17, 97}, 615 + {13, 95}, 616 + {14, 93}, 617 + {12, 95}, 618 + {15, 98}, 619 + {15, 96}, 620 + {14, 95}, 621 + {14, ...}, 622 + {...}, 623 + ... 624 + ])}, 625 + {"B", 626 + MapSet.new([ 627 + {45, 19}, 628 + {53, 23}, 629 + {54, 16}, 630 + {55, 17}, 631 + {53, 19}, 632 + {55, 20}, 633 + {56, 18}, 634 + {55, 21}, 635 + {49, 20}, 636 + {56, 22}, 637 + {47, 22}, 638 + {54, 23}, 639 + {47, ...}, 640 + {...}, 641 + ... 642 + ])}, 643 + {"B", 644 + MapSet.new([ 645 + {98, 9}, 646 + {97, 20}, 647 + {95, 16}, 648 + {100, 18}, 649 + {94, 21}, 650 + {97, 10}, 651 + {102, 16}, 652 + {93, 17}, 653 + {98, 19}, 654 + {95, 17}, 655 + {96, 13}, 656 + {92, ...}, 657 + {...}, 658 + ... 659 + ])}, 660 + {"B", 661 + MapSet.new([ 662 + {58, 10}, 663 + {61, 7}, 664 + {53, 9}, 665 + {58, 8}, 666 + {55, 11}, 667 + {60, 10}, 668 + {60, 11}, 669 + {60, 12}, 670 + {61, 11}, 671 + {59, 13}, 672 + {56, ...}, 673 + {...}, 674 + ... 675 + ])}, 676 + {"B", 677 + MapSet.new([ 678 + {131, 24}, 679 + {129, 25}, 680 + {130, 28}, 681 + {132, 31}, 682 + {127, 22}, 683 + {132, 33}, 684 + {130, 25}, 685 + {123, 25}, 686 + {130, 27}, 687 + {126, ...}, 688 + {...}, 689 + ... 690 + ])}, 691 + {"B", MapSet.new([{30, 42}, {31, 42}, {32, 42}])}, 692 + {"C", MapSet.new([{114, 87}, {114, 88}])}, 693 + {"C", MapSet.new([{103, 27}])}, 694 + {"C", MapSet.new([{98, 4}, {98, 5}])}, 695 + {"C", MapSet.new([{92, 104}])}, 696 + {"C", MapSet.new([{83, 33}])}, 697 + {"C", MapSet.new([{82, 87}])}, 698 + {"C", MapSet.new([{76, 32}])}, 699 + {"C", MapSet.new([{75, ...}])}, 700 + {"C", MapSet.new([{...}])}, 701 + {"C", MapSet.new([...])}, 702 + {"C", ...}, 703 + {...}, 704 + ... 705 + ] 706 + ``` 707 + 708 + ## Part 1 709 + 710 + ```elixir 711 + defmodule Garden.Circ do 712 + def circumfence(set) do 713 + {{sx, _}, {ex, _}} = Enum.min_max_by(set, &elem(&1, 0)) 714 + {{_, sy}, {_, ey}} = Enum.min_max_by(set, &elem(&1, 1)) 715 + 716 + rows = (sx - 1)..(ex + 1)//1 717 + cols = (sy - 1)..(ey + 1)//1 718 + 719 + vert = 720 + rows 721 + |> Enum.map(fn x -> count_flips(cols, &({x, &1} in set)) end) 722 + |> Enum.sum() 723 + 724 + hori = 725 + cols 726 + |> Enum.map(fn y -> count_flips(rows, &({&1, y} in set)) end) 727 + |> Enum.sum() 728 + 729 + vert + hori 730 + end 731 + 732 + defp count_flips(enum, init \\ false, func) do 733 + Enum.reduce(enum, {0, init}, fn elem, {count, last} -> 734 + curr = func.(elem) 735 + {count + Garden.as_int(last != curr), curr} 736 + end) 737 + |> elem(0) 738 + end 739 + end 740 + ``` 741 + 742 + <!-- livebook:{"output":true} --> 743 + 744 + ``` 745 + {:module, Garden.Circ, <<70, 79, 82, 49, 0, 0, 15, ...>>, {:count_flips, 3}} 746 + ``` 747 + 748 + ```elixir 749 + plots 750 + |> Enum.map(fn {_, points} -> 751 + Garden.Circ.circumfence(points) * MapSet.size(points) 752 + end) 753 + |> Enum.sum() 754 + ``` 755 + 756 + <!-- livebook:{"output":true} --> 757 + 758 + ``` 759 + 1464678 760 + ``` 761 + 762 + ## Part 2 763 + 764 + ```elixir 765 + defmodule Garden.Sides do 766 + def sides(set) do 767 + xy = do_count(set, 0, 1) 768 + yx = do_count(set, 1, 0) 769 + 770 + xy + yx 771 + end 772 + 773 + defp do_count(set, a, b) do 774 + set 775 + |> Enum.group_by(&elem(&1, a), &elem(&1, b)) 776 + |> Enum.sort() 777 + |> Enum.map(fn {_, row} -> row |> Enum.map(&(&1..&1)) |> RangeSet.new() end) 778 + |> Enum.chunk_every(2, 1, [RangeSet.new()]) 779 + |> Enum.flat_map(fn [top, bot] -> 780 + top.ranges 781 + |> Enum.map(fn a..b//_ -> 782 + Garden.as_int(not Enum.any?(bot.ranges, &(a == &1.first))) + 783 + Garden.as_int(not Enum.any?(bot.ranges, &(b == &1.last))) 784 + end) 785 + end) 786 + |> Enum.sum() 787 + end 788 + end 789 + ``` 790 + 791 + <!-- livebook:{"output":true} --> 792 + 793 + ``` 794 + {:module, Garden.Sides, <<70, 79, 82, 49, 0, 0, 16, ...>>, {:do_count, 3}} 795 + ``` 796 + 797 + ```elixir 798 + plots 799 + |> Enum.map(fn {_, plot} -> 800 + Garden.Sides.sides(plot) * MapSet.size(plot) 801 + end) 802 + |> Enum.sum() 803 + ``` 804 + 805 + <!-- livebook:{"output":true} --> 806 + 807 + ``` 808 + 877492 809 + ``` 810 + 811 + <!-- livebook:{"offset":17848,"stamp":{"token":"XCP.d5P0-cESwFZ7qUYI4K40J_3AxksZ7WIqnIE6sn4smJvJahembJKNW-3db5gLxIgp_FEyn1pBBioGJSDsU7MO2fi1HjFgxeFNU0dLXi9Z4tf68Ey8dtld73d7SrSGlcv2DDM","version":2}} -->