this repo has no description
at master 18 kB view raw
1<!-- livebook:{"persist_outputs":true} --> 2 3# Day 12 4 5```elixir 6Mix.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 26map = 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 98defmodule 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 139end 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 149plots = 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 711defmodule 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 739end 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 749plots 750|> Enum.map(fn {_, points} -> 751 Garden.Circ.circumfence(points) * MapSet.size(points) 752end) 753|> Enum.sum() 754``` 755 756<!-- livebook:{"output":true} --> 757 758``` 7591464678 760``` 761 762## Part 2 763 764```elixir 765defmodule 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 788end 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 798plots 799|> Enum.map(fn {_, plot} -> 800 Garden.Sides.sides(plot) * MapSet.size(plot) 801end) 802|> Enum.sum() 803``` 804 805<!-- livebook:{"output":true} --> 806 807``` 808877492 809``` 810 811<!-- livebook:{"offset":17848,"stamp":{"token":"XCP.d5P0-cESwFZ7qUYI4K40J_3AxksZ7WIqnIE6sn4smJvJahembJKNW-3db5gLxIgp_FEyn1pBBioGJSDsU7MO2fi1HjFgxeFNU0dLXi9Z4tf68Ey8dtld73d7SrSGlcv2DDM","version":2}} -->