diff --git a/datasets/adventofcode.com_2023_day_7_input.txt b/datasets/adventofcode.com_2023_day_7_input.txt new file mode 100644 index 0000000..27464b3 --- /dev/null +++ b/datasets/adventofcode.com_2023_day_7_input.txt @@ -0,0 +1,1000 @@ +4K8J9 314 +982KT 991 +88J55 371 +77744 552 +6268J 995 +9A7JJ 495 +2J28T 373 +88666 601 +68868 349 +5555A 844 +TTKTK 744 +86K64 111 +74A62 265 +7374J 135 +53Q44 673 +99979 890 +643T6 410 +58555 472 +2T4Q6 224 +TJAAA 692 +QQAKQ 576 +93469 282 +K6KK6 559 +95Q75 710 +K5955 743 +29223 240 +34J43 669 +8AAA7 299 +73J4K 121 +8JTKA 619 +TTKTJ 822 +8J74J 971 +J2828 298 +KQ7KQ 58 +5K44K 273 +KAQ55 831 +47J77 532 +54454 534 +8TT88 455 +77657 32 +Q8588 403 +KKJAK 358 +3A33A 574 +A947T 628 +68589 365 +QTTT7 668 +577A4 733 +A8286 562 +88885 954 +T3Q62 231 +TTT9J 256 +J462A 623 +39528 871 +8J277 690 +4852J 98 +48338 937 +55557 634 +QQKKA 172 +KA444 696 +8K292 821 +2KJK2 843 +5666J 897 +Q78J6 841 +53575 465 +73737 695 +3QTTQ 521 +6AAK3 51 +5A94K 74 +TJA24 649 +289A3 597 +88833 386 +A2Q32 750 +8T3TT 213 +J7K68 164 +A9A9Q 944 +T67T6 14 +66A66 148 +J5767 875 +5J522 102 +8QQQ8 772 +TKQQQ 884 +33983 542 +3333K 725 +33232 959 +6A656 414 +2A2A2 301 +JQ22Q 726 +22QJA 352 +TQQTQ 393 +84822 702 +K378J 659 +QAQAQ 975 +J5JJ5 379 +JAA45 698 +3T3Q2 921 +82382 17 +TK7A8 407 +T96T2 372 +52337 316 +KAQJ5 646 +53QA4 289 +8T8K8 291 +79447 475 +72A2Q 367 +728A2 363 +T9452 174 +KK77K 956 +9Q399 579 +5AJ5J 38 +Q5J55 216 +52555 845 +K46J5 602 +69523 333 +6733J 965 +AQQJQ 803 +4443T 145 +T9J99 453 +888A7 699 +82Q22 75 +66TJ6 242 +5QQQT 208 +99898 860 +78888 755 +9K9J7 918 +66A2A 46 +657K2 182 +AA44T 835 +T8T8T 241 +95732 205 +8257K 502 +Q5A69 313 +QQJQJ 585 +9A393 598 +44664 456 +KKK4J 643 +T8TTT 898 +KKATK 595 +3TTTT 223 +K3344 905 +JJ944 790 +A999A 934 +Q68JQ 988 +44334 49 +K3A3A 889 +84JJK 881 +25265 882 +QQ7T6 913 +A6262 280 +735K9 16 +5KQ4T 416 +QQ9Q8 39 +676AA 613 +A5999 793 +QQQ2Q 166 +8488J 509 +9T2Q9 23 +Q444Q 235 +Q5Q5Q 814 +5J888 813 +68699 716 +AJQAA 179 +3J5J5 920 +QQ4AA 481 +K4932 520 +3TT3T 20 +QQKK9 686 +TJ8Q4 738 +48545 176 +3K9K6 880 +77877 436 +949QA 269 +88828 753 +24A38 928 +244J4 605 +49T58 369 +6JJ5K 11 +68A88 440 +AJ995 604 +TTT35 622 +92K74 67 +85588 133 +A7ATT 138 +89AJ7 573 +J44Q4 801 +23Q76 610 +KK766 834 +72787 122 +2KK62 239 +4AAA8 1000 +29K5K 287 +Q9632 784 +28776 960 +Q66QQ 162 +KKTK7 867 +58777 936 +8777Q 870 +82Q75 942 +53737 545 +8J77Q 134 +JTTTJ 263 +JQTQ9 445 +TQQQQ 575 +425T5 851 +2J282 639 +AAAAJ 658 +K5K55 185 +K987K 86 +66QT6 275 +28A77 901 +996J6 9 +8444Q 769 +999TA 787 +97494 141 +35J35 717 +QQQQ5 981 +64QQ4 452 +55885 567 +T7QJQ 680 +9999J 511 +26688 113 +8858K 592 +4244T 335 +J56JQ 432 +33434 12 +8K95Q 767 +T336J 288 +777A8 762 +KAAJ8 405 +4QQ7Q 293 +8Q383 993 +A5TQ5 561 +7T77A 998 +33T3J 621 +2K288 146 +6AA47 827 +638J3 52 +2T633 703 +A3A5T 915 +J7777 799 +QQT55 584 +5A2Q3 629 +38AJ8 591 +A39AA 550 +Q5K4A 888 +T93K5 630 +Q4876 43 +84984 526 +2TQQT 832 +85J8J 59 +A8Q5Q 292 +K5KTK 266 +J5J33 776 +9K4KK 952 +55KKK 180 +34447 152 +J5552 136 +A4QJQ 428 +22JJ8 338 +ATKQ9 912 +5TT55 549 +4973K 886 +52Q55 327 +62829 399 +KTQK3 461 +TK683 654 +3JKQ2 770 +976Q3 951 +74449 727 +645J4 387 +22J2A 253 +83QTJ 533 +Q9Q55 212 +8JJJ8 513 +A8JJ7 566 +6K98Q 45 +88688 482 +A3343 568 +A5566 199 +66863 794 +5T8Q4 168 +J9578 221 +JAJAJ 961 +J4J44 254 +K88K6 272 +66963 336 +TK5Q6 640 +QT964 129 +TTA2A 932 +TT5AJ 626 +T7T4J 546 +QQQ44 30 +KKKKQ 468 +37QQ7 130 +78878 64 +63Q6Q 510 +KK6K4 809 +6J6TT 741 +AJ8TA 837 +QQA6Q 895 +722T2 594 +QKKQK 706 +725K2 459 +92A69 194 +84448 979 +KJKQQ 783 +88238 24 +626T6 382 +49K52 47 +6QJ6K 236 +57238 227 +J6JTK 719 +3T333 958 +T9J36 624 +5985A 802 +6446K 304 +Q4998 222 +5K396 7 +8559J 732 +QJ7Q7 79 +2KKK8 400 +7K77J 498 +2Q222 818 +A6AAA 479 +9Q73A 434 +AAJ96 101 +KTTQ6 839 +7J288 247 +K7JQT 84 +55625 655 +T2KQ8 919 +3269K 826 +A24A4 731 +8KJ7K 219 +A6277 543 +99393 758 +72662 796 +4KAJ9 557 +95KK3 19 +22225 855 +QKQQJ 946 +KT6QA 395 +8J39T 144 +27555 415 +T44T4 229 +43JK5 366 +62972 493 +55539 986 +83449 294 +28862 348 +JTA3T 431 +586K4 330 +KT3J7 226 +ATAT8 302 +J2Q27 402 +88Q8Q 424 +9K7KK 553 +88A88 923 +T8QJ5 413 +27222 972 +6AAA6 35 +A7333 829 +76J77 202 +26262 359 +55Q55 679 +T66T6 184 +55594 53 +J958A 999 +A5K5A 538 +TA77T 261 +T9979 792 +58J3K 48 +AAJKA 151 +8JJTT 807 +5A5JK 169 +88A58 250 +8T3QT 270 +67777 257 +TT77T 230 +2J6TT 444 +TA92T 71 +24922 760 +28222 279 +353TJ 765 +8J54T 516 +6QQ67 401 +8T98T 641 +9AA33 232 +JQQ4J 73 +K9997 842 +KAKKK 116 +K2332 95 +55Q5Q 191 +TQ7T7 941 +QQQK5 514 +5Q972 158 +6T64A 443 +46244 614 +2A9AT 607 +6T6K8 777 +89555 857 +Q223J 364 +KKTTK 672 +8K6JA 177 +86K97 713 +788K7 507 +3339T 976 +88624 110 +A8A98 887 +KAAAA 938 +367A8 786 +9A5A7 578 +73337 441 +6A58T 63 +QK6TQ 720 +777JA 955 +6KKKK 260 +94AA4 87 +K8KK8 964 +992T5 309 +33252 377 +64545 555 +5A553 438 +66A6J 795 +989T4 486 +8AJT4 153 +QK683 781 +2A4T5 300 +8A88A 820 +84877 953 +53535 611 +529AT 435 +ATAAA 681 +5564J 836 +Q7777 518 +Q992J 547 +374Q5 276 +7Q7Q5 645 +J3333 62 +44J64 849 +5JTT2 917 +2J423 808 +99Q92 632 +TKKTJ 704 +5TTKK 563 +A7A63 104 +582A9 730 +T363T 625 +9QJ4J 41 +J5T5T 759 +J77J7 217 +4KKKK 420 +AA4A7 930 +44JJ3 56 +9KK9T 388 +88KJA 858 +T6TT6 90 +777JT 115 +92Q22 962 +A7A7A 697 +JJ4J6 190 +5TA6Q 243 +KK7KK 246 +42224 429 +K2375 922 +45555 100 +75KKK 296 +QAA44 556 +T3JTT 527 +46999 933 +62772 262 +5TT4T 173 +28272 885 +44TT7 72 +889TJ 70 +TQ9TT 830 +J8K33 44 +66533 780 +69886 735 +74Q4Q 209 +36433 819 +88K88 312 +4TK98 752 +69599 708 +773A3 334 +JJJJJ 911 +2894K 785 +9Q845 667 +TTTT6 540 +97797 60 +5J66J 42 +38J38 525 +J222Q 797 +AKQ47 411 +7543T 492 +66566 906 +JK6K6 65 +45464 537 +4QK4K 112 +35533 381 +Q24J4 894 +Q223T 700 +KTTT9 8 +JT553 252 +5K923 89 +Q63A4 171 +T5TT5 318 +44842 739 +444A4 746 +5355K 778 +JJJ77 788 +96766 874 +4592A 900 +J49Q5 569 +J6J66 357 +62299 274 +88J52 969 +56TQ9 943 +JKKK8 529 +23223 973 +52T6K 775 +69999 949 +J5Q86 757 +Q5775 83 +3QQA6 548 +K79T2 940 +95K76 684 +44744 418 +J9AA4 374 +Q5455 422 +269QA 406 +4555J 853 +666T6 773 +4J5T3 500 +6J644 945 +J79Q7 665 +759KT 346 +3JAJ3 446 +AK42A 970 +555J5 596 +76TTT 93 +393K3 258 +A568A 15 +KQQQ2 218 +4Q6Q6 508 +KTTTT 380 +78QAA 36 +395J8 505 +6J6J3 852 +75944 564 +K5T2A 747 +T9989 480 +QQJ6Q 635 +J555J 657 +A6K26 76 +9323T 150 +78KT5 147 +Q6429 990 +JK3KK 618 +QATJT 462 +442Q6 846 +2J262 985 +A4AAA 197 +767A6 644 +5JQ5Q 978 +3338A 560 +A8AA8 903 +J8TT7 586 +55522 188 +3JAQ5 77 +JJTQ7 105 +TTT75 40 +3J565 664 +38585 356 +Q9JK9 879 +9J555 501 +Q3QJ4 245 +Q88Q3 238 +AAAJ2 26 +22TT2 865 +46573 779 +63336 27 +Q8JQK 873 +TTTQ3 319 +KJ5TA 656 +J65TK 285 +QT22Q 325 +J5625 593 +86466 81 +A7794 627 +24A24 55 +AKKAA 283 +29282 295 +TKATA 968 +9Q522 160 +J3232 29 +29KJ5 203 +QQ656 362 +98Q8Q 600 +78778 139 +5T6J5 817 +AQ992 477 +TATTA 908 +AAAA2 109 +AAA3A 3 +Q9Q99 683 +6666K 499 +9KKJ9 392 +K7KQK 361 +9K96T 131 +6458T 268 +3T2T8 142 +6K66K 800 +KKK54 749 +49494 588 +JTJK3 170 +5555T 798 +7T33T 804 +TJ6Q4 693 +J9777 652 +48777 907 +QK6JQ 31 +6865J 565 +AAJTT 137 +JT538 615 +7ATQ6 705 +83KQ2 805 +66266 701 +AK99A 847 +36666 485 +2QQ29 904 +J3777 823 +2A947 50 +7QQJA 916 +44Q5Q 68 +49444 609 +78542 519 +57JJ7 636 +8TK34 768 +7543K 554 +TT7TJ 127 +798Q5 278 +3K3J9 353 +QQQJ7 512 +A7A9J 984 +TTJTT 450 +9T8QK 324 +47JA7 466 +5J995 118 +695Q8 143 +5T582 590 +7Q67J 351 +24Q47 342 +79A99 99 +77775 248 +8A8Q8 149 +7A777 332 +99899 869 +3522Q 580 +3ATK4 140 +337J3 676 +J4422 370 +827Q4 467 +A5A28 375 +QQQKQ 570 +8QTJA 117 +8AQ6Q 10 +QK652 675 +KKTJJ 320 +44442 18 +JT77T 810 +688TQ 326 +65588 337 +587A9 950 +92222 914 +42823 977 +283Q6 103 +KQ98A 541 +6TQ7K 856 +8T882 186 +JAQQJ 711 +33994 647 +3QQ3Q 488 +76266 181 +926K6 449 +94635 863 +9523A 862 +8Q8Q5 494 +6JTTA 939 +K78K7 825 +JKK58 815 +29922 859 +883J8 391 +4JJJ4 69 +4Q49K 745 +T4555 233 +9J444 417 +6889Q 189 +22T2K 259 +5TT99 2 +59599 828 +33623 571 +76993 606 +88865 305 +5JAA5 748 +64JJ2 463 +KK4K4 328 +9Q9A9 157 +9KK9K 948 +A5A5A 478 +K9T83 909 +J8996 91 +268AQ 861 +82T39 206 +292J2 207 +T9TTT 892 +Q52T7 178 +84A48 107 +67786 57 +5KJAK 277 +3Q634 572 +3Q9J6 581 +J4KJA 771 +Q7K84 286 +29A3A 712 +3AQ9A 723 +826Q6 707 +QJJ4A 617 +59K93 448 +J67Q9 82 +A3TTT 833 +5JA93 924 +KKTKK 376 +9A999 854 +KQQKQ 308 +8A2JT 722 +99T9T 966 +JT3Q2 763 +K5757 484 +JTTT8 691 +J6666 344 +K4884 666 +K655K 474 +K2476 331 +8A962 503 +T3TKJ 926 +K3A74 754 +937J4 94 +57KJT 311 +282QK 345 +Q8435 21 +55454 225 +2AKQ5 670 +TAAA2 927 +Q8888 397 +JQQQQ 183 +QK692 215 +AA5KK 96 +J4A7A 192 +QA7QT 200 +K5A35 451 +33339 496 +Q95K3 281 +9J9J9 883 +77TKT 848 +QK279 297 +77366 408 +93KKK 528 +89949 506 +JK44K 255 +949J9 249 +A5AAA 963 +4KA4A 737 +777A3 28 +92999 329 +AJJ44 350 +KQ4J7 631 +ATQ23 167 +T6AKK 689 +JJ424 536 +Q43Q4 128 +7678K 425 +52736 764 +J8888 196 +8TKA4 718 +QJ99Q 106 +28764 642 +ATT85 390 +5K896 587 +6232J 210 +TTT2J 271 +7Q757 678 +QQQ8Q 633 +KTK33 577 +33JJ3 54 +9QQ9Q 524 +44747 497 +J5QA4 603 +T9428 155 +75755 872 +827AT 544 +42Q2A 878 +T7797 193 +6JA64 660 +JQ888 214 +4TTT4 439 +94J88 317 +KJK2K 687 +4237K 267 +888KQ 539 +89888 850 +55595 404 +7A3J9 4 +2A3K8 957 +4K9K5 616 +7KK6K 398 +KKK2K 126 +8JAJ8 161 +QJ999 33 +666AK 306 +63656 677 +8K346 515 +42J28 714 +4TT37 360 +A2992 476 +95979 967 +JKJKK 80 +77QQ7 385 +85J8K 165 +K8585 688 +J5KK7 812 +66699 159 +6326Q 925 +232TJ 523 +AK4KA 504 +QKJKK 460 +2A99J 66 +A583J 612 +J7222 736 +22J22 458 +67AA5 303 +8445J 896 +4467A 343 +5Q557 244 +KK8T8 220 +K7KJ7 323 +84888 651 +79947 198 +636J8 811 +37334 742 +5A438 378 +4J444 25 +33332 876 +AA33A 211 +22999 756 +KQQ99 551 +AJ2A4 791 +22QQ6 899 +TTT99 491 +25T9K 489 +6QKQK 234 +A8479 61 +AQ853 22 +T8575 663 +54J22 994 +QJ65Q 347 +3J545 6 +3TTT4 419 +9QJ8K 715 +3TJJ2 175 +289J7 201 +22224 92 +8AKA7 354 +66336 464 +Q3TTK 824 +TK5Q7 442 +QA3A5 187 +9A725 470 +294K4 1 +A3T7K 734 +9Q966 721 +4844T 88 +59J47 893 +84KT7 124 +43JKJ 724 +69989 740 +82882 430 +8AAAJ 487 +JJ888 996 +3433J 608 +KTK4K 383 +494J9 522 +T82TT 37 +K2QQK 530 +27KQ3 447 +33Q33 866 +92Q62 997 +T9T49 620 +TJ5TT 156 +52535 558 +9A333 840 +T24T2 78 +K4K44 582 +3Q849 483 +63763 709 +9Q7QQ 119 +84222 648 +9TQ26 409 +2A853 671 +AAAJ7 389 +224Q8 384 +AJ574 290 +7JJKQ 685 +J8JJJ 195 +2A973 599 +69699 935 +KJKKK 368 +QKT32 661 +3KAQ7 5 +7486T 728 +KK8AJ 891 +JKT9T 987 +66677 902 +2J578 125 +JT9T5 433 +7J963 931 +75577 653 +5A595 339 +2JK55 638 +94A39 154 +T3896 237 +TQ5TT 983 +KT272 877 +999J3 782 +7J667 34 +78J39 321 +A9AAT 531 +855J5 947 +87TA9 97 +AATAQ 228 +353J3 132 +525AA 108 +Q3635 589 +37JT2 251 +AAA8A 694 +75642 473 +9553K 114 +3Q9Q3 910 +8868J 650 +QQ666 774 +J458J 816 +28583 637 +JJ446 307 +A842T 412 +KKJ35 992 +44269 394 +3J87J 682 +JT654 13 +7J277 454 +53454 426 +669J6 674 +222JJ 761 +8T7J4 989 +68Q68 340 +66696 766 +9K525 163 +7A85Q 396 +QTTQT 315 +24294 535 +22A22 729 +26223 204 +27272 583 +A7KKK 421 +JKA4A 982 +5KKKK 471 +JK66A 284 +33QA9 517 +AJAAJ 123 +TT9J8 751 +63446 806 +A4TTT 427 +33K83 980 +6JK66 423 +252AJ 974 +77947 457 +AA88J 789 +53KTQ 838 +99J29 662 +3AJ33 490 +8J458 868 +655QQ 120 +AA347 355 +Q6QJ6 310 +Q936K 437 +A6AA2 85 +55KK4 264 +TJ6TT 341 +46444 469 +46J24 322 +T42Q8 864 +88989 929 diff --git a/src/day6/mod.rs b/src/day6/mod.rs new file mode 100644 index 0000000..063d114 --- /dev/null +++ b/src/day6/mod.rs @@ -0,0 +1,71 @@ +use super::Part; +use log::{debug, info, trace}; +use regex::Regex; + +fn solve_race(d: u64, t: u64) -> u64 { + info!("Resolving race d={}, t={}", d, t); + let mut count = 0; + + for x in 0..t { //TODO: we could definetly do maths (erk) here but i'm in a rush + trace!("If I am holding {}ms the boat will travel {}mm/{}mm ", x, (t-x)*x, d); + if (t-x)*x > d { + trace!("Found a solution: x={}: {} * {} = {}", x, x, t-x, d); + count+=1; + } + } + + count +} + +pub fn solve(lines: Vec, part: Part) -> u64 { + let mut time_line = lines.get(0).unwrap().to_owned(); + let mut distance_line = lines.get(1).unwrap().to_owned(); + + if let Part::Two = part { + time_line.remove_matches(' '); + distance_line.remove_matches(' '); + } + + let re = Regex::new(r"\d+").unwrap(); + + let times : Vec = re.captures_iter(&time_line) + .map(|capture| capture.get(0).unwrap().as_str().parse().unwrap()) + .collect(); + debug!("Current times: {:?}", times); + + let distances : Vec = re.captures_iter(&distance_line) + .map(|capture| capture.get(0).unwrap().as_str().parse().unwrap()) + .collect(); + debug!("Current distances: {:?}", distances); + + assert_eq!(times.len(), distances.len()); + + // Holding 1 ms => +1 mm/ms + // T: total time + // d: distance + // x: number of seconds holding the button + // x * (T - x) = d + // Tx - x² = d + + let mut result = 1; + for n in 0..(times.len()) { + let t = times[n]; + let d = distances[n]; + + result *= solve_race(d, t); + } + + result +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_solve_race() { + assert_eq!(solve_race(9, 7), 4); + assert_eq!(solve_race(40, 15), 8); + assert_eq!(solve_race(200, 30), 9); + } +} \ No newline at end of file diff --git a/src/day7/mod.rs b/src/day7/mod.rs new file mode 100644 index 0000000..e1d9357 --- /dev/null +++ b/src/day7/mod.rs @@ -0,0 +1,298 @@ +use std::{cmp::Ordering, collections::HashMap}; + +use super::Part; +use log::{debug, info, trace}; +use regex::Regex; + +#[allow(dead_code)] +#[derive(PartialEq, Eq, Debug, Hash, Clone)] +enum Value { + A, + K, + Q, + J, + T, + Number(u8) +} + +impl PartialOrd for Value { + + fn partial_cmp(&self, other: &Self) -> Option { + match (self, other) { + (Self::A, Self::A) => Some(Ordering::Equal), + (_, Self::A) => Some(Ordering::Less), + (Self::A, _) => Some(Ordering::Greater), + + (Self::K, Self::K) => Some(Ordering::Equal), + (_, Self::K) => Some(Ordering::Less), + (Self::K, _) => Some(Ordering::Greater), + + (Self::Q, Self::Q) => Some(Ordering::Equal), + (_, Self::Q) => Some(Ordering::Less), + (Self::Q, _) => Some(Ordering::Greater), + + (Self::J, Self::J) => Some(Ordering::Equal), + (_, Self::J) => Some(Ordering::Less), + (Self::J, _) => Some(Ordering::Greater), + + (Self::T, Self::T) => Some(Ordering::Equal), + (_, Self::T) => Some(Ordering::Less), + (Self::T, _) => Some(Ordering::Greater), + + (Self::Number(n_self), Self::Number(n_other)) => n_self.partial_cmp(n_other) + } + } +} + +impl Ord for Value { + fn cmp(&self, other: &Self) -> Ordering { + self.partial_cmp(other).unwrap() + } +} + +#[allow(dead_code)] +#[derive(Debug)] +enum Type { + FiveOfAKind(Value), + FourOfAKind(Value), + FullHouse(Value, Value), + ThreeOfAKind(Value), + TwoPair(Value, Value), + Pair(Value), + HighCard(Value) +} +impl PartialEq for Type { + fn eq(&self, other: &Self) -> bool { + matches!((self, other), (Self::FiveOfAKind(_), Self::FiveOfAKind(_)) | (Self::FourOfAKind(_), Self::FourOfAKind(_)) | (Self::ThreeOfAKind(_), Self::ThreeOfAKind(_)) | (Self::Pair(_), Self::Pair(_)) | (Self::HighCard(_), Self::HighCard(_)) | (Self::FullHouse(_, _), Self::FullHouse(_, _)) | (Self::TwoPair(_, _), Self::TwoPair(_, _))) + } +} +impl Eq for Type { + +} +impl PartialOrd for Type { + fn partial_cmp(&self, other: &Self) -> Option { + match (self, other) { + (Self::FiveOfAKind(v), Self::FiveOfAKind(o)) => v.partial_cmp(o), + (Self::FiveOfAKind(_), _) => Some(Ordering::Greater), + (_, Self::FiveOfAKind(_)) => Some(Ordering::Less), + + (Self::FourOfAKind(v), Self::FourOfAKind(o)) => v.partial_cmp(o), + (Self::FourOfAKind(_), _) => Some(Ordering::Greater), + (_, Self::FourOfAKind(_)) => Some(Ordering::Less), + + (Self::FullHouse(v, v2), Self::FullHouse(o, o2)) => { + let cmp = v.partial_cmp(o); + if let Some(Ordering::Equal) = cmp { + v2.partial_cmp(o2) + }else{ + cmp + } + }, + (Self::FullHouse(_, _), _) => Some(Ordering::Greater), + (_, Self::FullHouse(_, _)) => Some(Ordering::Less), + + (Self::ThreeOfAKind(v), Self::ThreeOfAKind(o)) => v.partial_cmp(o), + (Self::ThreeOfAKind(_), _) => Some(Ordering::Greater), + (_, Self::ThreeOfAKind(_)) => Some(Ordering::Less), + + (Self::TwoPair(v, v2), Self::TwoPair(o, o2)) => { + let cmp = v.partial_cmp(o); + if let Some(Ordering::Equal) = cmp { + v2.partial_cmp(o2) + }else{ + cmp + } + }, + (Self::TwoPair(_, _), _) => Some(Ordering::Greater), + (_, Self::TwoPair(_, _)) => Some(Ordering::Less), + + (Self::Pair(v), Self::Pair(o)) => v.partial_cmp(o), + (Self::Pair(_), _) => Some(Ordering::Greater), + (_, Self::Pair(_)) => Some(Ordering::Less), + + (Self::HighCard(v), Self::HighCard(o)) => v.partial_cmp(o), + } + } +} + +#[derive(Debug, PartialEq, Eq)] +struct Hand { + cards: [Value; 5], + kind: Type, + bid: u64, +} + +impl PartialOrd for Hand { + fn partial_cmp(&self, other: &Self) -> Option { + if self.kind == other.kind { + for (v, o) in self.cards.iter().zip(other.cards.iter()) { + match v.cmp(o) { + Ordering::Greater => return Some(Ordering::Greater), + Ordering::Less => return Some(Ordering::Less), + _ => {}, + } + }; + Some(Ordering::Equal) + }else{ + self.kind.partial_cmp(&other.kind) + } + } +} + +impl Ord for Hand { + fn cmp(&self, other: &Self) -> Ordering { + self.partial_cmp(other).unwrap() + } +} + +impl Value { + fn parse_char(c: char) -> Option { + match c { + 'A' => Some(Value::A), + 'K' => Some(Value::K), + 'Q' => Some(Value::Q), + 'J' => Some(Value::J), + 'T' => Some(Value::T), + '2'..='9' => Some(Value::Number(c.to_digit(10).unwrap() as u8)), + _ => None + } + } +} + +fn get_type_hand(cards: &[Value; 5]) -> Type { + // Get the count of each type of card + let counts = cards.iter().fold(HashMap::new(), |mut acc, e| { + let counter = acc.entry(e).or_insert(0); + *counter += 1; + + acc + }); + + let mut counts : Vec<_> = counts.iter().collect(); + counts.sort_by(|a,b| a.1.cmp(b.1)); + counts.reverse(); + debug!("# Cards {:?}", counts); + + let (v, c) = counts.first().unwrap(); + // TODO: make it an accumulator ? + + if **c == 5 { + Type::FiveOfAKind((***v).clone()) + }else if **c == 4 { + Type::FourOfAKind((***v).clone()) + }else if let Some(second_part) = counts.get(1) && **c == 3 && *second_part.1 == 2{ + Type::FullHouse((***v).clone(), (**second_part.0).clone()) + }else if **c == 3 { + Type::ThreeOfAKind((***v).clone()) + }else if let Some(second_part) = counts.get(1) && **c == 2 && *second_part.1 == 2 { + Type::TwoPair((***v).clone(), (**second_part.0).clone()) + }else if **c == 2 { + Type::Pair((***v).clone()) + }else{ + Type::HighCard((***v).clone()) + } +} + +fn parse(line: &str) -> Hand { + let (hand, bid) = line.split_once(' ').unwrap(); + + let cards = hand.chars().map(|c| Value::parse_char(c).unwrap()).collect::>().try_into().unwrap(); + let bid = bid.parse().unwrap(); + + let kind = get_type_hand(&cards); + + Hand { + cards, + kind, + bid + } +} + +pub fn solve(lines: Vec, _: Part) -> u64 { + let mut list : Vec = lines.iter().map(|v| parse(v)).collect(); + list.sort(); + debug!("{:?}", list); + + let mut sum: u64 = 0; + for (rank, card) in list.iter().enumerate() { + sum += (rank as u64 + 1 ) * card.bid; + } + + sum +} + +#[cfg(test)] +mod tests { + use log::info; + + use crate::utils::init_logger_test; + use super::*; + use super::Value::*; + fn init(){ + init_logger_test(); + } + + #[test] + fn test_parse_hands() { + init(); + + let h1 = "32T3K 765"; + let o1 = Hand{ + cards: [ + Number(3), + Number(2), + T, + Number(3), + K + ], + kind: Type::Pair(Number(3)), + bid: 765, + }; + let h2 = "T55J5 684"; + let o2 = Hand { + cards: [ + T, + Number(5), + Number(5), + J, + Number(5), + ], + bid: 684, + kind: Type::ThreeOfAKind(Number(5)) + }; + let h3 = "QQQJA 483"; + + let o3 = Hand { + cards: [ + Q, Q, Q, J, A + ], + kind: Type::ThreeOfAKind(Q), + bid: 483 + }; + + let h4 = "KK677 28"; + let o4 = Hand { + cards: [ + K, K, Number(6), Number(7), Number(7) + ], + kind: Type::TwoPair(K, Number(7)), + bid: 28 + }; + + info!("Hand 1 parsed {:?}", parse(h1)); + info!("Hand 1 reference {:?}", o1); + assert_eq!(parse(h1), o1); + + assert_eq!(parse(h2), o2); + assert_eq!(parse(h3), o3); + assert_eq!(parse(h4), o4); + } + + #[test] + fn test_parse_lines_and_all() { + let lines = "32T3K 765\nT55J5 684\nKK677 28\nKTJJT 220\nQQQJA 483".split('\n').map(|v| v.to_owned()).collect(); + let result = solve(lines, Part::One); + + assert_eq!(result, 6440); + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index f2c4994..4f8db0c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,14 @@ #![feature(let_chains)] +#![feature(array_zip)] +#![feature(string_remove_matches)] mod day1; mod day2; mod day3; mod day4; mod day5; +mod day6; +mod day7; mod utils; use log::info; use utils::Part; @@ -18,13 +22,10 @@ fn main() { .format_timestamp(None) .init(); - let data = utils::lines_from_file("./datasets/adventofcode.com_2023_day_5_input.txt").expect("Can't load the data"); - //let data = utils::lines_from_file("./datasets/test.txt").expect("Can't load the data"); - let result = day5::solve(data.clone(), Part::One); - let result2 = day5::solve(data, Part::Two); + let data = utils::lines_from_file("./datasets/adventofcode.com_2023_day_7_input.txt").expect("Can't load the data"); + let result = day7::solve(data, Part::One); - info!("Result part 1: {}", result); - info!("Result part 2: {}", result2); + info!("Result : {}", result); } @@ -56,8 +57,8 @@ mod tests { #[test] fn day3() { let data_path = "./datasets/adventofcode.com_2023_day_3_input.txt"; - let result = day3::solve(utils::lines_from_file(data_path).expect("Could not load the dataset for day 3"), Part::One); - let result2 = day3::solve(utils::lines_from_file(data_path).expect("Could not load the dataset for day 3"), Part::Two); + let result = day3::solve(utils::lines_from_file(data_path).expect("Could not load the dataset"), Part::One); + let result2 = day3::solve(utils::lines_from_file(data_path).expect("Could not load the dataset"), Part::Two); assert_eq!(result, 522726); assert_eq!(result2, 81721933); @@ -66,9 +67,26 @@ mod tests { #[test] fn day4() { let data_path = "./datasets/adventofcode.com_2023_day_4_input.txt"; - let result = day4::solve(utils::lines_from_file(data_path).expect("Could not load the dataset for day 3"), Part::One); - let result2 = day4::solve(utils::lines_from_file(data_path).expect("Could not load the dataset for day 3"), Part::Two); + let result = day4::solve(utils::lines_from_file(data_path).expect("Could not load the dataset"), Part::One); + let result2 = day4::solve(utils::lines_from_file(data_path).expect("Could not load the dataset"), Part::Two); assert_eq!(result, 20407); assert_eq!(result2, 23806951); } + + #[test] + fn day6() { + let data_path = "./datasets/adventofcode.com_2023_day_6_input.txt"; + let result = day6::solve(utils::lines_from_file(data_path).expect("Could not load the dataset"), Part::One); + let result2 = day6::solve(utils::lines_from_file(data_path).expect("Could not load the dataset"), Part::Two); + assert_eq!(result, 2612736); + assert_eq!(result2, 29891250); + } + + #[test] + fn day7() { + let data_path = "./datasets/adventofcode.com_2023_day_7_input.txt"; + let result = day7::solve(utils::lines_from_file(data_path).expect("Could not load the dataset"), Part::One); + + assert_eq!(result, 253866470); + } } \ No newline at end of file diff --git a/src/utils.rs b/src/utils.rs index 05b8ff3..da5a9c9 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -14,4 +14,12 @@ pub fn lines_from_file(filename: impl AsRef) -> Result> { pub enum Part { One, Two +} + +pub fn init_logger_test() { + env_logger::builder() + .filter_level(log::LevelFilter::Debug) + .format_timestamp(None) + .is_test(true) + .init(); } \ No newline at end of file