this repo has no description
at master 17 kB view raw
1<!-- vim:set ft=markdown: --> 2 3<!-- livebook:{"persist_outputs":true} --> 4 5# Day 16 6 7## Section 8 9```elixir 10defmodule Day16 do 11 defmodule Packet do 12 defstruct [:version, :type, :value] 13 end 14 15 def decode(<<version::3, 4::3, rest::bitstring>>) do 16 {value, rest} = literal(rest, 0) 17 18 {%Packet{type: 4, version: version, value: value}, rest} 19 end 20 21 def decode(<<version::3, type::3, 0::1, length::15, rest::bitstring>>) do 22 <<subpackets::bitstring-size(length), rest::bitstring>> = rest 23 24 {%Packet{type: type, version: version, value: decode_all(subpackets)}, rest} 25 end 26 27 def decode(<<version::3, type::3, 1::1, length::11, rest::bitstring>>) do 28 {value, rest} = Enum.map_reduce(1..length, rest, fn _, acc -> decode(acc) end) 29 30 {%Packet{type: type, version: version, value: value}, rest} 31 end 32 33 def decode_all(input) do 34 case decode(input) do 35 {packet, <<>>} -> [packet] 36 {packet, rest} -> [packet | decode_all(rest)] 37 end 38 end 39 40 defp literal(<<1::1, bits::4, rest::bitstring>>, acc) do 41 literal(rest, acc * 0x10 + bits) 42 end 43 44 defp literal(<<0::1, bits::4, rest::bitstring>>, acc) do 45 {acc * 0x10 + bits, rest} 46 end 47end 48 49input = 50 File.read!("day16.txt") 51 |> String.trim() 52 |> Base.decode16!() 53 |> Day16.decode() 54 |> elem(0) 55``` 56 57```output 58%Day16.Packet{ 59 type: 0, 60 value: [ 61 %Day16.Packet{ 62 type: 1, 63 value: [ 64 %Day16.Packet{type: 4, value: 20, version: 6}, 65 %Day16.Packet{ 66 type: 6, 67 value: [ 68 %Day16.Packet{type: 4, value: 14747, version: 1}, 69 %Day16.Packet{type: 4, value: 14747, version: 6} 70 ], 71 version: 2 72 } 73 ], 74 version: 1 75 }, 76 %Day16.Packet{ 77 type: 3, 78 value: [ 79 %Day16.Packet{type: 4, value: 15, version: 5}, 80 %Day16.Packet{type: 4, value: 10, version: 6} 81 ], 82 version: 7 83 }, 84 %Day16.Packet{ 85 type: 1, 86 value: [ 87 %Day16.Packet{ 88 type: 7, 89 value: [ 90 %Day16.Packet{type: 4, value: 2184, version: 1}, 91 %Day16.Packet{type: 4, value: 130250, version: 6} 92 ], 93 version: 6 94 }, 95 %Day16.Packet{type: 4, value: 5442981, version: 4} 96 ], 97 version: 6 98 }, 99 %Day16.Packet{type: 4, value: 8281083, version: 0}, 100 %Day16.Packet{ 101 type: 2, 102 value: [ 103 %Day16.Packet{type: 4, value: 102, version: 5}, 104 %Day16.Packet{type: 4, value: 647125, version: 7} 105 ], 106 version: 1 107 }, 108 %Day16.Packet{ 109 type: 1, 110 value: [ 111 %Day16.Packet{type: 4, value: 178, version: 1}, 112 %Day16.Packet{type: 4, value: 176, version: 6} 113 ], 114 version: 0 115 }, 116 %Day16.Packet{ 117 type: 1, 118 value: [ 119 %Day16.Packet{ 120 type: 6, 121 value: [ 122 %Day16.Packet{ 123 type: 0, 124 value: [ 125 %Day16.Packet{type: 4, value: 13, version: 1}, 126 %Day16.Packet{type: 4, value: 8, version: 4}, 127 %Day16.Packet{type: 4, value: 4, version: 3} 128 ], 129 version: 2 130 }, 131 %Day16.Packet{ 132 type: 0, 133 value: [ 134 %Day16.Packet{type: 4, value: 7, version: 7}, 135 %Day16.Packet{type: 4, value: 11, version: 3}, 136 %Day16.Packet{type: 4, value: 14, version: 2} 137 ], 138 version: 4 139 } 140 ], 141 version: 7 142 }, 143 %Day16.Packet{type: 4, value: 2724, version: 0} 144 ], 145 version: 1 146 }, 147 %Day16.Packet{type: 4, value: 9, version: 4}, 148 %Day16.Packet{ 149 type: 1, 150 value: [ 151 %Day16.Packet{ 152 type: 5, 153 value: [ 154 %Day16.Packet{type: 4, value: 7240238, version: 2}, 155 %Day16.Packet{type: 4, value: 233, version: 7} 156 ], 157 version: 1 158 }, 159 %Day16.Packet{type: 4, value: 37, version: 6} 160 ], 161 version: 4 162 }, 163 %Day16.Packet{type: 2, value: [%Day16.Packet{type: 4, value: 2, version: 5}], version: 5}, 164 %Day16.Packet{type: 4, value: 53749, version: 4}, 165 %Day16.Packet{type: 4, value: 11, version: 3}, 166 %Day16.Packet{ 167 type: 1, 168 value: [ 169 %Day16.Packet{type: 4, value: 382979, version: 4}, 170 %Day16.Packet{ 171 type: 5, 172 value: [ 173 %Day16.Packet{ 174 type: 0, 175 value: [ 176 %Day16.Packet{type: 4, value: 15, version: 1}, 177 %Day16.Packet{type: 4, value: 10, version: 0}, 178 %Day16.Packet{type: 4, value: 2, version: 6} 179 ], 180 version: 5 181 }, 182 %Day16.Packet{ 183 type: 0, 184 value: [ 185 %Day16.Packet{type: 4, value: 4, version: 7}, 186 %Day16.Packet{type: 4, value: 7, version: 4}, 187 %Day16.Packet{type: 4, value: 2, version: 5} 188 ], 189 version: 1 190 } 191 ], 192 version: 6 193 } 194 ], 195 version: 2 196 }, 197 %Day16.Packet{type: 4, value: 21251, version: 1}, 198 %Day16.Packet{ 199 type: 1, 200 value: [ 201 %Day16.Packet{type: 4, value: 163, version: 6}, 202 %Day16.Packet{ 203 type: 5, 204 value: [ 205 %Day16.Packet{type: 4, value: 59, version: 3}, 206 %Day16.Packet{type: 4, value: 836848134220, version: 1} 207 ], 208 version: 6 209 } 210 ], 211 version: 2 212 }, 213 %Day16.Packet{ 214 type: 2, 215 value: [ 216 %Day16.Packet{ 217 type: 0, 218 value: [ 219 %Day16.Packet{ 220 type: 0, 221 value: [ 222 %Day16.Packet{ 223 type: 2, 224 value: [ 225 %Day16.Packet{ 226 type: 2, 227 value: [ 228 %Day16.Packet{ 229 type: 0, 230 value: [ 231 %Day16.Packet{ 232 type: 3, 233 value: [ 234 %Day16.Packet{ 235 type: 2, 236 value: [ 237 %Day16.Packet{ 238 type: 2, 239 value: [ 240 %Day16.Packet{ 241 type: 3, 242 value: [%Day16.Packet{type: 0, value: [...], ...}], 243 version: 0 244 } 245 ], 246 version: 1 247 } 248 ], 249 version: 1 250 } 251 ], 252 version: 7 253 } 254 ], 255 version: 0 256 } 257 ], 258 version: 6 259 } 260 ], 261 version: 2 262 } 263 ], 264 version: 2 265 } 266 ], 267 version: 6 268 } 269 ], 270 version: 7 271 }, 272 %Day16.Packet{type: 1, value: [%Day16.Packet{type: 4, value: 44, version: 4}], version: 7}, 273 %Day16.Packet{ 274 type: 1, 275 value: [ 276 %Day16.Packet{type: 4, value: 255, version: 2}, 277 %Day16.Packet{type: 4, value: 91, version: 5}, 278 %Day16.Packet{type: 4, value: 176, version: 5}, 279 %Day16.Packet{type: 4, value: 23, version: 1} 280 ], 281 version: 7 282 }, 283 %Day16.Packet{ 284 type: 3, 285 value: [ 286 %Day16.Packet{type: 4, value: 11520, version: 4}, 287 %Day16.Packet{type: 4, value: 6069, version: 0}, 288 %Day16.Packet{type: 4, value: 1089149511401, version: 4}, 289 %Day16.Packet{type: 4, value: 158, version: 2}, 290 %Day16.Packet{type: 4, value: 620605, version: 0} 291 ], 292 version: 2 293 }, 294 %Day16.Packet{ 295 type: 0, 296 value: [ 297 %Day16.Packet{type: 4, value: 62788, version: 7}, 298 %Day16.Packet{type: 4, value: 9410622, version: 2}, 299 %Day16.Packet{type: 4, value: 15912821, version: 4} 300 ], 301 version: 4 302 }, 303 %Day16.Packet{ 304 type: 1, 305 value: [ 306 %Day16.Packet{type: 4, value: 22416, version: 5}, 307 %Day16.Packet{ 308 type: 5, 309 value: [ 310 %Day16.Packet{type: 4, value: 246, version: 1}, 311 %Day16.Packet{type: 4, value: 246, version: 4} 312 ], 313 version: 2 314 } 315 ], 316 version: 0 317 }, 318 %Day16.Packet{type: 3, value: [%Day16.Packet{type: 4, value: 13008601, version: 5}], version: 0}, 319 %Day16.Packet{ 320 type: 0, 321 value: [ 322 %Day16.Packet{ 323 type: 1, 324 value: [ 325 %Day16.Packet{type: 4, value: 3, version: 4}, 326 %Day16.Packet{type: 4, value: 14, version: 1}, 327 %Day16.Packet{type: 4, value: 5, version: 0} 328 ], 329 version: 5 330 }, 331 %Day16.Packet{ 332 type: 1, 333 value: [ 334 %Day16.Packet{type: 4, value: 2, version: 1}, 335 %Day16.Packet{type: 4, value: 14, version: 1}, 336 %Day16.Packet{type: 4, value: 10, version: 1} 337 ], 338 version: 6 339 }, 340 %Day16.Packet{ 341 type: 1, 342 value: [ 343 %Day16.Packet{type: 4, value: 8, version: 3}, 344 %Day16.Packet{type: 4, value: 6, version: 6}, 345 %Day16.Packet{type: 4, value: 11, version: 0} 346 ], 347 version: 1 348 } 349 ], 350 version: 5 351 }, 352 %Day16.Packet{ 353 type: 1, 354 value: [ 355 %Day16.Packet{type: 4, value: 32940592237, version: 2}, 356 %Day16.Packet{ 357 type: 5, 358 value: [ 359 %Day16.Packet{type: 4, value: 100, version: 1}, 360 %Day16.Packet{type: 4, value: 1393232728, version: 2} 361 ], 362 version: 2 363 } 364 ], 365 version: 0 366 }, 367 %Day16.Packet{type: 4, value: 89, version: 3}, 368 %Day16.Packet{ 369 type: 2, 370 value: [ 371 %Day16.Packet{type: 4, value: 204, version: 6}, 372 %Day16.Packet{type: 4, value: 260321821, version: 2}, 373 %Day16.Packet{type: 4, value: 225241983, version: 6} 374 ], 375 version: 0 376 }, 377 %Day16.Packet{ 378 type: 0, 379 value: [ 380 %Day16.Packet{type: 4, value: 960899, version: 3}, 381 %Day16.Packet{type: 4, value: 58997, version: 5}, 382 %Day16.Packet{type: 4, value: 54940, version: 6}, 383 %Day16.Packet{type: 4, value: 10974, version: 2}, 384 %Day16.Packet{type: 4, value: 882043, version: 2} 385 ], 386 version: 0 387 }, 388 %Day16.Packet{ 389 type: 1, 390 value: [ 391 %Day16.Packet{ 392 type: 6, 393 value: [ 394 %Day16.Packet{type: 4, value: 35633017255, version: 4}, 395 %Day16.Packet{type: 4, value: 35633017255, version: 2} 396 ], 397 version: 3 398 }, 399 %Day16.Packet{type: 4, value: 1359, version: 6} 400 ], 401 version: 6 402 }, 403 %Day16.Packet{ 404 type: 1, 405 value: [ 406 %Day16.Packet{type: 4, value: 92, version: 4}, 407 %Day16.Packet{type: 4, value: 38, version: 3}, 408 %Day16.Packet{type: 4, value: 160, version: 5}, 409 %Day16.Packet{type: 4, value: 111, version: 1}, 410 %Day16.Packet{type: 4, value: 64, version: 4} 411 ], 412 version: 4 413 }, 414 %Day16.Packet{ 415 type: 0, 416 value: [ 417 %Day16.Packet{type: 4, value: 2541, version: 3}, 418 %Day16.Packet{type: 4, value: 263947, version: 6}, 419 %Day16.Packet{type: 4, value: 7686705, version: 5}, 420 %Day16.Packet{type: 4, value: 31, version: 4} 421 ], 422 version: 2 423 }, 424 %Day16.Packet{ 425 type: 1, 426 value: [ 427 %Day16.Packet{ 428 type: 6, 429 value: [ 430 %Day16.Packet{type: 4, value: 3193865, version: 1}, 431 %Day16.Packet{type: 4, value: 20223, version: 7} 432 ], 433 version: 2 434 }, 435 %Day16.Packet{type: 4, value: 9328522, version: 5} 436 ], 437 version: 0 438 }, 439 %Day16.Packet{ 440 type: 2, 441 value: [ 442 %Day16.Packet{type: 4, value: 5, version: 4}, 443 %Day16.Packet{type: 4, value: 7, version: 3}, 444 %Day16.Packet{type: 4, value: 179420284, version: 4}, 445 %Day16.Packet{type: 4, value: 19890, version: 1}, 446 %Day16.Packet{type: 4, value: 2655, version: 0} 447 ], 448 version: 7 449 }, 450 %Day16.Packet{ 451 type: 1, 452 value: [ 453 %Day16.Packet{type: 4, value: 862089, version: 1}, 454 %Day16.Packet{ 455 type: 6, 456 value: [ 457 %Day16.Packet{type: 4, value: 248, version: 3}, 458 %Day16.Packet{type: 4, value: 3286, version: 5} 459 ], 460 version: 3 461 } 462 ], 463 version: 3 464 }, 465 %Day16.Packet{ 466 type: 1, 467 value: [ 468 %Day16.Packet{type: 4, value: 93, version: 6}, 469 %Day16.Packet{ 470 type: 5, 471 value: [ 472 %Day16.Packet{type: 4, value: 4269, version: 6}, 473 %Day16.Packet{type: 4, value: 240, version: 3} 474 ], 475 version: 4 476 } 477 ], 478 version: 5 479 }, 480 %Day16.Packet{ 481 type: 3, 482 value: [ 483 %Day16.Packet{type: 4, value: 2938, version: 6}, 484 %Day16.Packet{type: 4, value: 3, version: 6}, 485 %Day16.Packet{type: 4, value: 211, version: 7} 486 ], 487 version: 3 488 }, 489 %Day16.Packet{ 490 type: 1, 491 value: [ 492 %Day16.Packet{ 493 type: 7, 494 value: [ 495 %Day16.Packet{type: 4, value: 159, version: 0}, 496 %Day16.Packet{type: 4, value: 159, version: 5} 497 ], 498 version: 0 499 }, 500 %Day16.Packet{type: 4, value: 28, version: 1} 501 ], 502 version: 4 503 }, 504 %Day16.Packet{type: 4, value: 84, version: 4}, 505 %Day16.Packet{ 506 type: 1, 507 value: [ 508 %Day16.Packet{type: 4, value: 235, version: 4}, 509 %Day16.Packet{ 510 type: 6, 511 value: [ 512 %Day16.Packet{type: 0, value: [%Day16.Packet{...}, ...], version: 4}, 513 %Day16.Packet{type: 0, value: [...], ...} 514 ], 515 version: 3 516 } 517 ], 518 version: 6 519 }, 520 %Day16.Packet{type: 4, value: 1425, version: 4}, 521 %Day16.Packet{ 522 type: 1, 523 value: [ 524 %Day16.Packet{ 525 type: 7, 526 value: [%Day16.Packet{type: 0, value: [...], ...}, %Day16.Packet{type: 0, ...}], 527 version: 5 528 }, 529 %Day16.Packet{type: 4, value: 13, version: 2} 530 ], 531 version: 2 532 }, 533 %Day16.Packet{type: 0, value: [%Day16.Packet{type: 4, value: 3121, version: 6}], version: 5}, 534 %Day16.Packet{ 535 type: 1, 536 value: [ 537 %Day16.Packet{type: 4, value: 51, version: 2}, 538 %Day16.Packet{type: 4, value: 61, ...}, 539 %Day16.Packet{type: 4, ...} 540 ], 541 version: 4 542 }, 543 %Day16.Packet{ 544 type: 1, 545 value: [%Day16.Packet{type: 4, value: 1393, ...}, %Day16.Packet{type: 5, ...}], 546 version: 3 547 }, 548 %Day16.Packet{type: 1, value: [%Day16.Packet{type: 7, ...}, %Day16.Packet{...}], version: 3}, 549 %Day16.Packet{type: 1, value: [%Day16.Packet{...}, ...], version: 7}, 550 %Day16.Packet{type: 3, value: [...], ...}, 551 %Day16.Packet{type: 2, ...}, 552 %Day16.Packet{...}, 553 ... 554 ], 555 version: 3 556} 557``` 558 559## Task 1 560 561```elixir 562defmodule Day16.Task1 do 563 alias Day16.Packet 564 565 def sum(%Packet{type: 4, version: version}), do: version 566 567 def sum(%Packet{version: version, value: value}) do 568 Enum.reduce(value, version, &(sum(&1) + &2)) 569 end 570end 571 572Day16.Task1.sum(input) 573``` 574 575```output 576949 577``` 578 579## Task 2 580 581```elixir 582defmodule Day16.Task2 do 583 alias Day16.Packet 584 585 def evaluate(%Packet{type: 0} = packet), do: reduce(packet, 0, &+/2) 586 def evaluate(%Packet{type: 1} = packet), do: reduce(packet, 1, &*/2) 587 def evaluate(%Packet{type: 2} = packet), do: reduce(packet, :inf, &min/2) 588 def evaluate(%Packet{type: 3} = packet), do: reduce(packet, 0, &max/2) 589 590 def evaluate(%Packet{type: 4, value: value}), do: value 591 592 def evaluate(%Packet{type: 5} = packet), do: compare(packet, &>/2) 593 def evaluate(%Packet{type: 6} = packet), do: compare(packet, &</2) 594 def evaluate(%Packet{type: 7} = packet), do: compare(packet, &==/2) 595 596 defp reduce(%Packet{value: value}, initial, op) do 597 Enum.reduce(value, initial, &op.(evaluate(&1), &2)) 598 end 599 600 defp compare(%Packet{value: [a, b]}, op) do 601 if op.(evaluate(a), evaluate(b)), do: 1, else: 0 602 end 603end 604 605Day16.Task2.evaluate(input) 606``` 607 608```output 6091114600142730 610```