;; Puzzle Solution ;; Because the journey will take a few days, she offers to teach you the game of *Camel Cards*. Camel ;; Cards is sort of similar to [[https://en.wikipedia.org/wiki/List_of_poker_hands][poker]] except it's designed to be easier to play while riding a camel. ;; #+NAME: day7-imports ;; [[file:chicken-src.org::day7-imports][day7-imports]] ;; -*- geiser-scheme-implementation: chicken -*- (import (chicken string) (chicken keyword) (chicken sort) (chicken irregex)) (define-record card label weight) (define-record hand cards bid type-rec rank) (define-record hand-type label weight) ;; day7-imports ends here ;; #+NAME: day7-input-scm ;; [[file:chicken-src.org::day7-input-scm][day7-input-scm]] ;; -*- geiser-scheme-implementation: chicken -*- (define input " 3Q373 470 K53JT 351 A9JK9 856 2T333 515 867T4 541 58K22 253 5JA6J 994 K4A4K 865 94377 519 92J2Q 901 J7676 389 2KK36 938 JQ2KK 987 Q7A82 509 TTTA5 243 72J27 502 AKKKA 387 23222 674 55335 161 AA655 73 QKKQA 686 5J2T5 680 666AT 385 ATA3A 761 TTT8J 364 98A2T 282 59A44 260 6T9QJ 130 T7TKQ 721 9274T 656 T9AJ4 182 A2222 259 TQKJ7 67 4J844 560 AAATA 636 9J36J 546 QJQQQ 119 249TT 295 877J7 221 4KA23 116 929Q2 929 99JQQ 445 Q9QJ8 432 4Q7TJ 963 4J2J8 783 5J657 257 88788 183 KKK7K 909 KK396 637 J45AT 117 84448 806 A2698 820 A9AA5 320 A3934 19 Q45Q5 392 78686 254 A55A5 701 98A4K 655 5AJ88 95 AK3KK 55 773KK 33 J9J9J 356 2KAKK 563 655K5 287 55T56 475 54444 308 5J5QA 811 QKA76 792 2K288 42 JTKA2 694 88668 889 8TQ64 212 23QQ2 261 8K8K5 365 JKKAA 234 3J894 880 667Q2 817 888T4 599 T5Q83 315 3QK29 670 JK4KK 322 75T8T 144 AAA7K 291 7T333 495 A49K4 448 JJ3J3 251 5999J 278 38438 890 6K3Q9 122 TTT99 93 94775 240 K8QJ3 369 59674 107 267J4 355 QTQTQ 187 46J44 961 Q7AK2 580 69969 609 876A5 474 A3866 642 Q3QQA 526 JAA88 425 35Q9K 986 QQTQJ 550 54535 357 2J222 639 QK5J7 743 222Q2 191 T4T44 855 QTQQ2 338 JA7A2 300 AAAJ2 508 4J455 23 A77AA 339 5KK25 899 252J2 737 7QJ76 888 K46QK 795 A4T3J 640 8A8K8 176 AA5AA 41 J2Q24 958 58855 632 333J3 610 74474 807 K3AAA 78 JJ222 765 44224 688 76733 361 5845K 181 TT4T2 974 23J33 102 QQJ6Q 34 Q9AQQ 150 22747 717 KAA5A 121 7AA7J 286 J786T 780 3K8TT 32 A6KAA 25 9A362 166 A29Q2 499 6688K 57 KKQKA 947 999JJ 975 6A666 927 TTT3K 658 JQQ7T 467 8A247 934 7JK8J 712 KK39K 612 6666Q 17 77Q37 868 A66AJ 169 KKKKJ 535 7Q7JJ 591 K9848 646 46888 931 A86A8 326 743TA 527 QKK67 977 KKJ6K 471 AAJ7A 571 55292 330 3A222 390 6453J 109 JKKKA 403 4J9T5 21 K7A5K 486 6TT34 793 3479Q 60 44624 443 6KK3K 164 4447J 112 QQ27Q 452 JAK65 522 Q5Q5Q 354 J5Q6A 540 68999 711 3QJ4Q 155 A6AAA 314 222KK 767 55T9A 373 T5T57 913 TTTTA 794 8J258 190 3Q87J 489 AAQAQ 950 Q4JJ4 588 6T64T 9 636K5 228 AA222 248 7KJ35 616 26646 507 44A4J 829 23323 904 TA265 135 JJQT9 136 KATJ8 644 J2862 713 4JQ28 152 Q3K2T 56 6Q232 812 9A622 885 KJKKJ 773 3859T 374 99333 101 TKTTK 205 3333A 35 5A4AQ 548 T4944 967 43353 813 423JK 869 T99T7 219 3AAAA 394 T65Q6 740 J9243 352 6656J 496 444K4 574 Q8T6K 98 AQ55K 917 7QQJ7 605 TJ5TT 615 68JQ5 852 7A3J2 745 369AK 217 57755 343 A8844 61 Q76QQ 698 36333 774 237Q7 12 KT694 283 88286 154 4T552 990 Q9J54 759 K6697 350 A3A33 937 AA9AA 246 QQ7KK 748 TT4A6 380 4J992 845 A66AA 573 5QQ2Q 28 86J37 214 2A443 362 Q9QKK 654 44434 964 77773 74 44355 235 9QK75 863 3AJ33 766 T2TJT 53 44494 860 883A9 309 QQ59Q 360 A88A8 584 A83A4 395 7J9TA 299 55955 833 QJK35 188 4656A 514 8KTQ4 554 56J47 985 J272J 184 9J999 671 72295 31 53555 264 4A537 750 7A4JJ 875 QK834 463 88KKA 570 QQ9JK 906 6Q646 858 53336 359 QJ8QJ 587 424TJ 607 KTKK6 285 Q5AQQ 84 899A8 542 K8TKK 250 4JA4A 705 6J75J 896 888K8 312 5583J 660 6T335 614 Q757T 945 3AKKA 629 KK946 825 3393Q 406 7J288 367 49999 907 99729 837 66265 384 K47JQ 263 2AJ4K 566 TTKKA 186 8J877 418 56844 666 JTTTT 531 6TJ94 26 JQ5J5 344 7J772 85 33747 510 KJA2A 729 333TQ 578 JQAT4 955 75766 834 QQ6QQ 980 32K33 306 TTTJ6 231 2QTTT 213 999AQ 608 33353 202 Q8Q8Q 756 KK555 490 746K8 691 98A75 853 JQ858 816 KK9KK 536 9T999 933 TA8A8 39 8558J 919 J8KQK 15 73Q2K 503 2K2KJ 585 JK9K5 903 TJ7T7 545 J723T 453 KT895 583 TTTKT 123 39535 393 K4K88 893 43KK6 821 6AA8J 504 972TA 597 7J736 592 536A8 63 J23Q3 402 83K9Q 405 28337 396 9T558 776 7AA78 946 QTT24 441 26QT3 401 AJQAQ 953 6T6AJ 304 JK5KK 162 2JJ2J 484 73773 6 8J864 630 78782 557 6TJ52 424 487JQ 830 8J698 82 AJAAA 866 228J8 204 622J4 823 6J2QJ 79 22K22 232 A86A6 444 83K8Q 965 JK586 944 JA848 465 8888A 45 2T28T 803 73J73 450 27272 857 7A777 544 A998J 679 46466 458 KJ233 192 4453J 378 TQQJT 451 A3K5J 512 888Q6 968 6AA66 841 QQ222 883 3K5A3 233 JA4AA 379 62288 778 44456 51 4A644 862 55647 981 A77A7 327 KQ3A3 687 QQ7Q7 976 T4A2T 293 46226 628 Q59Q5 348 36AJ2 984 54433 532 JJQ24 831 7455J 381 78845 218 72AQ5 276 52T22 618 99399 68 36AA3 118 69669 839 33Q5J 785 TJ766 626 T28J4 556 T883Q 142 73928 932 TJ884 494 AJ36Q 485 9Q999 324 T725Q 267 22622 88 92364 685 97792 789 J673K 620 99943 625 77JJ7 921 8828Q 572 7777J 353 TAAJT 926 99T29 787 AQ4J4 520 9J559 5 J3T94 706 K9KK9 918 KK252 439 79925 97 TT47T 497 848T4 126 6TTT6 426 K8825 925 888J8 62 K5K85 972 AAKKA 449 J5555 663 89J99 27 4Q444 922 A9A99 397 5A555 163 8J3K8 662 29989 645 95222 751 Q4Q4Q 193 555K5 982 74AJ8 735 KKQ6K 668 7676Q 916 A28T7 784 K57KK 388 A4J4J 115 2K442 229 33TT3 956 TT6TA 741 TT782 131 TJ5JQ 238 TQ7T7 415 29KQQ 598 A8AAT 676 46A28 650 6698K 696 6J969 158 6694A 271 QTQ5T 498 Q2QQQ 613 2A7QJ 210 6T466 683 QJ575 799 Q63Q3 822 Q9J28 848 TTTT7 7 KA9AA 854 K2JJT 859 28228 179 K29KJ 429 JJ8JJ 222 A99A5 457 QQTTT 983 43KK2 134 984JJ 1 97J97 892 2AAA8 689 9Q77J 819 98TJK 517 56KA5 71 7J66J 294 55855 335 TTT8T 596 33663 407 7J774 911 3JQ55 564 QQQ7Q 329 85668 120 KK333 301 Q3553 867 7K557 988 Q8488 400 96J99 643 29224 714 T8ATA 346 99J93 462 K83J3 697 3KQJ4 653 5KJQ2 824 4JJ3A 897 56248 727 JJ666 702 355T5 245 45KAK 553 88AAA 236 K55J5 581 AJJ49 65 A8Q3J 197 AAAKQ 529 55976 707 77776 930 A9995 227 K7J7K 912 29K99 244 4Q464 80 22972 195 666JQ 189 26278 241 79288 601 5454A 427 JTAKQ 138 88833 549 84J54 215 AATAK 114 58959 145 8ATTJ 431 QJ26K 265 A3JA3 81 T8T4J 242 4T3A3 37 44777 871 JQ542 561 A97Q9 693 A76T4 412 28T4A 481 T485A 861 78286 303 K6776 52 T8TKQ 754 KJ938 957 Q444Q 840 25A89 455 58588 673 K8858 634 K8KJ8 170 K6KKK 851 53353 140 2T2K6 593 QQAQA 48 TT6J6 305 922J2 920 AA22K 22 J555Q 725 TTAAT 781 2244J 171 A95K7 436 2J299 651 78AAA 321 2KKK2 690 2J565 649 77J5K 77 T999T 762 J4445 879 J888Q 873 J884J 1000 98898 413 29299 442 QKQ3Q 678 A652A 993 55272 898 KA5K5 664 8KJAQ 147 Q56QJ 734 K77J3 739 J7677 661 T5569 206 2AA2J 757 TJTJT 342 T2TTT 682 88J82 363 9KK78 700 AT4T4 730 86968 736 99995 207 7A3J4 172 8KK87 991 TKKJJ 16 J7532 165 J9888 996 9AJTA 92 43T78 310 93J77 317 J4424 805 43J86 703 952TJ 127 54363 146 8T2J7 435 88848 832 TAAAQ 791 8228T 256 699QT 815 KQQQK 30 T82J3 49 36222 4 AK288 86 6792A 194 2Q22T 667 J3545 270 9QJK4 280 QQ22Q 371 K9247 446 A422A 943 765K3 469 9J5A6 874 4A4QA 775 8Q8Q8 124 T8Q62 850 8Q8Q5 747 6KT88 738 82888 722 3TQQQ 349 2J3TT 539 7TQ59 72 8998T 733 JQJT3 414 82428 589 92856 423 89833 54 79T4A 523 95839 979 TJJT5 936 33839 29 37433 511 TKJ2T 681 JT973 633 Q8Q8J 971 Q5555 440 K8886 24 Q75A4 43 3AQ33 298 T446T 719 577J5 753 KJTKT 167 52528 8 25222 641 QJ2T8 621 A8JQJ 316 7T7A7 772 KQQTQ 141 83734 758 6Q66Q 434 QJ6Q2 638 AAA7A 196 57555 203 4QJQ4 216 82J5Q 763 A73A3 940 46AJQ 559 T4936 103 89Q29 262 7872T 466 A5J58 274 AAAQA 290 37399 844 A759Q 328 TJ9TT 273 77887 268 64A2J 978 6T76Q 110 QQ467 742 9J7Q5 422 4K6Q3 91 336K3 826 6K63Q 382 23552 105 243AA 505 Q887J 764 2J92A 749 68A3Q 416 7T8T8 199 225J5 404 24774 153 T7T77 870 3J393 347 Q5Q8J 128 7Q777 796 QKKKK 617 86686 108 44KT4 75 56858 622 5AJK4 960 3245Q 311 36536 370 6644Q 11 JKAAA 104 T2426 579 J3399 83 33933 602 A299J 777 26J22 224 8666J 594 J3J38 669 3AJ84 239 52Q8T 877 QJQQK 779 QJ6T8 797 43339 399 9AJ74 476 T499Q 13 2TAKA 928 T3K78 809 2923K 201 J8858 798 T8888 818 98399 168 8T266 555 23A57 652 3KKK3 113 22T22 460 AJJAA 106 7QKA8 464 QQ8TQ 368 99A99 341 62Q5A 223 J9T47 568 Q7388 894 69662 744 96J2T 323 2A779 89 Q2874 269 77797 948 5359A 864 AJ9K4 482 Q3Q44 567 JT958 665 A38J3 438 J4666 296 428J5 501 38K8K 410 6T979 709 3533T 284 2285A 910 933T6 882 K6666 786 56Q32 992 5J752 198 AJJQJ 600 KK5KK 3 38T94 180 67QTJ 69 J6636 200 229J8 493 QJTQ3 247 5KQ5K 149 654AT 528 T84T4 878 Q23QQ 905 QQQ74 325 4JTQQ 408 T4T78 340 3T5T5 551 3J3J3 391 88844 631 TTT9T 810 57775 935 A777J 604 4555T 2 A5J8T 942 22AJJ 506 22323 997 A3323 624 84442 516 2T992 76 J7T76 828 J8552 995 KTKK3 886 33853 782 53233 129 44J4J 372 KQQT2 480 K5649 576 3J63K 760 2J666 827 6JT68 318 45Q64 849 49884 801 9KTTK 902 66737 952 5Q8J4 708 57Q92 724 627J7 331 K22J6 473 4T444 923 J4444 552 78J8J 491 4K328 477 4AA3A 808 7A34Q 437 AQ888 428 8TA99 768 AA9A9 143 9K5AT 211 77722 40 TQTTT 941 Q2A4K 492 236T9 677 J8686 746 J585K 64 TJKQT 582 T3TTJ 157 22266 38 KT5TK 692 QJQQJ 908 4K623 279 7JJJ7 173 64A66 524 J7AJ8 417 K43Q3 769 T662T 148 54J2J 488 K6485 44 J6666 970 J26J9 209 8337Q 334 A27A4 319 A7T78 132 K777A 842 KKK4K 249 99K9K 430 8745K 151 Q2QTJ 433 QKQ76 525 25Q2Q 533 5QK6J 800 77T77 558 5K323 939 33KK4 590 K8A52 111 ATQJ6 569 ATK89 50 4433A 836 3KKKQ 891 46TK4 538 5249Q 447 2462K 675 8JT6T 336 466J7 459 7K7KK 838 544Q4 959 58773 483 823J5 999 2TKA5 752 AKJ58 386 7T833 99 KQ88Q 659 KJ3A4 790 K9595 307 3K3J4 534 3838T 220 32522 720 366Q3 500 J8868 989 T7KTK 376 JQQQA 14 42555 409 5T5T5 648 4KK4Q 383 K7777 884 736A3 543 343Q3 366 TJ856 237 JJ555 46 K5QQQ 275 QAQQ7 672 8KTJQ 731 QQQ3Q 47 J257Q 575 6Q3QQ 87 QKK43 924 TTATJ 998 K44K5 771 37895 881 48823 521 KKK74 456 99J79 139 J4542 635 AJ96K 954 K8937 411 5J355 895 96967 185 333T3 562 TAJ77 755 J38A8 487 AAT79 313 A6Q73 398 386JA 10 J35Q8 623 27758 969 3K3KJ 966 7928Q 627 AAA4A 59 2AA52 478 848J8 133 55225 843 TTQT9 619 3Q79K 255 27AK8 58 TKTKK 272 KTTAT 333 55666 802 47748 454 Q3T56 699 63T3T 302 8754Q 723 4J86T 358 8TTQ9 226 5523J 125 88588 606 58AAA 208 TK273 137 4Q7KQ 160 29292 577 Q333Q 611 22TT2 716 A55AA 258 64822 468 22228 847 2242T 788 JA26Q 472 8JAAA 174 K5Q8A 175 Q5AT4 732 J4434 530 76666 337 9998Q 547 9T2J9 100 3Q982 90 7727Q 281 92944 973 K2597 814 K444K 36 26KJ6 292 34K38 962 5A378 225 636J9 375 TTTT4 420 A66TA 461 69QK5 345 76293 479 66966 804 A3383 297 T82TT 657 2QJJQ 156 K2JK3 94 K6K66 252 K58QJ 876 6J979 513 92647 718 QQ9Q9 586 862Q5 20 5465K 915 KQ44Q 595 T66T6 288 TJT7T 710 5JT8K 159 KJTK3 603 KKJTQ 949 67776 914 J4323 177 22229 704 96999 178 8AJKA 70 69T69 419 65556 770 87738 537 547J4 835 44766 421 3355J 684 2K266 647 5TTT5 266 3T3TT 332 88JJ8 96 QQ5K3 887 K7JKK 377 J8Q2Q 66 2KKJ6 230 TTKQT 277 22Q92 18 JTTTK 695 J993Q 846 88898 728 88T87 715 Q74J4 872 4T999 951 T997Q 289 92QA9 726 AJ394 900 TT2T2 518 JJJJJ 565") ;; day7-input-scm ends here ;; In Camel Cards, you get a list of *hands*, and your goal is to order them based on the *strength* of ;; each hand. A hand consists of *five cards* labeled one of =A=, =K=, =Q=, =J=, =T=, =9=, =8=, =7=, ;; =6=, =5=, =4=, =3=, or =2=. The relative strength of each card follows this order, where =A= is the ;; highest and =2= is the lowest. ;; #+NAME: day7-part1-cards ;; [[file:chicken-src.org::day7-part1-cards][day7-part1-cards]] ;; -*- geiser-scheme-implementation: chicken -*- (define cards `((#:A . ,(make-card #:A 13)) (#:K . ,(make-card #:K 12)) (#:Q . ,(make-card #:Q 11)) (#:J . ,(make-card #:J 10)) (#:T . ,(make-card #:T 9)) (#:9 . ,(make-card #:9 8)) (#:8 . ,(make-card #:8 7)) (#:7 . ,(make-card #:7 6)) (#:6 . ,(make-card #:6 5)) (#:5 . ,(make-card #:5 4)) (#:4 . ,(make-card #:4 3)) (#:3 . ,(make-card #:3 2)) (#:2 . ,(make-card #:2 1)))) ;; day7-part1-cards ends here ;; The hands are separated into types. ;; #+NAME: day7-part1-types ;; [[file:chicken-src.org::day7-part1-types][day7-part1-types]] ;; -*- geiser-scheme-implementation: chicken -*- (define (calc-card-frequencies cardlist #!optional (frequencies '())) (if (eqv? '() cardlist) (sort (map cdr frequencies) >) (let* ((card-label (card-label (car cardlist))) (card-old-frequency (alist-ref card-label frequencies eqv? 0))) (calc-card-frequencies (cdr cardlist) (alist-update card-label (+ 1 card-old-frequency) frequencies))))) (define (calc-hand-type hand) (let ((frequencies (calc-card-frequencies (hand-cards hand)))) (cond ;; Insert the comparisons from below here ((= 5 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:five-of-a-kind hand-types))) ((= 4 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:four-of-a-kind hand-types))) ((and (= 3 (car frequencies)) (= 2 (cadr frequencies))) (hand-type-rec-set! hand (alist-ref #:full-house hand-types))) ((= 3 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:three-of-a-kind hand-types))) ((and (= 2 (car frequencies)) (= 2 (cadr frequencies))) (hand-type-rec-set! hand (alist-ref #:two-pair hand-types))) ((= 2 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:one-pair hand-types))) ((= 1 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:high-card hand-types))))) hand) ;; day7-part1-types ends here ;; Hands are primarily ordered based on type; for example, every *full house* is stronger than any ;; *three of a kind*. ;; #+NAME:day7-part1-hand-types ;; [[file:chicken-src.org::day7-part1-hand-types][day7-part1-hand-types]] ;; -*- geiser-scheme-implementation: chicken -*- (define hand-types `((#:five-of-a-kind . ,(make-hand-type #:five-of-a-kind 7)) (#:four-of-a-kind . ,(make-hand-type #:four-of-a-kind 6)) (#:full-house . ,(make-hand-type #:full-house 5)) (#:three-of-a-kind . ,(make-hand-type #:three-of-a-kind 4)) (#:two-pair . ,(make-hand-type #:two-pair 3)) (#:one-pair . ,(make-hand-type #:one-pair 2)) (#:high-card . ,(make-hand-type #:high-card 1)))) ;; day7-part1-hand-types ends here ;; If two hands have the same type, a second ordering rule takes effect. Start by comparing the *first ;; card in each hand*. If these cards are different, the hand with the stronger first card is ;; considered stronger. If the first card in each hand have the *same label*, however, then move on to ;; considering the *second card in each hand*. If they differ, the hand with the higher second card ;; wins; otherwise, continue with the third card in each hand, then the fourth, then the fifth. ;; #+NAME: day7-part1-hand-comparison ;; [[file:chicken-src.org::day7-part1-hand-comparison][day7-part1-hand-comparison]] ;; -*- geiser-scheme-implementation: chicken -*- (define (card> card-a card-b) (> (card-weight card-a) (card-weight card-b))) (define (hand-cards> cards-a cards-b) (or (card> (car cards-a) (car cards-b)) (and (< 1 (length cards-a)) (= (card-weight (car cards-a)) (card-weight (car cards-b))) (hand-cards> (cdr cards-a) (cdr cards-b))))) (define (hands> hand-a hand-b) (let ((type-weight-a (hand-type-weight (hand-type-rec hand-a))) (type-weight-b (hand-type-weight (hand-type-rec hand-b))) (cards-a (hand-cards hand-a)) (cards-b (hand-cards hand-b))) (or (> type-weight-a type-weight-b) (and (= type-weight-a type-weight-b) (hand-cards> cards-a cards-b))))) ;; day7-part1-hand-comparison ends here ;; #+RESULTS: ;; : #t ;; To play Camel Cards, you are given a list of hands and their corresponding *bid* (your puzzle ;; input). For example: ;; #+begin_example ;; 32T3K 765 ;; T55J5 684 ;; KK677 28 ;; KTJJT 220 ;; QQQJA 483 ;; #+end_example ;; Better sample input from [[https://old.reddit.com/r/adventofcode/comments/18cr4xr/2023_day_7_better_example_input_not_a_spoiler/][u/LxsterGames]] on Reddit: ;; #+NAME: day7-part1-hand-input-example ;; #+begin_example ;; 2345A 1 ;; Q2KJJ 13 ;; Q2Q2Q 19 ;; T3T3J 17 ;; T3Q33 11 ;; 2345J 3 ;; J345A 2 ;; 32T3K 5 ;; T55J5 29 ;; KK677 7 ;; KTJJT 34 ;; QQQJA 31 ;; JJJJJ 37 ;; JAAAA 43 ;; AAAAJ 59 ;; AAAAA 61 ;; 2AAAA 23 ;; 2JJJJ 53 ;; JJJJ2 41 ;; #+end_example ;; #+NAME: day7-part1-data-regex ;; [[file:chicken-src.org::day7-part1-data-regex][day7-part1-data-regex]] ;; -*- geiser-scheme-implementation: chicken -*- (define camel-card-irregex '(: (submatch-named cards (+ (or (/ #\A #\Z) (/ #\0 #\9)))) " " (submatch-named bid (+ (/ #\0 #\9))))) ;; day7-part1-data-regex ends here ;; #+NAME: day7-part1-data-extraction ;; [[file:chicken-src.org::day7-part1-data-extraction][day7-part1-data-extraction]] ;; -*- geiser-scheme-implementation: chicken -*- (define (cardstr->cards cardstr) (map (compose (cut alist-ref <> cards) string->keyword string) (string->list cardstr))) (define (input->hands input) (irregex-fold camel-card-irregex (lambda (from-index match seed) (let ((cardstr (irregex-match-substring match 'cards)) (bidstr (irregex-match-substring match 'bid))) (cons (make-hand (cardstr->cards cardstr) (string->number bidstr) #f #f) seed))) '() input)) ;; day7-part1-data-extraction ends here ;; This example shows five hands; each hand is followed by its *bid* amount. Each hand wins an amount ;; equal to its bid multiplied by its *rank*, where the weakest hand gets rank 1, the second-weakest ;; hand gets rank 2, and so on up to the strongest hand. Because there are five hands in this example, ;; the strongest hand will have rank 5 and its bid will be multiplied by 5. ;; #+NAME: day7-part1-hand-ranking ;; [[file:chicken-src.org::day7-part1-hand-ranking][day7-part1-hand-ranking]] ;; -*- geiser-scheme-implementation: chicken -*- (define (rank-hands sorted-hands #!optional (index 1)) (when (not (eqv? '() sorted-hands)) (hand-rank-set! (car sorted-hands) index) (rank-hands (cdr sorted-hands) (+ index 1)))) ;; day7-part1-hand-ranking ends here ;; #+RESULTS: ;; | Cards | Hand Type | Rank | Bid | Bid*Rank | ;; | AAAAA | five-of-a-kind | 19 | 61 | 1159 | ;; | JJJJJ | five-of-a-kind | 18 | 37 | 666 | ;; | AAAAJ | four-of-a-kind | 17 | 59 | 1003 | ;; | JAAAA | four-of-a-kind | 16 | 43 | 688 | ;; | JJJJ2 | four-of-a-kind | 15 | 41 | 615 | ;; | 2AAAA | four-of-a-kind | 14 | 23 | 322 | ;; | 2JJJJ | four-of-a-kind | 13 | 53 | 689 | ;; | Q2Q2Q | full-house | 12 | 19 | 228 | ;; | QQQJA | three-of-a-kind | 11 | 31 | 341 | ;; | T55J5 | three-of-a-kind | 10 | 29 | 290 | ;; | T3Q33 | three-of-a-kind | 9 | 11 | 99 | ;; | KK677 | two-pair | 8 | 7 | 56 | ;; | KTJJT | two-pair | 7 | 34 | 238 | ;; | T3T3J | two-pair | 6 | 17 | 102 | ;; | Q2KJJ | one-pair | 5 | 13 | 65 | ;; | 32T3K | one-pair | 4 | 5 | 20 | ;; | J345A | high-card | 3 | 2 | 6 | ;; | 2345A | high-card | 2 | 1 | 2 | ;; | 2345J | high-card | 1 | 3 | 3 | ;; | Total | | | | 6592 | ;; Now, you can determine the total winnings of this set of hands by adding up the result of ;; multiplying each hand's bid with its rank (=765= * 1 + =220= * 2 + =28= * 3 + =684= * 4 + =483= * ;; 5). So the *total winnings* in this example are *=6440=*. ;; #+NAME: day7-part1-total-winnings ;; [[file:chicken-src.org::day7-part1-total-winnings][day7-part1-total-winnings]] ;; -*- geiser-scheme-implementation: chicken -*- (define (total-winnings hands) (foldl (lambda (total hand) (let ((bid (hand-bid hand)) (rank (hand-rank hand))) (+ total (* bid rank)))) 0 hands)) ;; day7-part1-total-winnings ends here ;; Find the rank of every hand in your set. *What are the total winnings?* ;; #+NAME: day7-part1-calc-fn ;; [[file:chicken-src.org::day7-part1-calc-fn][day7-part1-calc-fn]] ;; -*- geiser-scheme-implementation: chicken -*- (define (calc-part-1) (let ((hands (input->hands input))) (map calc-hand-type hands) (rank-hands (reverse (sort hands hands>))) (total-winnings hands))) ;; day7-part1-calc-fn ends here ;; Quest ;; To make things a little more interesting, the Elf introduces one additional rule. Now, =J= cards are ;; [[https://en.wikipedia.org/wiki/Joker_(playing_card)][jokers]] - wildcards that can act like whatever card would make the hand the strongest type possible. ;; To balance this, *=J cards are now the weakest* individual cards, weaker even than =2=. The other ;; cards stay in the same order: =A=, =K=, =Q=, =T=, =9=, =8=, =7=, =6=, =5=, =4=, =3=, =2=, =J=. ;; #+NAME: day7-part2-cards ;; [[file:chicken-src.org::day7-part2-cards][day7-part2-cards]] ;; -*- geiser-scheme-implementation: chicken -*- (define p2-cards `((#:A . ,(make-card #:A 13)) (#:K . ,(make-card #:K 12)) (#:Q . ,(make-card #:Q 11)) (#:T . ,(make-card #:T 10)) (#:9 . ,(make-card #:9 9)) (#:8 . ,(make-card #:8 8)) (#:7 . ,(make-card #:7 7)) (#:6 . ,(make-card #:6 6)) (#:5 . ,(make-card #:5 5)) (#:4 . ,(make-card #:4 4)) (#:3 . ,(make-card #:3 3)) (#:2 . ,(make-card #:2 2)) (#:J . ,(make-card #:J 1)))) ;; day7-part2-cards ends here ;; /In addition, the ~cardstr->cards~ and, subsequently, ~input->hands~ functions have to be adjusted ;; to use this new list./ ;; #+NAME: day7-part2-data-extraction ;; [[file:chicken-src.org::day7-part2-data-extraction][day7-part2-data-extraction]] ;; -*- geiser-scheme-implementation: chicken -*- (define (p2-cardstr->cards cardstr) (map (compose (cut alist-ref <> p2-cards) string->keyword string) (string->list cardstr))) (define (p2-input->hands input) (irregex-fold camel-card-irregex (lambda (from-index match seed) (let ((cardstr (irregex-match-substring match 'cards)) (bidstr (irregex-match-substring match 'bid))) (cons (make-hand (p2-cardstr->cards cardstr) (string->number bidstr) #f #f) seed))) '() input)) ;; day7-part2-data-extraction ends here ;; =J= cards can pretend to be whatever card is best for the purpose of determining hand type; for ;; example, =QJJQ2= is now considered *four of a kind*. However, for the purpose of breaking ties ;; between two hands of the same type, =J= is always treated as =J=, not the card it's pretending to ;; be: =JKKK2= is weaker than =QQQQ2= because =J= is weaker than =Q=. ;; #+NAME: day7-part2-types ;; [[file:chicken-src.org::day7-part2-types][day7-part2-types]] ;; -*- geiser-scheme-implementation: chicken -*- (define (add-joker frequencies joker-freq) (let* ((joker-account joker-freq) (new-freqs (map (lambda (freq) (cond ((eqv? #:J (car freq)) freq) ((< 5 (+ joker-account (cdr freq))) (set! joker-account (- 5 (cdr freq))) (cons (car freq) 5)) (else (let ((newval (+ joker-account (cdr freq)))) (set! joker-account 0) (cons (car freq) newval))))) frequencies))) (alist-update #:J joker-account new-freqs))) (define (p2-calc-card-frequencies cardlist #!optional (frequencies '())) (if (eqv? '() cardlist) (let* ((joker-freq (alist-ref #:J frequencies eqv? 0)) (new-freqs (add-joker (sort frequencies (lambda (x y) (> (cdr x) (cdr y)))) joker-freq))) (sort (map cdr new-freqs) >)) (let* ((card-label (card-label (car cardlist))) (card-old-frequency (alist-ref card-label frequencies eqv? 0))) (p2-calc-card-frequencies (cdr cardlist) (alist-update card-label (+ 1 card-old-frequency) frequencies))))) (define (p2-calc-hand-type hand) (let ((frequencies (p2-calc-card-frequencies (hand-cards hand)))) (cond ;; Insert the comparisons from part 1 here ((= 5 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:five-of-a-kind hand-types))) ((= 4 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:four-of-a-kind hand-types))) ((and (= 3 (car frequencies)) (= 2 (cadr frequencies))) (hand-type-rec-set! hand (alist-ref #:full-house hand-types))) ((= 3 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:three-of-a-kind hand-types))) ((and (= 2 (car frequencies)) (= 2 (cadr frequencies))) (hand-type-rec-set! hand (alist-ref #:two-pair hand-types))) ((= 2 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:one-pair hand-types))) ((= 1 (car frequencies)) (hand-type-rec-set! hand (alist-ref #:high-card hand-types))))) hand) ;; day7-part2-types ends here ;; #+RESULTS: ;; | Cards | Hand Type | Rank | Bid | Bid*Rank | ;; | AAAAA | five-of-a-kind | 19 | 61 | 1159 | ;; | AAAAJ | five-of-a-kind | 18 | 59 | 1062 | ;; | 2JJJJ | five-of-a-kind | 17 | 53 | 901 | ;; | JAAAA | five-of-a-kind | 16 | 43 | 688 | ;; | JJJJ2 | five-of-a-kind | 15 | 41 | 615 | ;; | JJJJJ | five-of-a-kind | 14 | 37 | 518 | ;; | KTJJT | four-of-a-kind | 13 | 34 | 442 | ;; | QQQJA | four-of-a-kind | 12 | 31 | 372 | ;; | T55J5 | four-of-a-kind | 11 | 29 | 319 | ;; | 2AAAA | four-of-a-kind | 10 | 23 | 230 | ;; | Q2Q2Q | full-house | 9 | 19 | 171 | ;; | T3T3J | full-house | 8 | 17 | 136 | ;; | Q2KJJ | three-of-a-kind | 7 | 13 | 91 | ;; | T3Q33 | three-of-a-kind | 6 | 11 | 66 | ;; | KK677 | two-pair | 5 | 7 | 35 | ;; | 32T3K | one-pair | 4 | 5 | 20 | ;; | 2345J | one-pair | 3 | 3 | 9 | ;; | J345A | one-pair | 2 | 2 | 4 | ;; | 2345A | high-card | 1 | 1 | 1 | ;; | Total | | | | 6839 | ;; With the new joker rule, the total winnings in this example are *=5905=*. ;; Using the new joker rule, find the rank of every hand in your set. *What are the new total ;; winnings?* ;; #+NAME: day7-part2-calc-fn ;; [[file:chicken-src.org::day7-part2-calc-fn][day7-part2-calc-fn]] ;; -*- geiser-scheme-implementation: chicken -*- (define (calc-part-2) (let ((hands (p2-input->hands input))) (map p2-calc-hand-type hands) (rank-hands (reverse (sort hands hands>))) (total-winnings hands))) ;; day7-part2-calc-fn ends here