From 9b6584b0cf6d44aae64d71fd7f1abc459c54307a Mon Sep 17 00:00:00 2001 From: Bas Dado Date: Tue, 3 Dec 2024 00:33:28 +0100 Subject: [PATCH] Solved day 1 --- .gitignore | 4 + .idea/.gitignore | 8 + .idea/advent-of-code-2024-rust.iml | 11 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + Cargo.lock | 105 +++ Cargo.toml | 14 + input/day01.txt | 1000 ++++++++++++++++++++++++++++ input/day1_example.txt | 6 + src/day1.rs | 59 ++ src/dayX.rs | 40 ++ src/day_solver.rs | 6 + src/main.rs | 192 ++++++ src/util.rs | 181 +++++ 14 files changed, 1640 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/advent-of-code-2024-rust.iml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 input/day01.txt create mode 100644 input/day1_example.txt create mode 100644 src/day1.rs create mode 100644 src/dayX.rs create mode 100644 src/day_solver.rs create mode 100644 src/main.rs create mode 100644 src/util.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1b1301f --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/target +flamegraph.svg +perf.data +perf.data.* \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/advent-of-code-2024-rust.iml b/.idea/advent-of-code-2024-rust.iml new file mode 100644 index 0000000..cf84ae4 --- /dev/null +++ b/.idea/advent-of-code-2024-rust.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..b697a58 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..f4d4efc --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,105 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "advent-of-code-2024-rust" +version = "0.1.0" +dependencies = [ + "itertools", + "num", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..c88c7f0 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "advent-of-code-2024-rust" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +num = "0.4" +itertools = "0.13.0" + +# For flamegraph, enable this: +[profile.release] +debug = true diff --git a/input/day01.txt b/input/day01.txt new file mode 100644 index 0000000..df72c69 --- /dev/null +++ b/input/day01.txt @@ -0,0 +1,1000 @@ +40094 37480 +52117 14510 +92290 82570 +41563 59882 +56597 98604 +60657 66508 +85570 59882 +56065 27818 +78474 72704 +71099 14510 +34302 92950 +11680 14510 +17162 66508 +85767 69912 +43222 99057 +84192 42459 +86349 47916 +15974 93804 +62582 84872 +46480 96423 +49083 47125 +26321 82391 +29705 99057 +76669 53445 +97344 23937 +22364 82947 +43057 41784 +89096 14096 +54594 74691 +16496 21289 +16315 26820 +12070 39776 +92869 76329 +51048 82455 +39150 94320 +58187 83731 +68901 59853 +73788 77097 +11009 17200 +88295 15720 +59037 65311 +89459 74691 +44460 30211 +71139 80238 +91079 65185 +35005 50427 +50560 84872 +66445 66508 +11233 14510 +17699 33984 +90637 44753 +93142 10300 +19092 42065 +19173 83731 +58875 86050 +63423 83870 +71780 70501 +29252 92869 +59508 78068 +28083 14549 +81355 33405 +64678 38506 +83118 41435 +83177 48400 +94114 70501 +52985 82400 +60853 70531 +70827 98303 +78106 23782 +58175 55623 +33789 19841 +76421 45114 +58847 77539 +99979 53408 +59287 42943 +73877 29014 +95914 36915 +84344 87773 +19462 84872 +75441 13097 +51621 85661 +18456 32965 +49881 48400 +59056 55469 +52464 14549 +17562 76246 +99617 74396 +14300 46447 +15278 16859 +78081 41160 +74953 18829 +96718 92869 +56734 70429 +96632 92950 +87669 82496 +41413 47115 +23478 83870 +44726 38354 +98494 70501 +20040 82400 +52539 42459 +66799 78088 +34219 14821 +47568 77539 +36511 76135 +49296 14510 +81088 39776 +29532 39776 +93599 32110 +89573 43968 +61226 48400 +61073 17960 +10265 55334 +83307 82947 +26932 81159 +66857 83731 +77172 74877 +82796 14510 +83224 75812 +65968 33984 +58067 54289 +27835 73261 +25580 85562 +28693 14510 +11013 42459 +72686 75812 +38200 64002 +10540 82391 +16594 86787 +38238 47324 +72787 84872 +32314 65237 +52509 85451 +11856 42459 +74689 14549 +11006 47324 +62911 36777 +96648 28762 +78556 84872 +43118 55149 +15524 18835 +97188 68430 +36316 11638 +23469 74803 +30969 33984 +19616 57386 +74603 51560 +73140 52522 +50052 84086 +67225 82400 +82945 39776 +59463 36777 +43724 39776 +38655 36019 +16887 34982 +63076 82400 +57786 92869 +40159 91888 +86882 74877 +30168 74750 +94821 91385 +22335 20714 +14549 74691 +17267 46572 +86022 83923 +40758 83870 +33144 41548 +20281 78088 +87782 14661 +26820 67869 +72492 81368 +92950 55032 +42737 36777 +22360 65185 +61694 67189 +43534 76135 +25697 62054 +65617 70501 +36055 82455 +42978 70973 +69418 29676 +87319 39776 +92611 74554 +45366 50611 +86780 47925 +14580 36676 +60406 24721 +44987 66508 +23481 13654 +89422 77304 +21807 92950 +52893 22984 +70221 76135 +61432 28691 +50739 61410 +69705 10534 +11551 84737 +14653 82947 +84764 70227 +19435 86399 +46702 90481 +59882 66508 +27462 39776 +45303 78835 +41509 75370 +22494 80790 +59433 58283 +19204 20602 +13874 75812 +50130 44169 +68727 83731 +58262 18103 +33787 88584 +28931 50419 +90686 77539 +33865 92950 +57146 59882 +26465 55530 +68279 41051 +77998 92950 +44063 69056 +21928 28982 +18478 83731 +79582 30353 +80695 81630 +25322 71284 +52650 91070 +90146 16859 +74890 66508 +54271 49699 +35728 96535 +15295 88122 +85415 41051 +96077 74836 +71257 31093 +10677 78088 +72271 58494 +50820 64678 +12266 33434 +32264 78179 +59541 64841 +51353 83870 +41310 74853 +62865 15554 +66303 53130 +30556 25580 +27203 66508 +31790 71172 +33932 47324 +43212 88773 +58069 83731 +88235 25580 +41094 99057 +25979 25580 +62261 60853 +79993 23589 +73964 71455 +82400 64678 +65762 18579 +73651 16859 +67581 76135 +30713 14716 +47252 19658 +14691 39961 +40662 12202 +57025 69091 +83266 48400 +30600 79683 +62076 16859 +16881 83870 +65361 63743 +80773 63741 +71794 48591 +65839 66508 +75318 20602 +91238 82391 +45707 64678 +40980 77539 +85661 99057 +59298 29272 +19492 84014 +93934 48400 +15984 64678 +89737 48584 +94738 63640 +36639 52035 +61394 40066 +48772 34199 +18258 74691 +20283 80659 +63972 40629 +82137 59882 +76239 25580 +12349 41106 +75728 64348 +74691 78088 +62001 21680 +70269 34199 +25443 39776 +19584 15829 +30199 87448 +92524 19400 +41674 23116 +63728 44519 +99875 91712 +17735 30851 +67540 81902 +27828 92950 +85889 33984 +39816 37113 +87480 91733 +19469 33984 +62803 12772 +17043 33984 +97479 81159 +91505 45435 +12207 69925 +60626 95997 +68126 92869 +76852 13346 +71419 70109 +49664 42459 +74526 32376 +16446 47891 +23116 39776 +43806 64678 +23988 61719 +97167 92950 +66668 44592 +25225 35154 +14284 14510 +23861 47115 +55048 45238 +33484 60853 +46372 80717 +61795 22743 +73995 44753 +89733 76532 +91399 53238 +53467 20602 +71484 98629 +37974 64678 +73312 99057 +75812 73554 +47324 58729 +14895 92017 +69525 50204 +47032 78088 +90971 72856 +63357 33984 +94931 99057 +11959 73715 +70226 77539 +54005 44541 +38941 48400 +64230 74691 +31008 11797 +47599 55425 +67007 10384 +14054 82455 +22131 22556 +52663 80307 +90266 61207 +76934 33537 +97373 27252 +37507 99057 +95323 86821 +79869 56443 +53249 77539 +62806 14510 +23745 41051 +61452 60853 +97548 19963 +57870 24236 +18763 15129 +85117 39776 +30254 51456 +51491 67525 +93572 77539 +82325 83731 +15877 41056 +98690 11852 +58483 14549 +46792 46579 +19738 32343 +96327 41051 +84003 82455 +58135 99057 +22481 68384 +38401 92272 +44698 30430 +39030 14510 +64037 47324 +70100 84872 +64299 48400 +75003 18219 +74190 19588 +71831 92869 +20635 88403 +28133 39036 +39722 42459 +42378 20602 +31939 75812 +69490 77539 +85822 41051 +99562 93734 +48527 23116 +56404 52393 +44682 26105 +66332 92869 +55356 52743 +13056 18829 +19925 82455 +66686 22256 +48103 99057 +82466 99057 +71384 20602 +56960 36777 +14192 41310 +44212 58300 +71988 92950 +90172 75812 +86104 75812 +58359 98375 +95930 48202 +61264 14510 +85630 74877 +27124 48370 +49572 48140 +48424 77539 +77569 45931 +30308 81159 +26594 40011 +63775 66508 +34220 82947 +46571 47585 +81978 77539 +37668 82947 +51727 66508 +79066 20602 +12567 74691 +47130 12241 +15691 93831 +65408 33984 +15617 82400 +48601 36777 +10561 60853 +97955 41051 +82817 21661 +21081 77539 +50859 33984 +23474 82400 +15893 47324 +48663 98013 +80276 77539 +29558 64989 +98180 99880 +31381 66796 +32510 14549 +47508 15854 +14500 14549 +30226 70501 +10524 92869 +26213 92869 +75481 44753 +39239 53324 +72660 64678 +16154 83870 +84492 41051 +21987 20602 +45236 75576 +36827 57147 +81865 60831 +36531 99057 +77201 70501 +28863 31856 +32410 48400 +62294 53873 +49825 99057 +17226 50273 +36614 34199 +14510 48400 +15818 74691 +41051 27891 +39776 33984 +43740 25580 +61248 97412 +63739 47404 +33984 88105 +64598 81159 +71104 89965 +71399 13250 +22174 20602 +60654 39776 +36993 45136 +81016 74327 +47735 64918 +80903 14510 +87865 39776 +38245 91066 +29883 51319 +52463 23311 +32632 35610 +75507 97544 +57330 65354 +59693 55540 +96123 48400 +15649 92950 +84872 82947 +52036 85576 +56140 65185 +23571 32245 +45230 97874 +49231 50934 +43993 85661 +27831 14510 +59732 83870 +46676 39776 +92968 60853 +66157 28036 +88365 70501 +78552 95048 +30812 39388 +70615 32340 +90718 49637 +55059 43376 +44052 32254 +64928 14510 +49820 82400 +60638 64678 +39415 82391 +17390 82391 +64214 77539 +59411 78901 +13819 33984 +92129 28689 +51618 86239 +24039 42459 +27702 39776 +69110 75948 +58967 84872 +97823 45780 +11609 82400 +54722 82391 +82391 18829 +74051 85569 +24976 75812 +65185 36777 +86919 18888 +39690 82947 +42614 48845 +36554 16859 +29410 99296 +38412 70501 +74218 18829 +49407 90164 +48400 64678 +23114 82947 +27649 78088 +68537 78526 +24479 21094 +47444 99057 +65003 33984 +39426 83535 +90358 51196 +22234 98284 +30880 28789 +32544 82947 +10847 82947 +54047 18829 +52242 32818 +10490 24089 +41618 75977 +35876 14549 +49262 28889 +94438 26726 +51893 75812 +93759 58987 +51981 14510 +60103 71702 +88905 66508 +48747 42459 +96263 75812 +40463 83870 +48597 57204 +22536 44753 +66412 99054 +17790 66120 +77539 25203 +78865 50851 +50309 81159 +17303 35610 +54010 79127 +20241 14510 +63100 92950 +83731 14510 +68951 31982 +56970 82400 +44753 60853 +46362 49519 +67946 60853 +84813 83698 +71665 11245 +30689 66459 +69584 47324 +42706 75812 +52831 78088 +92039 20602 +58831 14549 +20290 41051 +90055 41727 +50084 48967 +23456 27651 +39078 41568 +63877 34199 +99100 83870 +45801 64678 +84659 44834 +11493 25580 +69169 85661 +67297 75310 +13814 88874 +92809 83870 +84504 44970 +18829 39776 +32708 83870 +55821 81159 +33006 82400 +73062 16859 +19055 99551 +78888 33984 +19620 36962 +35643 84872 +36777 74691 +81225 41051 +11880 96744 +58979 11943 +22530 25580 +61936 72308 +50817 85661 +33683 82947 +38394 67535 +78267 50808 +90229 95996 +76219 47324 +24324 40775 +64552 77539 +50492 24650 +75184 37186 +72456 98388 +65577 28564 +74502 42459 +70395 70501 +45032 12987 +71299 82400 +39462 59882 +90600 62577 +47384 74691 +13946 81159 +72317 58599 +15940 38852 +10917 33984 +35057 70501 +62360 55948 +78591 36777 +92380 95224 +80300 25360 +74967 47844 +33642 32775 +67167 29873 +84766 31938 +54914 18149 +12612 60853 +51871 78088 +52446 11322 +45850 99057 +86339 20388 +92007 92950 +50584 55255 +74877 83870 +70625 36777 +59262 76788 +88734 74877 +54461 99057 +53614 20602 +97695 92442 +95664 74877 +26474 63443 +40271 66508 +46223 27041 +95183 18367 +23141 76135 +90287 82391 +86387 74877 +59164 63318 +96424 13830 +46986 50003 +14676 98418 +16897 75812 +93799 83870 +26152 14783 +73164 35799 +83870 74691 +69539 25580 +37270 25580 +22633 66508 +95442 35703 +60229 92950 +68469 74691 +32827 95745 +54254 66508 +19421 30678 +83601 37175 +48236 33984 +35864 92869 +12715 91646 +37578 49676 +52157 28386 +89788 39266 +55235 50669 +77355 33641 +92895 48400 +90314 82391 +89697 29794 +78864 81204 +74210 71372 +19120 45857 +50876 30101 +59106 92950 +19702 25499 +97014 91896 +74875 16783 +13073 84306 +26041 83870 +68942 88484 +40578 83731 +72258 65004 +92705 83870 +86757 59882 +98431 76644 +26967 82947 +16928 37207 +35610 15275 +78099 66508 +18168 48400 +58016 48400 +81932 93264 +49522 70501 +46342 99057 +78434 34199 +57459 93096 +99686 37409 +45420 15677 +65862 61547 +68451 32852 +62057 20602 +54187 53430 +41398 43131 +81637 25396 +10157 93885 +66508 12152 +10450 84872 +25261 20602 +56274 63730 +72119 95604 +46569 75812 +35380 42970 +43443 92950 +39631 52734 +42459 45026 +96567 34884 +93222 62504 +60053 71698 +75897 47324 +48328 20602 +99057 48400 +35826 82341 +67035 82400 +58053 86856 +81936 12257 +68310 14510 +29468 62020 +81781 67379 +15436 14549 +56095 65185 +66163 10638 +49425 14510 +68972 92950 +49574 14549 +38234 83870 +28540 84872 +81462 48400 +41295 34199 +80808 91315 +28524 33984 +77949 74691 +99083 20602 +62026 42459 +31125 48400 +79195 63833 +42400 74725 +13187 57183 +28716 77539 +80819 92964 +95678 39668 +54023 39776 +59766 42459 +71124 13499 +68339 49253 +61897 46696 +80221 11294 +35387 98184 +68473 39786 +35763 73269 +65760 20385 +89259 47268 +14170 77539 +35101 85211 +18374 83870 +92328 85661 +82839 78903 +18361 33984 +23227 74691 +95071 64678 +90966 82947 +95801 77539 +81159 64755 +65256 70501 +55147 13543 +15387 99057 +35642 82400 +32240 27515 +67866 14549 +12086 49665 +36184 84872 +15635 31890 +10214 40993 +49134 77539 +62743 48400 +44489 70501 +80178 68714 +36457 78753 +17887 84293 +16849 67107 +63559 77539 +80694 52080 +58142 78088 +18872 14510 +12338 67478 +85829 40208 +66792 84872 +61928 93693 +33263 17549 +84614 81847 +61330 48400 +68335 20602 +29181 60853 +74548 75771 +30127 15911 +47115 26923 +91933 35610 +83734 84584 +44683 89834 +41249 78088 +80290 48400 +96903 79098 +70501 82561 +32022 63239 +69817 24120 +90313 78614 +70861 42934 +58151 47251 +28667 55887 +22841 34199 +73857 71309 +16835 14899 +95850 34199 +50640 51985 +18035 47324 +37594 50221 +16970 71726 +25362 15286 +44543 18995 +83609 45774 +89691 84872 +50795 70501 +24679 48469 +71908 82947 +67185 38287 +18054 35390 +34199 69184 +40616 75812 +20602 94728 +49793 82400 +14963 24258 +60662 74691 +86403 43539 +74430 66236 +77078 39136 +87428 82947 +77070 54393 +70944 42459 +12653 18130 +81773 25580 +49019 17153 +82455 31077 +25942 64678 +26835 91201 +39062 80768 +81313 27193 +45192 77539 +15593 37923 +56100 28304 +82947 38124 +88630 40195 +52146 10487 +85442 23549 +99766 23732 +16859 25580 +21961 24033 +76135 30552 +17662 77266 +52907 28266 +98310 14512 +52835 17260 +41921 99977 +98536 79658 +14361 75812 +33091 85661 +98222 76135 +21436 89453 +38710 11479 +82047 68962 +35897 14592 +88326 74877 +46035 99057 +78652 97213 +44755 20602 +96573 47324 +36653 46767 +70603 26820 +61979 76005 +21272 39776 +78088 81081 +34305 33984 +35661 10012 +61006 47115 +93440 41051 +21321 98330 +75070 16859 +95372 70501 +38869 60853 +76195 78088 +14557 46481 +42861 86390 +57044 34199 +68752 33984 +86232 67003 +27620 76135 +55091 37530 +29965 41051 +33771 84872 +58339 66508 +12708 75812 +72653 92869 +84021 10337 +87356 82391 +74653 92950 +92234 47324 +50621 33984 +42267 64801 +22400 42459 +24231 79555 +58301 84563 +80962 99057 +71109 14549 +65386 46911 +26148 43854 +38755 82400 +75344 98637 +25436 14549 +64378 97144 +62564 94652 +10638 16859 +38487 36777 +73552 66508 +91379 34199 +22001 14549 +56967 13015 +98527 38329 +41766 38964 +10762 75812 +15598 25580 +42586 16859 +51351 32233 +59322 66508 +98442 10520 +15717 73514 +20342 72228 +13498 75812 \ No newline at end of file diff --git a/input/day1_example.txt b/input/day1_example.txt new file mode 100644 index 0000000..dfca0b1 --- /dev/null +++ b/input/day1_example.txt @@ -0,0 +1,6 @@ +3 4 +4 3 +2 5 +1 3 +3 9 +3 3 \ No newline at end of file diff --git a/src/day1.rs b/src/day1.rs new file mode 100644 index 0000000..924386a --- /dev/null +++ b/src/day1.rs @@ -0,0 +1,59 @@ +use std::arch::x86_64::_addcarryx_u32; +use itertools::Itertools; +use crate::day_solver::DaySolver; +#[cfg(test)] +use crate::util::read_file; + +pub struct Day1 { + list1: Vec, + list2: Vec, +} + +impl Day1 { + + pub fn create(input: String) -> Self { + let lines = input.lines() + .map(|l| l.split_whitespace().map(|n| n.parse().unwrap()).collect()) + .collect::>>(); + + let list1 = lines.iter().map(|l| l[0]).collect(); + let list2 = lines.iter().map(|l| l[1]).collect(); + + // Put the input into the day struct + Day1 { + list1, list2 + } + } + + fn sort_list(list: &[u32]) -> Vec { + list.iter().sorted().map(|n| n.to_owned()).collect::>() + } +} + +impl DaySolver for Day1 { + + + fn solve_part1(&mut self) -> String { + let list1_sorted = Day1::sort_list(&self.list1); + let list2_sorted = Day1::sort_list(&self.list2); + (0..list1_sorted.len()).map(|i| u32::abs_diff(list1_sorted[i], list2_sorted[i])) + .sum::().to_string() + } + + fn solve_part2(&mut self) -> String { + self.list1.iter().map(|n1| self.list2.iter().filter(|n2| n1.eq(n2)).count() as u32 * n1) + .sum::().to_string() + } +} + +#[test] +fn test_part1() { + let mut day = Day1::create(read_file("input/day1_example.txt")); + assert_eq!("11", day.solve_part1()); +} + +#[test] +fn test_part2() { + let mut day = Day1::create(read_file("input/day1_example.txt")); + assert_eq!("31", day.solve_part2()); +} diff --git a/src/dayX.rs b/src/dayX.rs new file mode 100644 index 0000000..da92c96 --- /dev/null +++ b/src/dayX.rs @@ -0,0 +1,40 @@ +use crate::day_solver::DaySolver; +#[cfg(test)] +use crate::util::read_file; + +pub struct DayX { +} + +impl DayX { + + pub fn create(input: String) -> Self { + // let lines = input.lines(); + + // Put the input into the day struct + return DayX {} + } +} + +impl DaySolver for DayX { + + + fn solve_part1(&mut self) -> String { + return 0.to_string(); + } + + fn solve_part2(&mut self) -> String { + return 0.to_string(); + } +} + +#[test] +fn test_part1() { + let mut day = DayX::create(read_file("input/dayX_example.txt")); + assert_eq!("EXAMPLE_ANSWER", day.solve_part1()); +} + +#[test] +fn test_part2() { + let mut day = DayX::create(read_file("input/dayX_example.txt")); + assert_eq!("EXAMPLE_ANSWER", day.solve_part2()); +} diff --git a/src/day_solver.rs b/src/day_solver.rs new file mode 100644 index 0000000..bfac4f2 --- /dev/null +++ b/src/day_solver.rs @@ -0,0 +1,6 @@ + +pub trait DaySolver { + // fn create() -> Self; + fn solve_part1(&mut self) -> String; + fn solve_part2(&mut self) -> String; +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..67e0647 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,192 @@ +extern crate core; + +use std::time::Instant; +use crate::day1::Day1; +use crate::day_solver::DaySolver; +use crate::util::read_file; + +mod util; +mod day_solver; +mod day1; + +const DEFAULT_BENCHMARK_AMOUNT: u32 = 100; + +fn main() { + + let args: Vec = std::env::args().collect(); + + let day_arg_idx = args.iter().position(|a| a == "-d"); + let single_day = day_arg_idx.is_some(); + let day = if single_day { args[day_arg_idx.unwrap() + 1].parse::().unwrap() } else { 0 }; + + let benchmark_arg_idx_option = args.iter().position(|a| a == "--bench").or( + args.iter().position(|a| a == "-b")); + + let benchmark = benchmark_arg_idx_option.is_some(); + let bench_amount: u32 = if let Some(benchmark_arg_idx) = benchmark_arg_idx_option { + args.get(benchmark_arg_idx + 1) + .map_or(DEFAULT_BENCHMARK_AMOUNT, |r| r.parse::().unwrap_or(DEFAULT_BENCHMARK_AMOUNT)) + } else { + DEFAULT_BENCHMARK_AMOUNT + }; + + let mut bench_results: Vec = Vec::new(); + + // This is essentially the warmup for the benchmark: + run_once(single_day, day, false, &mut bench_results); + let first_run_bench = bench_results[0].to_owned(); + + let (_, total_time) = bench(|| + if benchmark { + // Ignore the warmup run in the rest of the benchmark: + bench_results.clear(); + + for _ in 0..bench_amount { + run_once(single_day, day, true, &mut bench_results); + } + }); + + if benchmark { + + println!("Executed {} rounds in {:.3} s ({} μs, or {} μs on average per round)", bench_results.len(), total_time as f64 / 1000000f64, total_time, total_time / bench_amount as u128); + print_bench_result(&bench_results, |b| b.total, "Execution"); + print_bench_result(&bench_results, |b| b.read_file, "Reading file"); + print_bench_result(&bench_results, |b| b.init, "Initialization"); + print_bench_result(&bench_results, |b| b.part1, "Part 1"); + print_bench_result(&bench_results, |b| b.part2, "Part 2"); + print_bench_result(&bench_results, |b| b.part1 + b.part2, "Part 1 & 2 together"); + println!("First time took {} μs (read {} μs, init {} μs, part 1: {} μs, part 2: {} μs)", first_run_bench.total, first_run_bench.read_file, first_run_bench.init, first_run_bench.part1, first_run_bench.part2); + println!("Average: {} μs (read {} μs, init {} μs, part 1: {} μs, part 2: {} μs)", + avg_bench(&bench_results, |b| b.total), + avg_bench(&bench_results, |b| b.read_file), + avg_bench(&bench_results, |b| b.init), + avg_bench(&bench_results, |b| b.part1), + avg_bench(&bench_results, |b| b.part2)); + } else { + println!("Execution took {} μs (read {} μs, init {} μs, part 1: {} μs, part 2: {} μs)", first_run_bench.total, first_run_bench.read_file, first_run_bench.init, first_run_bench.part1, first_run_bench.part2); + } +} + +#[derive(Copy, Clone)] +struct AocBenchResult { + read_file: u128, + init: u128, + part1: u128, + part2: u128, + total: u128 +} + +fn build_day_solver(day: u8, input: String) -> Option> { + + match day { + 1 => Some(Box::new(Day1::create(input))), + // 2 => Some(Box::new(Day2::create(input))), + // 3 => Some(Box::new(Day3::create(input))), + // 4 => Some(Box::new(Day4::create(input))), + // 5 => Some(Box::new(Day5::create(input))), + // 6 => Some(Box::new(Day6::create(input))), + // 7 => Some(Box::new(Day7::create(input))), + // 8 => Some(Box::new(Day8::create(input))), + // 9 => Some(Box::new(Day9::create(input))), + // 10 => Some(Box::new(Day10::create(input))), + // 11 => Some(Box::new(Day11::create(input))), + // 12 => Some(Box::new(Day12::create(input))), + _ => None + } +} + +fn solve(day: u8, silent: bool) -> AocBenchResult { + + let now = Instant::now(); + + let (input, read_file_time) = bench(|| { + let input_filename = format!("input/day{:02}.txt",day); + read_file(&input_filename) + }); + + let (solver, init_time) = bench(|| build_day_solver(day, input.to_owned())); + + let part1_time: u128; + let part2_time: u128; + match solver { + Some(mut s) => { + + let(part1, pt1_time) = bench(|| s.solve_part1()); + part1_time = pt1_time; + + if !silent { + println!("Day {} Part 1: {}", day, part1); + } + let (part2, pt2_time) = bench(|| s.solve_part2()); + part2_time = pt2_time; + if !silent { + println!("Day {} Part 2: {}", day, part2); + } + }, + None => panic!("This day is not yet implemented") + } + + AocBenchResult{ + read_file: read_file_time, + init: init_time, + part1: part1_time, + part2: part2_time, + total: now.elapsed().as_micros() + } + +} + + +fn print_bench_result(bench_results: &[AocBenchResult], f: F, bench_part_description: &str) + where + F: FnMut(&AocBenchResult) -> u128 { + + let mut benches: Vec = bench_results.iter().map(f).collect(); + benches.sort(); + let avg_runtime: u128 = benches.iter().sum::() / (bench_results.len() as u128); + + println!("{} took {} μs {} (Min: {} μs, Max: {} μs, Median: {} μs)", bench_part_description, avg_runtime, if bench_results.len() > 1 { "on average"} else {""}, + benches[0], benches[benches.len() - 1], benches[benches.len() / 2]) +} + +fn avg_bench(bench_results: &[AocBenchResult], f: F) -> u128 + where + F: FnMut(&AocBenchResult) -> u128 { + + let benches: Vec = bench_results.iter().map(f).collect(); + return benches.iter().sum::() / (bench_results.len() as u128) +} + +fn run_once(single_day: bool, day: u8, silent: bool, bench_results: &mut Vec) { + + + let bench_result = if single_day { + solve(day, silent) + } else { + solve_all(silent) + }; + bench_results.push(bench_result); +} + +fn solve_all(silent: bool) -> AocBenchResult { + let mut bench_results = Vec::new(); + let max_day = (1..).take_while(|d| build_day_solver(*d, "".to_string()).is_some()).last().unwrap(); + for day in 1..(max_day + 1) { + bench_results.push(solve(day, silent)); + } + return AocBenchResult { + read_file: bench_results.iter().map(|t| t.read_file).sum(), + init: bench_results.iter().map(|t| t.init).sum(), + part1: bench_results.iter().map(|t| t.part1).sum(), + part2: bench_results.iter().map(|t| t.part2).sum(), + total: bench_results.iter().map(|t| t.total).sum(), + } + +} + +fn bench(mut f: F) -> (K, u128) + where F: FnMut() -> K { + let now = Instant::now(); + let res = f(); + (res, now.elapsed().as_micros()) +} \ No newline at end of file diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..edd4194 --- /dev/null +++ b/src/util.rs @@ -0,0 +1,181 @@ +use std::fmt::Display; +use std::fs; + +use itertools::Itertools; +use num::Integer; + +pub fn read_file(filename: &str) -> String { + fs::read_to_string(filename) + .expect("Couldn't read file!") +} + +#[allow(dead_code)] +pub fn into_lines(input: String) -> Vec { + input.lines().map(|l| l.to_owned()).collect() +} + + + +#[derive(Debug, Clone)] +pub struct Grid { + pub(crate) width: usize, + pub(crate) data: Vec, + /** What to return if a coordinate that is out of bounds is requested */ + pub(crate) default: Option +} + +impl Grid { + + #[allow(dead_code)] + pub fn set_row(&mut self, y: usize, v: T) { + // let range = &mut self.data[x * self.width..(x+1) * self.width]; + for i in self.width * y..self.width * (y + 1) { + self.data[i] = v.to_owned(); + } + } + + #[allow(dead_code)] + pub fn set_col(&mut self, x: usize, v: T) { + for y in 0..self.height() { + let idx = self.idx(&x, &y); + self.data[idx] = v.to_owned(); + } + } + + pub(crate) fn idx(&self, x: &usize, y: &usize) -> usize { + y * self.width + x + } + + pub(crate) fn coord(&self, i: usize) -> Coord { + Coord::new(i % self.width, i / self.width) + } + + pub(crate) fn height(&self) -> usize { + self.data.len() / self.width + } + + pub(crate) fn get(&self, x: &usize, y: &usize) -> &T { + if self.in_bounds(x, y) { + let idx = self.idx(x, y); + &self.data[idx] + } else if let Some(x) = &self.default { + return x; + } else { + panic!("Out of grid bounds: {}, {}", x, y); + } + } + + #[allow(dead_code)] + pub fn set(&mut self, x: &usize, y: &usize, v: T) { + let idx = self.idx(x, y); + self.data[idx] = v; + } + + pub fn in_bounds(&self, x: &usize, y: &usize) -> bool { + return x < &self.width && y < &self.height() + } + + pub fn find_positions<'a, P>(&'a self, predicate: &'a P) -> impl Iterator> + 'a + where P: Fn(&'a T) -> bool + 'a { + + return self.data.iter().enumerate() + .filter(|(_,x)| predicate(x).to_owned()) + .map(|(i, _)| self.coord(i)); + } + + pub fn validate(&self) { + debug_assert!(&self.data.len() % self.width == 0) + } +} + +impl Grid { + + #[allow(dead_code)] + pub fn print(&self) { + + self.print_range(0, self.width, 0, self.height()); + } + + #[allow(dead_code)] + pub fn print_range(&self, from_x: usize, to_x: usize, from_y: usize, to_y: usize) { + + for y in from_y.max(0)..to_y.min(self.height()) { + for x in from_x.max(0)..to_x.min(self.width) { + print!("{}", self.get(&x, &y)) + } + println!(); + } + } +} + +impl Grid { + + pub fn find(&self, v: &T) -> Option> { + return if let Some((i, _)) = self.data.iter().find_position(|x| x == &v) { + return Some(Coord::new(i % self.width, i / self.width)) + } else { + None + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct Coord where T: Sized { + pub x: T, + pub y: T +} + + +#[allow(dead_code)] +impl Coord where T: Sized { + pub(crate) fn new(x: T, y: T) -> Self { + Coord { x, y } + } +} + +#[allow(dead_code)] +impl Coord where T: Integer + Copy { + pub fn manhattan_dist(&self, other: &Coord) -> T { + self.x.max(other.x).sub(self.x.min(other.x)) + self.y.max(other.y).sub(self.y.min(other.y)) + } +} + +#[allow(dead_code)] +impl Coord { + pub fn north(&self) -> Option> { + if self.y == 0 { return None } + return Some(Coord::new(self.x, self.y - 1)); + } + + pub fn south(&self) -> Option> { + return Some(Coord::new(self.x, self.y + 1)); + } + + pub fn east(&self) -> Option> { + return Some(Coord::new(self.x + 1, self.y)); + } + + pub fn west(&self) -> Option> { + if self.x == 0 { return None } + return Some(Coord::new(self.x - 1, self.y)); + } + + pub fn compass(&self) -> Vec> { + + let mut res = Vec::with_capacity(4); + if let Some(north) = self.north() { + res.push(north); + } + if let Some(south) = self.south() { + res.push(south); + } + if let Some(east) = self.east() { + res.push(east); + } + if let Some(west) = self.west() { + res.push(west); + } + + res + } +}