commit 4d06281fd272855b144e3852f2b66444b0cdc155
Author: Ethan Long <ethandavidlong@gmail.com>
Date: Sun, 1 Dec 2024 23:50:58 +1100
Initial commit with day 1 complete.
Pretty easy day, though I've definitely overcomplicated this.
Diffstat:
8 files changed, 1369 insertions(+), 0 deletions(-)
diff --git a/LICENSE b/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2024 Ethan Long
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/aoc2024.cabal b/aoc2024.cabal
@@ -0,0 +1,132 @@
+cabal-version: 3.4
+-- The cabal-version field refers to the version of the .cabal specification,
+-- and can be different from the cabal-install (the tool) version and the
+-- Cabal (the library) version you are using. As such, the Cabal (the library)
+-- version used must be equal or greater than the version stated in this field.
+-- Starting from the specification version 2.2, the cabal-version field must be
+-- the first thing in the cabal file.
+
+-- Initial package description 'aoc2024' generated by
+-- 'cabal init'. For further documentation, see:
+-- http://haskell.org/cabal/users-guide/
+--
+-- The name of the package.
+name: aoc2024
+
+-- The package version.
+-- See the Haskell package versioning policy (PVP) for standards
+-- guiding when and how versions should be incremented.
+-- https://pvp.haskell.org
+-- PVP summary: +-+------- breaking API changes
+-- | | +----- non-breaking API additions
+-- | | | +--- code changes with no API change
+version: 0.1.0.0
+
+-- A short (one-line) description of the package.
+-- synopsis:
+
+-- A longer description of the package.
+-- description:
+
+-- The license under which the package is released.
+license: MIT
+
+-- The file containing the license text.
+license-file: LICENSE
+
+-- The package author(s).
+author: Ethan Long
+
+-- An email address to which users can send suggestions, bug reports, and patches.
+maintainer: ethandavidlong@gmail.com
+
+-- A copyright notice.
+-- copyright:
+category: Advent of Code Challenge 2024
+build-type: Simple
+
+-- Extra doc files to be distributed with the package, such as a CHANGELOG or a README.
+extra-doc-files: CHANGELOG.md
+
+-- Extra source files to be distributed with the package, such as examples, or a tutorial module.
+-- extra-source-files:
+
+common warnings
+ ghc-options: -Wall
+
+library
+ -- Import common warning flags.
+ import: warnings
+
+ -- Modules exported by the library.
+ exposed-modules:
+ Solutions
+
+ -- Modules included in this library but not exported.
+ other-modules:
+ Utils
+ Day1
+
+ -- LANGUAGE extensions used by modules in this package.
+ -- other-extensions:
+
+ -- Other library packages from which modules are imported.
+ build-depends: base ^>=4.19.0.0
+
+ -- Directories containing source files.
+ hs-source-dirs: src
+
+ -- Base language which the package is written in.
+ default-language: GHC2021
+
+executable aoc2024
+ -- Import common warning flags.
+ import: warnings
+
+ -- .hs or .lhs file containing the Main module.
+ main-is: Main.hs
+
+ -- Modules included in this executable, other than Main.
+ -- other-modules:
+
+ -- LANGUAGE extensions used by modules in this package.
+ -- other-extensions:
+
+ -- Other library packages from which modules are imported.
+ build-depends:
+ base ^>=4.19.0.0,
+ aoc2024
+
+ -- Directories containing source files.
+ hs-source-dirs: app
+
+ -- Base language which the package is written in.
+ default-language: GHC2021
+
+test-suite aoc2024-test
+ -- Import common warning flags.
+ import: warnings
+
+ -- Base language which the package is written in.
+ default-language: GHC2021
+
+ -- Modules included in this executable, other than Main.
+ -- other-modules:
+
+ -- LANGUAGE extensions used by modules in this package.
+ -- other-extensions:
+
+ -- The interface type and version of the test suite.
+ type: exitcode-stdio-1.0
+
+ -- Directories containing source files.
+ hs-source-dirs: test
+
+ -- The entrypoint to the test suite.
+ main-is: Main.hs
+
+ -- Test dependencies.
+ build-depends:
+ base ^>=4.19.0.0,
+ aoc2024,
+ doctest
diff --git a/app/Main.hs b/app/Main.hs
@@ -0,0 +1,17 @@
+module Main where
+
+import Text.Printf (printf)
+
+import Solutions (solutions, SolType)
+
+runSolutions :: [(Integer, IO (SolType, SolType))] -> IO ()
+runSolutions ((num, fun) : sols) = do
+ printf "Running day %d:\n" num
+ (sol1, sol2) <- fun
+ printf "Solution for part 1: %s\n" (show sol1)
+ printf "Solution for part 2: %s\n" (show sol2)
+ runSolutions sols
+runSolutions [] = putStrLn "Done!"
+
+main :: IO ()
+main = runSolutions solutions
diff --git a/inputs/day1 b/inputs/day1
@@ -0,0 +1,1000 @@
+19394 30201
+88523 40612
+60736 82993
+75224 92188
+78157 27314
+40925 54647
+86284 23731
+28269 14815
+95540 16406
+48998 59590
+30875 22128
+39762 70353
+90841 51911
+72017 77153
+90563 12816
+97482 68004
+41285 32178
+10561 31048
+55289 51911
+58094 14440
+25799 18533
+39530 88299
+26398 56543
+84654 62539
+17891 55936
+49607 98934
+77920 33887
+63548 68649
+49452 45428
+10623 68630
+44369 79502
+24171 42203
+23836 54647
+35024 97148
+53006 14515
+17908 12813
+96110 45282
+21260 31585
+19069 68649
+50462 59959
+58898 80858
+63205 27250
+68401 14973
+13938 96725
+97309 16113
+79019 22128
+80069 51105
+62881 31929
+93649 28456
+62227 87150
+67133 38055
+22177 28210
+70120 41359
+65463 22128
+20788 53022
+16101 93317
+88771 80239
+17935 96253
+39580 59590
+13624 14515
+39315 81433
+87396 39312
+39438 36516
+19555 37518
+12294 73072
+39136 39440
+68137 38055
+64762 54647
+11693 39768
+27873 21222
+74977 22128
+65309 37518
+99968 93649
+73977 51911
+38300 69694
+69852 18529
+65284 42203
+43782 30201
+74032 80207
+37820 68004
+39747 42203
+85435 18611
+13406 52826
+49130 98817
+52354 55049
+92149 43275
+36943 93096
+12471 50411
+60136 24044
+44887 12366
+87542 84432
+46184 30378
+49717 55951
+96962 43275
+34123 51911
+51911 22128
+29657 16830
+78653 14100
+59461 38055
+29224 38218
+36439 68630
+13523 39762
+90606 38055
+25442 34772
+81801 16055
+23207 10144
+47997 99304
+98666 78425
+79422 62539
+93922 16723
+55628 61077
+89976 79887
+86134 46710
+66713 69568
+70140 97593
+44831 34608
+94934 44979
+51449 36022
+69165 18010
+69254 68649
+23289 15723
+25055 39762
+14060 43275
+55286 15464
+37866 38055
+41143 36251
+82404 43275
+64498 10231
+19413 77772
+91738 36203
+98188 68649
+18533 22128
+26451 14515
+27689 18533
+63800 28677
+51092 84147
+33392 95229
+61939 29850
+93244 63867
+69356 44901
+30830 68630
+73378 22118
+54810 98128
+60906 89093
+64786 49722
+73954 68004
+51826 64510
+45477 17137
+39832 19305
+39313 77094
+87150 62539
+24195 19958
+60222 55319
+53575 18533
+12726 80970
+70517 95031
+89448 52996
+94123 17400
+33021 58607
+12660 49866
+38086 13197
+47154 55140
+62889 68004
+26260 79122
+62539 27869
+10837 68630
+32785 80193
+61750 83026
+48843 16021
+23001 86838
+78135 38055
+46469 70018
+92523 24044
+77332 48312
+88022 59590
+69886 63430
+76828 99616
+30411 68630
+37813 44203
+58166 68004
+11224 90390
+47464 89093
+44093 68004
+18663 94925
+67651 92188
+82915 68004
+84939 72354
+93163 47611
+35337 80589
+31836 41400
+83607 54647
+27234 28677
+17611 17933
+45939 42203
+44136 88447
+24980 76214
+64751 83636
+82530 59590
+83164 96240
+52225 71708
+39901 56044
+68629 54625
+41761 39768
+84332 39762
+56294 22128
+88603 30201
+34147 80858
+70748 54647
+83432 42203
+61677 53864
+55026 29850
+45757 39762
+53241 93649
+31385 37518
+56659 92510
+60236 13326
+65487 22847
+57628 29627
+38867 28677
+61389 81881
+52190 28677
+73770 21680
+28535 28677
+72684 93649
+68234 51911
+70718 61655
+57893 14515
+87278 88350
+99048 38055
+85431 14513
+21498 38055
+11733 75489
+29786 14018
+83685 28535
+84668 28677
+96742 46929
+83192 93649
+14291 80858
+15967 70441
+40857 33823
+37360 24044
+28437 87500
+81625 87150
+10670 25629
+39088 59590
+79068 70485
+86163 92549
+16356 57690
+77035 34542
+95893 30201
+68524 12245
+67206 44145
+61332 70163
+18337 20493
+93390 23528
+54333 28535
+71139 68630
+38055 68004
+68004 38055
+77905 75926
+47611 25005
+79842 25140
+13662 24044
+53745 68004
+41222 51558
+52076 81725
+15371 68630
+23306 93649
+29817 62872
+93289 39762
+22128 20318
+38431 89215
+23505 14273
+28107 58177
+86820 68059
+26522 92188
+50144 92577
+82874 12814
+66228 43275
+80001 51911
+42537 38055
+39967 43275
+85939 62539
+65039 58483
+20791 26022
+13246 71961
+29704 51911
+37362 28677
+52727 46073
+56123 51911
+31682 80858
+99721 80046
+11915 22128
+78695 37518
+37842 63797
+33522 18533
+42425 66307
+61796 22896
+18581 19401
+85444 99628
+79723 44667
+32198 99245
+61485 68649
+25570 81282
+59494 49927
+31201 28027
+20105 62342
+68086 24044
+99087 94172
+69972 57265
+62874 85761
+76958 86675
+15510 32803
+32628 75816
+98849 14515
+57502 74495
+99195 25898
+71072 55730
+70180 54871
+90411 60473
+17690 53384
+72498 20928
+62472 37518
+23478 59585
+21680 17400
+64962 92188
+67171 38817
+87749 88305
+96550 31707
+34827 37518
+14965 28677
+81400 37518
+28022 68630
+65594 84915
+61051 14515
+37268 22708
+42755 36626
+90944 68004
+14515 62539
+78631 59726
+83844 21457
+47511 35413
+63833 74936
+27770 46589
+63009 62539
+58607 32317
+72299 58657
+98414 68649
+59427 46701
+42920 37518
+42943 34608
+76950 81768
+66370 95413
+62072 68649
+69498 21093
+38482 80380
+90604 89093
+79371 93649
+24310 29039
+84526 43555
+28190 77592
+42959 25808
+62789 65719
+96930 62539
+17482 83419
+36117 13993
+87059 68630
+21860 84317
+66292 18533
+72327 54647
+32333 80858
+95478 92598
+40395 20333
+23169 68649
+46662 34608
+27483 49185
+14770 28677
+30201 54647
+81414 33531
+71539 68004
+18733 97799
+71233 72190
+23912 11930
+72646 59590
+80943 24568
+53771 34976
+25524 83036
+71583 94321
+68782 83197
+92398 93066
+18717 34608
+71309 17400
+66027 21680
+92188 20493
+52654 18533
+41484 57624
+74536 39762
+34402 41766
+65396 46662
+64587 54185
+73313 20493
+64781 72433
+40433 51135
+15383 80240
+53862 92188
+18251 57427
+92391 61937
+42843 92188
+30265 10605
+70472 91659
+11115 38423
+38743 68649
+29204 27470
+89512 14515
+47347 37341
+35918 91685
+35111 12245
+87122 12864
+62610 18533
+69117 39762
+34608 90733
+68159 47235
+44645 62103
+11360 55339
+98841 54077
+68166 93649
+30855 40539
+34886 53682
+19259 20845
+49446 62103
+28770 85627
+69727 46662
+19805 35760
+13092 22128
+21397 22128
+79152 54647
+68649 10146
+95088 94375
+38088 53889
+34497 57303
+36209 35946
+30822 14481
+23427 65318
+18266 93649
+42203 37288
+86082 73722
+31027 51911
+41998 92188
+15099 14515
+11613 25759
+59774 40495
+38313 39768
+73717 99304
+98902 40528
+99167 10317
+41435 61425
+15042 67261
+78981 78425
+76225 83595
+67283 22175
+84631 93649
+61343 28178
+12940 24044
+57352 92188
+73255 82693
+65000 64876
+79110 12189
+55163 93265
+36832 99304
+92421 78808
+24862 22772
+13598 50315
+76781 67526
+64986 89093
+48307 14515
+30499 81298
+18397 72464
+44296 37518
+53975 18611
+46262 24044
+28139 37518
+49533 38055
+93528 24044
+13765 92179
+72839 79453
+90780 21608
+69774 54647
+45153 46074
+83124 17400
+91418 40532
+70779 80858
+78588 78914
+96799 87616
+17454 65856
+39594 42203
+96631 21680
+62254 28677
+32818 42203
+63705 43275
+78591 78425
+39160 78425
+75105 63469
+91888 28677
+64917 39762
+79697 93649
+23416 73388
+69209 38517
+86468 15028
+87174 93649
+21197 42042
+83503 62539
+46243 64759
+83425 42203
+64091 59590
+82387 38055
+72432 61526
+68423 44628
+63036 34059
+46945 69634
+92178 23198
+92475 24044
+71265 17669
+22466 93938
+78425 33739
+84989 67532
+59915 24044
+62251 76757
+25112 18533
+78278 78229
+27294 94970
+49019 56614
+21504 43275
+11920 20613
+33923 78425
+45471 46569
+59325 93446
+80028 18533
+25706 18482
+81065 54169
+14435 59686
+20330 39762
+51339 31931
+72276 68004
+83903 38055
+80068 14515
+66905 42203
+79932 57636
+19408 21680
+83911 99103
+84717 46260
+35764 31880
+91958 38055
+12711 89093
+61725 95957
+39768 29557
+86115 18533
+17195 99304
+99304 46662
+95620 75784
+23299 51888
+70384 94672
+95974 37909
+19983 64539
+30328 43275
+93287 67609
+29850 93226
+71063 88634
+87005 58583
+13402 28677
+16810 20493
+53126 43275
+87495 53455
+59241 22128
+38729 36581
+97527 22250
+54481 87922
+53294 41392
+99814 43405
+52458 64149
+97173 28535
+90268 65954
+15958 96885
+27539 94140
+75668 53320
+92730 76721
+54793 64662
+20493 43955
+38749 26031
+63488 67792
+69715 74163
+99423 25406
+13503 92188
+37032 74091
+82994 87542
+95113 23287
+82341 14082
+47782 68649
+19392 68109
+58145 34558
+11367 37518
+24090 93649
+74367 51289
+58821 67880
+84758 49564
+41324 43221
+63755 12136
+18456 92213
+43908 15825
+76789 99304
+13654 28677
+92979 67378
+45134 55863
+39852 28677
+55066 47477
+53972 28677
+35205 57113
+34894 37518
+93606 39762
+45212 68223
+71473 76746
+77246 49748
+72899 39768
+39506 30201
+13959 92188
+56571 96952
+68789 89676
+29980 21680
+82077 30201
+95915 49831
+31832 97611
+79076 92188
+47570 12245
+21058 62539
+19787 19635
+36452 37518
+24331 83335
+35181 30201
+65847 93322
+28677 38055
+30918 21680
+71808 47589
+78490 89093
+50658 46493
+84525 30201
+92052 28677
+35798 29805
+67640 78425
+28644 68649
+79569 28677
+55849 64863
+60737 54647
+78807 49913
+49986 38055
+61356 68004
+85575 14515
+43531 86349
+53843 22835
+92048 98829
+18275 42231
+59311 59590
+63750 93503
+77779 51911
+26196 49215
+65202 22128
+54245 71063
+60651 54736
+12795 24044
+12691 52335
+14868 76240
+57009 93649
+22924 86143
+46880 83204
+44046 54647
+88721 81171
+62559 60554
+16394 14138
+82812 51911
+91964 89572
+24111 75105
+54143 39762
+96970 95647
+65895 92157
+90345 79560
+11847 78425
+26002 32659
+15535 44103
+33281 68649
+54737 43275
+75392 93649
+43098 24044
+41574 29446
+87423 22128
+76419 75360
+65498 76890
+10938 28677
+45987 14515
+54998 26279
+37518 26076
+23092 89093
+56921 60094
+84101 18301
+23120 99304
+53441 80129
+10525 56782
+43726 40686
+61391 24829
+68630 91104
+62125 43275
+53111 90283
+39402 16948
+51205 34608
+58826 61814
+99060 75190
+35880 98594
+92110 50013
+65717 52474
+30095 63994
+51486 39762
+67902 84259
+18402 58434
+29938 17400
+18611 25182
+85078 33378
+64358 32171
+92243 68919
+22205 16964
+78191 75823
+66220 17400
+59143 38586
+37247 30201
+66923 89998
+77849 99304
+78619 18533
+15016 78465
+51214 51911
+60173 38229
+40398 54647
+85099 18533
+14582 55523
+27504 42203
+99400 19531
+11061 76191
+71600 63853
+65520 78425
+46348 39762
+82323 68649
+60500 13832
+50789 93649
+29819 62539
+53629 12245
+68689 50868
+66009 71159
+66056 11686
+79406 17400
+16799 28677
+81044 41209
+51166 53906
+82919 22523
+14096 17400
+22876 98879
+74460 81300
+35827 26565
+26421 68630
+26223 38055
+41827 68004
+16656 51911
+82262 24044
+20908 18533
+35562 14052
+57341 52417
+76022 86260
+79301 64857
+53092 21680
+92740 22128
+52415 28981
+23043 20493
+68913 32022
+25155 38763
+89907 71063
+57055 59590
+83130 17400
+62554 86934
+78177 90086
+42006 29151
+59006 59590
+54514 62539
+91441 78587
+96678 33768
+85071 73073
+65555 24044
+17750 68004
+95125 66725
+79124 93495
+91205 18533
+66332 73755
+65100 68630
+65055 38055
+45502 68630
+53781 39762
+12902 98857
+89582 53003
+42262 68004
+58411 94659
+45418 68392
+24720 59590
+59590 73476
+96877 15344
+53645 38315
+41081 28871
+44928 29773
+14232 68649
+88042 92094
+48259 46083
+80858 93649
+22758 88432
+76760 18611
+75606 54804
+38843 78425
+79989 62539
+97934 54647
+11337 46662
+94685 23016
+11546 83071
+44205 30003
+21374 38055
+78416 17400
+34842 39201
+22383 51911
+80155 43275
+93228 53319
+88857 22128
+84048 33319
+19980 29201
+89184 21680
+35848 84371
+17400 28677
+10985 45969
+45857 54403
+69026 57795
+24044 24044
+68840 18719
+18020 46662
+12012 94899
+53078 99304
+22616 57170
+83684 80858
+69679 37518
+18547 21689
+61762 48895
+32214 40187
+54647 37518
+49923 68630
+30699 84626
+82213 43275
+89544 40557
+86907 18533
+10007 92188
+33723 31433
+71326 59590
+43056 23659
+22112 93649
+29413 34871
+62103 28890
+99839 72605
+82466 34608
+63961 98699
+53925 37518
+76255 87718
+63941 54647
+99403 31572
+16280 22238
+24735 29508
+80271 12245
+54165 90392
+89734 58572
+14857 29850
+75370 24044
+97725 37518
+48788 48744
+76858 68217
+31339 49004
+74171 92188
+92778 62539
+81891 46662
+32207 42203
+89414 17400
+46799 43275
+31925 15424
+30646 80858
+93120 60565
+12245 87632
+57323 87542
+12723 44094
+87211 15455
+87213 22128
+24725 87661
+48091 52235
+90573 62167
+33839 25755
+84427 22128
+76722 37892
+33739 56210
+26953 28610
+18734 71063
+50146 93649
+74422 75490
+11801 80858
+99794 69569
+43452 17400
+88161 18611
+63363 72507
+85697 20493
+20311 89093
+87978 44496
+70962 51911
+95376 38555
+39600 38055
+49544 80007
+86928 25847
+36128 89093
+26726 68649
+80767 87542
+98537 34966
+96829 26089
+90261 62539
+22485 92188
+62557 67857
+90304 51894
+49968 82644
+41017 54386
+89768 30201
+56055 80995
+70937 92185
+37132 68459
+86318 59840
+51330 18167
+74069 24044
+35200 34718
+14871 17547
+88542 39762
+70691 68630
+52454 54647
+96898 17400
+13342 83750
+51301 51440
+31504 14515
+89361 77628
+66758 99304
+76024 68630
+33179 20780
+90757 15919
+90820 85981
+10606 92699
+38801 79056
+20602 91576
+73304 39768
+15768 42203
+42580 45606
+89093 37081
+42484 68649
+75272 21554
+56843 68649
+33767 56156
+43275 43275
+95051 85058
+40784 22128
+92406 30201
+24412 99304
+75949 16311
+23180 39762
+95260 45202
+87848 87542
+37421 93075
+12916 39425
+52570 49541
+63243 92786
+41946 18533
+15841 64834
+32242 18611
+84236 87067
+63032 68649
+25207 93649
+30525 37518
+38044 17787
+17774 33739
+25953 20493
+31123 43275
+88196 42203
+13796 77501
+19398 80858
+88811 11201
+71454 62539
+94597 52436
+14793 16357
+86183 77981
+49244 92146
+11382 76204
+33929 51911
+15981 68004
+53640 45703
diff --git a/src/Day1.hs b/src/Day1.hs
@@ -0,0 +1,169 @@
+module Day1 (solution) where
+
+import Control.Monad (liftM, join)
+import Data.List (sort)
+
+import Utils (SolType(..))
+
+input :: IO String
+input = readFile "inputs/day1"
+
+exampleInput :: String
+exampleInput = join [
+ "3 4\n",
+ "4 3\n",
+ "2 5\n",
+ "1 3\n",
+ "3 9\n",
+ "3 3\n"
+ ]
+
+-- | Split an input string into two smaller strings on any whitespace. All
+-- further whitespace is ignored
+-- Example:
+-- >>> splitWhitespace "3 4"
+-- Just ("3","4")
+-- >>> splitWhitespace "4 3"
+-- Just ("4","3")
+-- >>> splitWhitespace "2 5"
+-- Just ("2","5")
+-- >>> splitWhitespace "1 3"
+-- Just ("1","3")
+-- >>> splitWhitespace "3 9"
+-- Just ("3","9")
+-- >>> splitWhitespace "3 3"
+-- Just ("3","3")
+-- >>> splitWhitespace "agasdfadpc"
+-- Nothing
+-- >>> splitWhitespace "abcde fghi jk"
+-- Just ("abcde","fghijk")
+splitWhitespace :: String -> Maybe (String, String)
+splitWhitespace = helper [] Nothing
+ where
+ helper :: String -> Maybe String -> String -> Maybe (String, String)
+ --helper lAcc rAcc str
+ helper l Nothing (' ':rest) = helper l (Just []) rest
+ helper l Nothing (c:rest) = helper (c:l) Nothing rest
+ helper l r (' ':rest) = helper l r rest
+ helper l (Just r) (c:rest) = helper l (Just (c:r)) rest
+ helper l r [] = do
+ rStr <- r
+ return (reverse l, reverse rStr)
+
+-- | Given a tuple of monadic values, return a lifted monadic tuple
+-- Example:
+-- >>> liftMonadTuple (Just "test", Just "case 1")
+-- Just ("test","case 1")
+-- >>> liftMonadTuple (Just "test", Nothing)
+-- Nothing
+-- >>> liftMonadTuple (Nothing, Just "test")
+-- Nothing
+liftMonadTuple :: Monad m => (m a, m b) -> m (a, b)
+liftMonadTuple (mx, my) = do
+ x <- mx
+ y <- my
+ return (x, y)
+
+-- | Given a function and a tuple of values that function can act on, apply the
+-- function to each tuple element
+-- Example:
+-- >>> both ((+) 1) (2, 3)
+-- (3,4)
+both :: (a -> b) -> (a, a) -> (b, b)
+both f (a, b) = (f a, f b)
+
+-- | Given a datatype that can be read, attempt to read it. Instead of giving an
+-- exception, this gives a Maybe monad.
+-- Example:
+-- >>> (safeRead @Integer) "120"
+-- Just 120
+-- >>> (safeRead @Integer) "hello"
+-- Nothing
+safeRead :: Read a => String -> Maybe a
+safeRead s = case reads s of
+ [(value, "")] -> Just value
+ _ -> Nothing
+
+-- | Parse the input into the two lists of integers
+-- Example:
+-- >>> parse exampleInput
+-- Just ([3,4,2,1,3,3],[4,3,5,3,9,3])
+parse :: String -> Maybe ([Integer], [Integer])
+parse inputStr = do
+ let ls = lines inputStr
+ lrs <- mapM splitWhitespace ls
+ (l, r) <- liftM unzip $ mapM (liftMonadTuple . both safeRead) lrs
+ return (l, r)
+
+-- | Take the absolute difference between two integers
+-- Example:
+-- >>> integerDiff 2 3
+-- 1
+-- >>> integerDiff 3 2
+-- 1
+-- >>> integerDiff 3 4
+-- 1
+-- >>> integerDiff 4 3
+-- 1
+-- >>> integerDiff 2 5
+-- 3
+-- >>> integerDiff 1 3
+-- 2
+-- >>> integerDiff 3 9
+-- 6
+-- >>> integerDiff 3 3
+-- 0
+integerDiff :: Integer -> Integer -> Integer
+integerDiff x y
+ | x < y = y - x
+ | otherwise = x - y
+
+-- | Solution to day 1 part 1
+-- Example:
+-- >>> liftM solution1 $ parse exampleInput
+-- Just 11
+solution1 :: ([Integer], [Integer]) -> Integer
+solution1 (l, r) = helper 0 (sort l, sort r)
+ where
+ helper :: Integer -> ([Integer], [Integer]) -> Integer
+ helper n (x:xs, y:ys) = helper (n + integerDiff x y) (xs, ys)
+ helper n ([], _) = n
+ helper n (_, []) = n
+
+-- | Return the number of times something appears in a list
+-- Example:
+-- >>> numInstances 3 [4,3,5,3,9,3]
+-- 3
+-- >>> numInstances 4 [4,3,5,3,9,3]
+-- 1
+-- >>> numInstances 2 [4,3,5,3,9,3]
+-- 0
+-- >>> numInstances 1 [4,3,5,3,9,3]
+-- 0
+numInstances :: Eq a => a -> [a] -> Integer
+numInstances = helper 0
+ where
+ helper :: Eq a => Integer -> a -> [a] -> Integer
+ helper n x (el:rest)
+ | x == el = helper (n + 1) x rest
+ | otherwise = helper n x rest
+ helper n _ [] = n
+
+-- | Solution to day 1 part 2
+-- Example:
+-- >>> liftM solution2 $ parse exampleInput
+-- Just 31
+solution2 :: ([Integer], [Integer]) -> Integer
+solution2 = helper 0
+ where
+ helper :: Integer -> ([Integer], [Integer]) -> Integer
+ helper n (x:xs, ys) = helper (n + x * numInstances x ys) (xs, ys)
+ helper n ([], _) = n
+
+solution :: IO (SolType, SolType)
+solution = do
+ probStr <- input
+ let parsedLists = parse probStr
+ let sol1 = liftM (IntSol . solution1) parsedLists
+ let sol2 = liftM (IntSol . solution2) parsedLists
+ return $ (MaybeSol sol1, MaybeSol sol2)
diff --git a/src/Solutions.hs b/src/Solutions.hs
@@ -0,0 +1,10 @@
+module Solutions (solutions, SolType) where
+
+import qualified Day1 (solution)
+
+import Utils (SolType)
+
+solutions :: [(Integer, IO (SolType, SolType))]
+solutions = [
+ (1, Day1.solution)
+ ]
diff --git a/src/Utils.hs b/src/Utils.hs
@@ -0,0 +1,15 @@
+module Utils (SolType(..)) where
+
+data SolType =
+ IntSol Integer
+ | FloatSol Double
+ | StrSol String
+ | MaybeSol (Maybe SolType)
+
+instance Show SolType where
+ show (IntSol n) = show n
+ show (FloatSol n) = show n
+ show (StrSol s) = s
+ show (MaybeSol msol) = case msol of
+ Just sol -> show sol
+ Nothing -> "Nothing"
diff --git a/test/Main.hs b/test/Main.hs
@@ -0,0 +1,6 @@
+module Main (main) where
+
+import Test.DocTest (doctest)
+
+main :: IO ()
+main = doctest ["-isrc", "src/Day1.hs"]