From 0034691f2ab85b1b93e128c58f7b870c1a8e8544 Mon Sep 17 00:00:00 2001 From: Alan R Evans Date: Sun, 1 Dec 2024 08:02:28 +0000 Subject: [PATCH] 2024 day1 --- 2024/go/.vscode/launch.json | 16 + 2024/go/day01/day01.go | 54 ++ 2024/go/day01/day01_test.go | 17 + 2024/go/day01/input.txt | 1000 ++++++++++++++++++++++++ 2024/go/go.mod | 5 + 2024/go/go.sum | 2 + 2024/go/main.go | 84 ++ 2024/go/utils/grid2d/grid2d.go | 77 ++ 2024/go/utils/inputFile.go | 63 ++ 2024/go/utils/inputs/inputs.go | 45 ++ 2024/go/utils/sparseGrid/sparseGrid.go | 81 ++ 2024/go/utils/utils.go | 222 ++++++ 12 files changed, 1666 insertions(+) create mode 100644 2024/go/.vscode/launch.json create mode 100644 2024/go/day01/day01.go create mode 100644 2024/go/day01/day01_test.go create mode 100644 2024/go/day01/input.txt create mode 100644 2024/go/go.mod create mode 100644 2024/go/go.sum create mode 100644 2024/go/main.go create mode 100644 2024/go/utils/grid2d/grid2d.go create mode 100644 2024/go/utils/inputFile.go create mode 100644 2024/go/utils/inputs/inputs.go create mode 100644 2024/go/utils/sparseGrid/sparseGrid.go create mode 100644 2024/go/utils/utils.go diff --git a/2024/go/.vscode/launch.json b/2024/go/.vscode/launch.json new file mode 100644 index 0000000..800ee93 --- /dev/null +++ b/2024/go/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Package", + "type": "go", + "request": "launch", + "mode": "auto", + "args": ["16"], + "program": "${fileDirname}" + } + ] +} \ No newline at end of file diff --git a/2024/go/day01/day01.go b/2024/go/day01/day01.go new file mode 100644 index 0000000..8d706d0 --- /dev/null +++ b/2024/go/day01/day01.go @@ -0,0 +1,54 @@ +package day01 + +import ( + "adventofcode2024/utils" + "sort" + "strings" +) + +func Part1(input string) int { + var list1, list2 []int + + num := 0 + lines := strings.Split(input, "\n") + for _, line := range lines { + fields := strings.Fields(line) + // Convert the fields to integers + val1 := utils.MustAtoi(fields[0]) + val2 := utils.MustAtoi(fields[1]) + + // Append to the respective slices + list1 = append(list1, val1) + list2 = append(list2, val2) + } + sort.Ints(list1) + sort.Ints(list2) + for i := 0; i < len(list1); i++ { + num += utils.Abs(list1[i] - list2[i]) + } + return num + +} + +func Part2(input string) int { + var list1 []int + list2 := make(map[int]int) + + + num := 0 + lines := strings.Split(input, "\n") + for _, line := range lines { + fields := strings.Fields(line) + // Convert the fields to integers + val1 := utils.MustAtoi(fields[0]) + val2 := utils.MustAtoi(fields[1]) + + // Append to the respective slices + list1 = append(list1, val1) + list2[val2]++ + } + for i := 0; i < len(list1); i++ { + num += list1[i] * list2[list1[i]] + } + return num +} diff --git a/2024/go/day01/day01_test.go b/2024/go/day01/day01_test.go new file mode 100644 index 0000000..2ad653c --- /dev/null +++ b/2024/go/day01/day01_test.go @@ -0,0 +1,17 @@ +package day01 + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestPart1(t *testing.T) { + r := Part1("") + require.Equal(t, 0, r) +} + +func TestPart2(t *testing.T) { + r := Part2("") + require.Equal(t, 0, r) +} diff --git a/2024/go/day01/input.txt b/2024/go/day01/input.txt new file mode 100644 index 0000000..2576b42 --- /dev/null +++ b/2024/go/day01/input.txt @@ -0,0 +1,1000 @@ +61967 56543 +11022 54992 +21268 29417 +90452 95846 +90728 95846 +82351 12878 +40277 58932 +36981 22944 +93875 53190 +39283 59850 +39396 34776 +16395 35328 +32473 10395 +15028 20276 +31930 65432 +24773 22172 +40802 97123 +10909 29189 +23996 60290 +55260 93875 +93378 76216 +46284 95037 +41664 15145 +84475 39021 +52069 55213 +94827 20473 +79648 48127 +43947 76411 +20473 71938 +70251 80695 +13125 65297 +49246 75802 +49184 15227 +92091 54909 +31992 41267 +45911 19856 +93403 97963 +45807 76216 +61063 41259 +47907 21322 +15388 15227 +85798 13686 +60015 50364 +34294 34597 +14526 70647 +79498 72002 +76367 46598 +10763 67546 +53531 88962 +86158 30240 +48843 20473 +74127 95846 +29239 39021 +89243 55213 +42208 52849 +11396 54168 +51485 54805 +28347 34661 +32396 55213 +89137 18330 +84414 55213 +64013 12511 +50364 62725 +69550 70382 +75395 47413 +86240 56543 +22944 56900 +99262 56543 +70893 48848 +49889 85195 +41385 85280 +33498 11649 +53359 11649 +35483 61686 +15429 34776 +82878 78142 +71716 76015 +63677 22034 +38703 71901 +88599 89560 +34092 19913 +79849 34661 +86969 51576 +28571 33019 +26154 22944 +52835 29417 +53205 77890 +20276 39461 +82458 50421 +85308 55213 +23780 34661 +35311 30488 +42273 63441 +68289 14174 +53846 48389 +66984 86158 +69976 83576 +44223 36234 +40372 27603 +83168 76216 +60101 62691 +99675 90166 +70006 84175 +24063 54443 +54560 10210 +30011 34776 +77029 26998 +37798 77700 +69137 77283 +68787 22650 +93357 39021 +18050 81124 +78744 18131 +32059 46598 +21287 42621 +42292 11649 +99706 11352 +86307 34948 +53716 41259 +84440 80333 +39562 66295 +81493 90431 +64911 41267 +41829 82797 +33421 55780 +73962 65004 +70599 48389 +71389 78405 +56211 96609 +86614 20276 +60185 18584 +46519 19856 +85341 21402 +63706 54396 +99509 19131 +77048 68330 +47476 41259 +19677 48389 +21320 22944 +98668 67439 +77246 41489 +20072 31880 +63382 27469 +86557 20276 +80371 51645 +24256 21964 +53783 49002 +36807 85389 +98394 82801 +95346 86158 +10431 85065 +98843 95846 +18651 63897 +10144 65443 +49483 34856 +72449 30766 +94011 91054 +11029 24754 +36006 54821 +18459 65297 +52537 10646 +58677 95846 +52571 24400 +45008 53241 +84084 59701 +63723 65432 +41397 25462 +66176 94916 +37821 87108 +10786 81993 +43825 48389 +59143 99924 +55219 45778 +53780 75436 +52820 46104 +23497 84939 +88371 58423 +41259 37181 +22603 76216 +99333 15881 +96990 19856 +56662 49575 +54876 67245 +25213 78142 +24559 78821 +58907 68881 +14836 15227 +22463 68881 +52592 29417 +39763 40027 +28925 62885 +74177 38729 +58731 56543 +86958 26033 +50538 25025 +18993 10013 +80692 56917 +27924 43417 +57696 84166 +66253 34776 +27631 43340 +66106 94016 +95853 48244 +70430 82286 +23027 26092 +56532 95846 +67501 45349 +12215 41267 +19720 50585 +96226 45042 +74000 27047 +62451 32342 +31717 76164 +45992 51137 +41345 62978 +58818 89347 +49405 34661 +71577 69710 +54334 20032 +23609 78142 +34661 25224 +15665 41259 +69935 21666 +30320 10215 +47745 22944 +16919 79188 +90987 50880 +43151 35249 +56543 85280 +31607 43137 +50565 96043 +76216 53795 +31299 74160 +12068 52582 +34212 25224 +59157 27762 +49371 80778 +12067 34054 +84925 15227 +94050 15227 +16313 95846 +45020 76657 +96730 50985 +35597 80727 +15922 86678 +72237 15949 +19348 91593 +22493 50364 +81453 36932 +63469 31880 +83204 44281 +97516 76216 +29851 85280 +83853 50364 +22722 65432 +44826 11286 +78112 61461 +34712 11649 +77566 63897 +89300 56543 +84751 22250 +17748 34661 +26317 65297 +93586 85526 +93545 46598 +80829 92121 +31655 65297 +70888 19856 +78658 67271 +19856 34776 +39960 56479 +61689 39021 +70480 50390 +55500 21322 +43674 65945 +17507 21322 +37527 60767 +46386 25187 +26815 49575 +84007 56865 +88175 51137 +36052 48389 +59939 53813 +72268 65297 +81352 61501 +16822 68881 +36521 85280 +34361 99506 +63695 86158 +98179 63897 +84080 95846 +35952 25224 +63718 16985 +47260 21322 +32958 86125 +46871 95846 +84506 62971 +22962 87402 +44900 74111 +79913 81638 +83540 20473 +90341 89847 +17097 75291 +95448 11649 +10951 65297 +66309 43216 +71201 15227 +52481 62912 +21951 51137 +22464 62319 +10029 63499 +78832 76216 +98333 11649 +40894 68881 +52946 19856 +50329 14803 +29823 39056 +76686 20473 +83170 26188 +53459 68881 +13042 33617 +78116 60418 +48212 51137 +92069 88727 +57787 34115 +73872 25224 +50550 18671 +97638 62724 +41131 65597 +84806 55213 +94592 31880 +71180 41259 +92360 97729 +98620 62980 +34471 52669 +91532 20276 +35790 61616 +75503 15748 +75074 21322 +11737 41127 +77602 25224 +94166 11649 +11580 58318 +33589 65023 +28957 41259 +48071 85280 +46598 71087 +36777 62347 +60594 20473 +81800 83420 +31339 40736 +16207 47305 +23624 48389 +41126 73202 +95465 44217 +73513 58171 +48492 34661 +27319 65297 +15520 19856 +48278 74391 +42528 42241 +21889 96386 +61833 19076 +13142 93210 +19905 15227 +64895 13547 +15908 78271 +20442 55213 +33221 50364 +78895 40466 +56182 97639 +40093 14980 +85157 26820 +36540 96113 +56873 49315 +39565 30340 +93297 49684 +43957 63789 +63897 50409 +69723 58764 +26167 17686 +78216 51576 +66527 84415 +51137 19856 +36635 56543 +59257 93611 +80851 26970 +21322 36633 +60017 19856 +74310 12230 +54464 85280 +74537 55813 +55344 19856 +19176 41267 +31914 76216 +77455 80335 +34039 39669 +35118 89909 +65432 74023 +37950 11649 +36603 62501 +52464 46856 +32342 72736 +89467 63318 +98246 67207 +15075 17421 +76916 74263 +92157 95846 +31880 43080 +45051 13900 +91452 67550 +68619 90797 +54105 39021 +33071 72624 +63784 57575 +67379 49283 +38131 29417 +57202 55213 +21615 56543 +90526 46598 +96898 65297 +49860 34661 +74266 93975 +21484 44229 +66643 68881 +16715 84749 +90512 73621 +89388 16965 +94053 36641 +35962 65432 +29763 47174 +14745 77272 +34993 34661 +83014 11649 +60837 92670 +15494 20473 +47055 93024 +12035 36814 +49721 39021 +26438 39677 +21933 19856 +16148 40828 +87391 68949 +56399 22506 +48696 72022 +95549 10092 +18684 52865 +44990 21322 +77310 19856 +35505 83623 +89352 74555 +86186 55213 +23227 94800 +37067 34776 +74039 42442 +53442 92091 +85527 55213 +64005 63897 +60463 60857 +84190 19303 +11722 99564 +47545 20473 +50423 25224 +19300 13219 +11549 88441 +41246 56543 +64539 21322 +16656 21331 +81984 29417 +21166 65297 +27236 27913 +73250 22933 +14078 21480 +86888 37494 +60623 68881 +56818 25224 +92340 28382 +72247 42211 +19198 85280 +29546 52039 +44394 65297 +14866 21610 +67444 21322 +85995 96825 +71932 38843 +99764 34776 +79024 43841 +59707 89498 +45503 87250 +83594 96789 +85277 55213 +32640 95846 +27823 23982 +28543 31399 +33759 95846 +23087 91530 +93094 93695 +88151 82097 +53506 17212 +61712 63975 +69833 45914 +19987 60322 +68648 28755 +15919 34380 +76804 90603 +83622 39021 +89705 46485 +29860 58935 +58392 78957 +26149 17889 +19305 89821 +88282 17673 +14085 75808 +78937 41259 +75320 64962 +84453 21322 +29476 94656 +84039 41267 +84385 11391 +39529 52865 +63057 23532 +37397 56543 +39202 19856 +90160 15799 +20310 22944 +40937 41267 +44029 91325 +50399 34661 +83445 39021 +58878 60759 +87071 87733 +44142 46155 +71837 82441 +74478 86781 +68295 50364 +94162 65432 +69323 97655 +63974 61934 +39245 98569 +13669 47701 +44744 34661 +75459 50364 +88291 55213 +99416 11649 +36887 85280 +29988 45252 +97663 76216 +35645 26140 +78021 85280 +67424 69456 +72759 79790 +33820 20473 +95942 39872 +81333 85280 +40810 61461 +69479 32816 +15379 24034 +11921 13179 +52719 54900 +20410 63897 +97887 15408 +40546 43910 +44053 49808 +90572 60565 +80385 78142 +40458 95846 +92895 29481 +30189 84413 +52865 69499 +19745 52865 +50975 49392 +89519 73695 +86176 38188 +47604 62257 +67436 29417 +11296 82182 +85459 91364 +27362 38039 +10585 59869 +46438 22944 +44742 35866 +85280 16513 +21227 81727 +16973 32676 +47127 68881 +98849 68881 +38328 21322 +12186 31773 +13799 71462 +13565 51576 +29848 45510 +76548 86158 +67804 56543 +55213 88508 +88481 12489 +13389 41259 +25035 88404 +50679 51137 +13786 85280 +50406 11649 +38054 89777 +79568 24534 +24756 85373 +93482 86158 +43790 79276 +60250 83576 +43730 21322 +87160 36323 +88807 61112 +97993 89540 +44262 89194 +82245 85280 +40413 96894 +56866 55804 +27892 93799 +15314 52111 +23042 60143 +97060 89497 +58200 19325 +27659 67004 +89411 22944 +87316 89489 +19976 37593 +38865 11649 +45078 24406 +36358 55213 +45579 35021 +99402 73275 +40782 20276 +48389 34465 +61983 65432 +46549 71333 +60731 50364 +28239 82886 +37245 84331 +89695 72707 +45702 35310 +46936 95846 +31661 65432 +63867 34661 +22578 46504 +35924 99928 +97445 95928 +60411 48389 +36833 68881 +10278 50364 +39206 34776 +95474 94852 +15159 45432 +90288 95481 +77881 30096 +56304 62251 +49910 81451 +13678 21322 +42650 94971 +75244 74862 +77750 74920 +54566 50186 +92641 49575 +23566 81405 +39983 70620 +82218 31880 +95885 58807 +97444 40125 +86195 35943 +34776 68881 +20384 76109 +91857 44727 +59888 33738 +47992 61640 +50291 53340 +59747 40258 +98077 68881 +11930 29301 +52116 44318 +96256 77071 +75365 39021 +14830 29417 +34876 92947 +48613 17514 +43229 85569 +15955 72245 +61458 76216 +74993 61461 +97198 63897 +66233 56543 +92861 80868 +22888 50889 +11649 15227 +72510 44999 +60024 46310 +51981 78952 +30134 85280 +15153 48389 +32013 53946 +14541 27325 +54878 19856 +12630 51576 +12646 63897 +68382 76216 +40855 21322 +31477 99082 +94979 10843 +82341 87920 +35488 41259 +57823 99959 +90928 54338 +91407 51576 +81221 22944 +55919 42682 +27235 95483 +68881 73120 +21359 46598 +59534 46435 +91806 50364 +42497 15227 +57049 12517 +76929 26842 +76110 68881 +78586 39021 +51225 65432 +87650 93875 +48080 35764 +68282 80266 +23715 24411 +62383 46689 +35851 38657 +48668 35985 +57008 42062 +44396 52990 +97855 71998 +35578 28469 +22235 56010 +70948 68881 +77965 73892 +15973 14537 +35328 85469 +94454 46598 +62384 19856 +78071 20276 +88122 86158 +88105 68881 +77090 23412 +11822 55213 +31989 39118 +68039 65297 +81126 55174 +43631 32060 +11917 11649 +11974 29417 +62698 41674 +64496 28711 +33691 73796 +92195 66727 +11682 20677 +65996 79079 +92131 95846 +44640 25224 +62049 65297 +67359 34661 +63094 29497 +24813 67897 +41267 38839 +13278 56543 +71572 12828 +80808 78142 +56156 95846 +51530 89113 +75797 63897 +93988 35495 +30272 68056 +31629 16046 +17562 34661 +34072 96205 +43904 62359 +83398 49834 +28423 97195 +82852 90842 +49810 31220 +66513 50188 +27911 45688 +56971 20473 +22800 78142 +86334 41267 +93393 11649 +84601 71534 +86633 79250 +60407 78142 +85126 53116 +74638 36062 +20964 71314 +82352 36930 +83394 29417 +65297 11649 +10164 29082 +15227 76216 +95846 48389 +91167 80269 +72154 47261 +71176 19856 +75281 65297 +51576 50364 +89997 24184 +53631 65432 +24704 25224 +39021 21322 +64838 19091 +76401 48512 +13948 34578 +33099 63897 +94777 12300 +59825 51487 +96739 30997 +41555 48028 +12667 15227 +16397 51137 +74081 58852 +53928 55213 +34791 42483 +29417 27352 +87524 89512 +25224 76216 +47202 25224 +30915 34551 +79149 89897 +92898 72170 +84546 19856 +63881 22611 +65227 85280 +68664 11649 +13738 11834 +48100 20473 +31647 12357 +58285 82005 +38498 61310 +17399 29417 +53470 56543 +94488 41267 +55069 51137 +65843 12011 +86089 21427 +98998 69258 +93772 50364 +61461 21322 +32797 20276 +63534 45983 +42044 68881 +49575 49268 +89725 71824 +13151 55213 +47235 50474 +70742 41267 +69846 83201 +49984 45584 +70773 16704 +41907 58931 +80020 78319 +38557 41267 +59468 17081 +24017 20360 +83576 26453 +44100 42968 +32619 97934 +95538 95846 +10470 41259 +40765 22806 +84349 19856 +31770 75551 +63239 76216 +22175 31938 +50014 51673 +18008 84899 +98253 72600 +38935 22946 +94044 29417 +12440 63667 +71981 22652 +35876 56543 +13131 22143 +78690 34776 +27878 11370 +19659 34776 +64979 50364 +89717 30357 +71844 92010 +26402 90514 +78750 74617 +53297 22944 +49589 50364 +16296 69699 +46311 74647 +83938 50477 +73500 84604 +38665 68881 +62321 73263 +79989 10191 +81079 63922 +19186 15227 +89155 56543 +90154 27651 +36567 65164 +95351 20473 +73278 40535 +47097 19856 +62480 41267 +51246 25224 +94838 27133 +98878 22911 +73123 91366 +21914 67909 +87431 81551 +27032 15227 +15090 61123 +13350 98688 +37173 58301 +92022 11981 +66900 26049 +18381 10986 +75360 15227 +69620 79680 +18780 60264 +84878 68881 +15467 33806 +71799 58322 +47180 19679 +39054 92091 +29531 94509 +62925 70352 +99943 51998 +64891 75738 +88061 20473 +98252 59643 +12766 64598 +38349 30817 +50824 41267 +47031 97828 +82027 46701 +59404 40860 +88020 78142 +83250 72893 +37738 53309 +85272 34122 +57713 65432 +56624 78571 +10906 55213 +42778 39021 +56224 59056 +71584 44879 +42348 55213 +53434 75449 +78142 14981 +40177 28988 +54053 68881 +66277 69900 +35127 50364 +54463 21098 +21554 87868 +89672 76216 +95148 82149 +74621 76216 +40237 20473 +10257 20473 +70014 41883 +42436 41267 +59460 71093 +57487 15227 +65720 91317 +98718 92080 +88722 21322 +63630 26854 +49789 89200 +96784 20473 +30583 20473 +41407 56714 +86109 34661 +13834 44624 +19298 44781 +67868 48389 +73954 14305 +78878 48389 +99934 63566 +53524 51137 +77891 26553 +98684 68881 +28112 38511 +80455 33657 +45447 51355 +77158 75485 +16208 55213 +37619 41978 +77064 20473 +38184 80480 +57747 89791 +88771 29417 +78861 95846 +87502 11649 +31852 98307 +50648 47711 +23961 34661 +96913 79564 diff --git a/2024/go/go.mod b/2024/go/go.mod new file mode 100644 index 0000000..942e8e7 --- /dev/null +++ b/2024/go/go.mod @@ -0,0 +1,5 @@ +module adventofcode2024 + +go 1.19 + +require golang.org/x/exp v0.0.0-20221208152030-732eee02a75a diff --git a/2024/go/go.sum b/2024/go/go.sum new file mode 100644 index 0000000..68834ce --- /dev/null +++ b/2024/go/go.sum @@ -0,0 +1,2 @@ +golang.org/x/exp v0.0.0-20221208152030-732eee02a75a h1:4iLhBPcpqFmylhnkbY3W0ONLUYYkDAW9xMFLfxgsvCw= +golang.org/x/exp v0.0.0-20221208152030-732eee02a75a/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= diff --git a/2024/go/main.go b/2024/go/main.go new file mode 100644 index 0000000..acbb018 --- /dev/null +++ b/2024/go/main.go @@ -0,0 +1,84 @@ +package main + +import ( + "fmt" +// "math/rand" + "os" +// "strings" +// "time" + "adventofcode2024/utils" + "adventofcode2024/day01" +) +// Usage: go run main.go +// assumes input is in day/input.txt +func main() { + d := day() + fmt.Printf("Running day %02d\n", d) + + switch d { + case 1: + fmt.Printf("part 1: %d\n", day01.Part1(utils.Readfile(d))) + fmt.Printf("part 2: %d\n", day01.Part2(utils.Readfile(d))) + default: + panic(fmt.Errorf("no such day: %d", d)) + } +} + +// Reads day from os.Args. +func day() int { + latest := 1 + if len(os.Args) == 1 { + return latest + } + + if os.Args[1] == "next" { + genNext(latest + 1) + os.Exit(0) + } + day := utils.MustAtoi(os.Args[1]) + return day +} + + +func genNext(n int) { + os.Mkdir(fmt.Sprintf("day%02d", n), 0755) + f, err := os.Create(fmt.Sprintf("day%02d/day%02d.go", n, n)) + utils.PanicOnErr(err) + defer f.Close() + f.WriteString(fmt.Sprintf(`package day%02d + +func Part1(input string) int { + return 0 +} + +func Part2(input string) int { + return 0 +} +`, n)) + fmt.Printf("wrote day%02d/day%02d.go\n", n, n) + + f, err = os.Create(fmt.Sprintf("day%02d/day%02d_test.go", n, n)) + utils.PanicOnErr(err) + defer f.Close() + f.WriteString(fmt.Sprintf(`package day%02d + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestPart1(t *testing.T) { + r := Part1("") + require.Equal(t, 0, r) +} + +func TestPart2(t *testing.T) { + r := Part2("") + require.Equal(t, 0, r) +} +`, n)) + fmt.Printf("wrote day%02d/day%02d_test.go\n", n, n) + utils.GenInputFile(n) + +} \ No newline at end of file diff --git a/2024/go/utils/grid2d/grid2d.go b/2024/go/utils/grid2d/grid2d.go new file mode 100644 index 0000000..aff1da3 --- /dev/null +++ b/2024/go/utils/grid2d/grid2d.go @@ -0,0 +1,77 @@ +package grid2d + +import ( + "strings" + + "adventofcode2024/utils" +) + +type Grid[T any] struct { + sizeX, sizeY int + matrix [][]T + empty T +} + +func NewGrid[T any](sizeX, sizeY int, empty T) *Grid[T] { + matrix := make([][]T, sizeY) + rows := make([]T, sizeX*sizeY) + for i := 0; i < sizeX*sizeY; i++ { + rows[i] = empty + } + + j := 0 + for i := 0; i < sizeY; i++ { + matrix[i] = rows[j : j+sizeX : j+sizeX] + j += sizeX + } + return &Grid[T]{ + sizeX: sizeX, + sizeY: sizeY, + matrix: matrix, + empty: empty, + } +} + +func (g *Grid[T]) SizeX() int { + return g.sizeX +} + +func (g *Grid[T]) SizeY() int { + return g.sizeY +} +func (g *Grid[T]) Matrix() [][]T { + return g.matrix +} + +func (g *Grid[T]) Get(x, y int) T { + if x < 0 || x >= g.sizeX { + return g.empty + } + if y < 0 || y >= g.sizeY { + return g.empty + } + return g.matrix[y][x] +} + +func (g *Grid[T]) Set(x, y int, v T) { + if x < 0 || x >= g.sizeX { + panic("invalid x") + } + if y < 0 || y >= g.sizeY { + panic("invalid y") + } + g.matrix[y][x] = v +} + +func (g *Grid[T]) StringWithFormatter(formatter func(T, int, int) string) string { + var r strings.Builder + for j := 0; j < g.sizeY; j++ { + for i := 0; i < g.sizeX; i++ { + _, err := r.WriteString(formatter(g.matrix[j][i], i, j)) + utils.PanicOnErr(err) + } + _, err := r.WriteRune('\n') + utils.PanicOnErr(err) + } + return r.String() +} diff --git a/2024/go/utils/inputFile.go b/2024/go/utils/inputFile.go new file mode 100644 index 0000000..439a866 --- /dev/null +++ b/2024/go/utils/inputFile.go @@ -0,0 +1,63 @@ +package utils + +import ( + "fmt" + "io" + "net/http" + "os" +) + +func GenInputFile(day int) string { + var d string + if day < 10 { + d = fmt.Sprintf("0%d", day) + } else { + d = fmt.Sprintf("%d", day) + } + + pwd, _ := os.Getwd() + path := fmt.Sprintf("%s/day%s/input.txt", pwd, d) + fi, _ := os.Stat(path) + if fi != nil { + return path + } + + fmt.Printf("Creating new input file %v...", path) + f, err := os.Create(path) + if err != nil { + fmt.Println(err) + } else { + defer f.Close() + data := readHttp(2024, day) + _, err := f.WriteString(data) + if err != nil { + fmt.Println(err) + } + } + return path +} + +func readHttp(year, day int) string { + fmt.Println("Fetching data into file...") + + url := fmt.Sprintf("https://adventofcode.com/%d/day/%d/input", year, day) + session := os.Getenv("sessionAoC") + req, err := http.NewRequest("GET", url, nil) + if err != nil { + panic(err) + } + + req.AddCookie(&http.Cookie{Name: "session", Value: session}) + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + panic(err) + } + + body, err := io.ReadAll(resp.Body) + if err != nil { + panic(err) + } + return string(body) +} + diff --git a/2024/go/utils/inputs/inputs.go b/2024/go/utils/inputs/inputs.go new file mode 100644 index 0000000..8576011 --- /dev/null +++ b/2024/go/utils/inputs/inputs.go @@ -0,0 +1,45 @@ +package inputs + +import ( + "strings" + + "adventofcode2024/utils" + "adventofcode2024/utils/grid2d" + sparsegrid "adventofcode2024/utils/sparseGrid" +) + +func ToInts(input string, sep string) []int { + var r []int + for _, line := range strings.Split(input, sep) { + if line != "" { + r = append(r, utils.MustAtoi(line)) + } + } + return r +} + +func ToGrid2D[T any](input, rowSep, colSep string, empty T, conv func(string) T) *grid2d.Grid[T] { + lines := strings.Split(input, rowSep) + + grid := grid2d.NewGrid(len(lines[0]), len(lines), empty) + for y, line := range lines { + for x, v := range strings.Split(line, colSep) { + grid.Set(x, y, conv(v)) + } + } + + return grid +} + +func ToSparseGrid[T comparable](input, rowSep, colSep string, empty T, conv func(string) T) *sparsegrid.SparseGrid[T] { + lines := strings.Split(input, rowSep) + + grid := sparsegrid.NewGrid(empty) + for y, line := range lines { + for x, v := range strings.Split(line, colSep) { + grid.Set(x, y, conv(v)) + } + } + + return grid +} diff --git a/2024/go/utils/sparseGrid/sparseGrid.go b/2024/go/utils/sparseGrid/sparseGrid.go new file mode 100644 index 0000000..c7fbb6f --- /dev/null +++ b/2024/go/utils/sparseGrid/sparseGrid.go @@ -0,0 +1,81 @@ +package sparsegrid + +import ( + "fmt" + "strings" + + "adventofcode2024/utils" +) + +type SparseGrid[T comparable] struct { + minX, maxX, minY, maxY int + data map[string]T + empty T +} + +func NewGrid[T comparable](empty T) *SparseGrid[T] { + return &SparseGrid[T]{ + minX: utils.MaxInt, + maxX: utils.MinInt, + minY: utils.MaxInt, + maxY: utils.MinInt, + data: map[string]T{}, + empty: empty, + } +} + +func (g *SparseGrid[T]) SizeX() (int, int) { + return g.minX, g.maxX +} + +func (g *SparseGrid[T]) SizeY() (int, int) { + return g.minY, g.maxY +} + +func (g *SparseGrid[T]) Visited() int { + return len(g.data) +} + +func (g *SparseGrid[T]) Get(x, y int) T { + k := key(x, y) + v, ok := g.data[k] + if !ok { + return g.empty + } + return v +} + +func (g *SparseGrid[T]) Set(x, y int, v T) { + k := key(x, y) + current, ok := g.data[k] + if ok && v == current { + return + } else if !ok && v == g.empty { + return + } else if v == g.empty { + delete(g.data, k) + } else { + g.data[k] = v + g.minX = utils.Min(g.minX, x) + g.maxX = utils.Max(g.maxX, x) + g.minY = utils.Min(g.minY, y) + g.maxY = utils.Max(g.maxY, y) + } +} + +func (g *SparseGrid[T]) StringWithFormatter(formatter func(T, int, int) string) string { + var r strings.Builder + for j := g.minY; j <= g.maxY; j++ { + for i := g.minX; i <= g.maxX; i++ { + _, err := r.WriteString(formatter(g.Get(i, j), i, j)) + utils.PanicOnErr(err) + } + _, err := r.WriteRune('\n') + utils.PanicOnErr(err) + } + return r.String() +} + +func key(x, y int) string { + return fmt.Sprintf("%d:%d", x, y) +} diff --git a/2024/go/utils/utils.go b/2024/go/utils/utils.go new file mode 100644 index 0000000..14d1797 --- /dev/null +++ b/2024/go/utils/utils.go @@ -0,0 +1,222 @@ +package utils + +import ( + "bufio" + "fmt" + "io" + "os" + "reflect" + "regexp" + "strconv" + "strings" + + "golang.org/x/exp/constraints" +) + +func PanicOnErr(err error) { + if err != nil { + panic(err) + } +} + +const MaxInt = int(^uint(0) >> 1) +const MinInt = ^MaxInt + +func Max[T constraints.Ordered](a, b T) T { + if a > b { + return a + } + return b +} + +func Min[T constraints.Ordered](a, b T) T { + if a < b { + return a + } + return b +} + +func SliceMinMax[T constraints.Ordered](slice []T) (*T, *T) { + if len(slice) == 0 { + return nil, nil + } + min := &slice[0] + max := &slice[0] + for i, v := range slice { + if v < *min { + min = &slice[i] + } + if v > *max { + max = &slice[i] + } + } + return min, max +} + +func MustAtoi(s string) int { + v, err := strconv.Atoi(s) + PanicOnErr(err) + return v +} + +// Returns key from map[T]int which has the max value +func MapFindMax(m interface{}) interface{} { + var maxK interface{} = nil + var maxV = MinInt + iter := reflect.ValueOf(m).MapRange() + for iter.Next() { + k := iter.Key() + v := int(iter.Value().Int()) + if v > maxV { + maxV = v + maxK = k.Interface() + } + } + return maxK +} + +// Returns key from map[T]int which has the min value +func MapFindMin(m interface{}) interface{} { + var minK interface{} = nil + var minV = MaxInt + iter := reflect.ValueOf(m).MapRange() + for iter.Next() { + k := iter.Key() + v := int(iter.Value().Int()) + if v < minV { + minV = v + minK = k.Interface() + } + } + return minK +} + +func Readfile(day int) string { + filename := fmt.Sprintf("day%02d/input.txt", day) + file, err := os.Open(filename) + PanicOnErr(err) + defer file.Close() + + reader := bufio.NewReader(file) + contents, err := io.ReadAll(reader) + PanicOnErr(err) + + return strings.TrimSuffix(string(contents), "\n") +} + +func ReadfileAsSlice(day int) []string { + filename := fmt.Sprintf("day%02d/input.txt", day) + file, err := os.Open(filename) + PanicOnErr(err) + defer file.Close() + + arr := make([]string, 0) + sc := bufio.NewScanner(file) + for sc.Scan() { + arr = append(arr, sc.Text()) + } + + return arr +} + +func ParseToStruct(re *regexp.Regexp, input string, target interface{}) bool { + m := re.FindStringSubmatch(input) + if m == nil { + return false + } + + var useOffset bool + + for i, name := range re.SubexpNames() { + if i == 0 { + continue + } + var field reflect.Value + if name == "" { + // use offset + if i == 1 { + useOffset = true + } else if !useOffset { + panic("can't mix named and unnamed subexpressions") + } + field = reflect.ValueOf(target).Elem().Field(i - 1) + } else { + // use name + if i == 1 { + useOffset = false + } else if useOffset { + panic("can't mix named and unnamed subexpressions") + } + field = reflect.ValueOf(target).Elem().FieldByName(name) + } + if field.Kind() == reflect.String { + field.SetString(m[i]) + } else if field.Kind() == reflect.Int { + v, err := strconv.Atoi(m[i]) + PanicOnErr(err) + field.SetInt(int64(v)) + } else if field.Kind() == reflect.Uint8 { + if len(m[i]) != 1 { + panic(fmt.Sprintf("expecting 1 char, got: %s", m[i])) + } + field.SetUint(uint64(m[i][0])) + } else { + panic(fmt.Sprintf("unknown kind: %s", field.Kind())) + } + } + return true +} + +func MustParseToStruct(re *regexp.Regexp, input string, target interface{}) { + if !ParseToStruct(re, input, target) { + panic(fmt.Errorf("failed to parse: %s", input)) + } +} + +func CharToLower(c byte) byte { + return strings.ToLower(string(c))[0] +} + +func CharToUpper(c byte) byte { + return strings.ToUpper(string(c))[0] +} + +func Contains(haystack []string, needle string) bool { + for _, s := range haystack { + if s == needle { + return true + } + } + return false +} + +func Abs[T constraints.Signed](x T) T { + if x < 0 { + return -x + } + return x +} + +func Gcd(x, y int) int { + if x <= 0 || y <= 0 { + panic(fmt.Errorf("invalid input: %d, %d", x, y)) + } + if x == y { + return x + } + if x > y { + return Gcd(x-y, y) + } else { + return Gcd(x, y-x) + } +} + +func Sign[T constraints.Signed](x T) int { + if x < 0 { + return -1 + } else if x > 0 { + return 1 + } else { + return 0 + } +}