My yearly advent-of-code solutions

Compare changes

Choose any two refs to compare.

+2
.gitignore
···
+
input.txt
+
input_test.txt
+2 -1
2024/.gitignore
···
*.mod
*.out
-
./bin
+
*.txt
+
_build/
+36 -36
2024/day_01.f90
···
-
module sorting
-
! apparently you need to put the subroutine in a module
-
implicit none
-
contains
-
subroutine sort(arr)
+
module sorting
+
! apparently you need to put the subroutine in a module
+
implicit none
+
contains
+
subroutine sort(arr)
!! a little insertion sort KISS
!! also yea we have no in built sorting
-
implicit none
-
integer, intent(inout) :: arr(1000)
-
integer :: i, j, key
-
do i = 2, 1000
-
key = arr(i)
-
j = i - 1
-
do while (j > 0 .and. arr(j) > key)
-
arr(j+1) = arr(j)
-
j = j - 1
+
implicit none
+
integer, intent(inout) :: arr(1000)
+
integer :: i, j, key
+
do i = 2, 1000
+
key = arr(i)
+
j = i - 1
+
do while (j > 0 .and. arr(j) > key)
+
arr(j+1) = arr(j)
+
j = j - 1
+
end do
+
arr(j+1) = key
end do
-
arr(j+1) = key
-
end do
-
end subroutine sort
+
end subroutine sort
end module sorting
program day_01
-
use sorting
-
implicit none
-
integer :: io, i, dist, sim, left(1000), right(1000) ! yea we are coding to the input file and not generic
-
open(newunit=io, file='./day_01_input.txt', status='old', action='read')
+
use sorting
+
implicit none
+
integer :: io, i, dist, sim, left(1000), right(1000) ! yea we are coding to the input file and not generic
+
open(newunit=io, file='./day_01_input.txt', status='old', action='read')
-
do i = 1, 1000
-
read(io, *) left(i), right(i) ! read both values in line
-
end do
+
do i = 1, 1000
+
read(io, *) left(i), right(i) ! read both values in line
+
end do
-
close(10) ! close the file
+
close(10) ! close the file
-
call sort(left)
-
call sort(right)
+
call sort(left)
+
call sort(right)
-
! if we dont init these bad things happen on multiple runs
-
dist = 0
-
sim = 0
+
! if we dont init these bad things happen on multiple runs
+
dist = 0
+
sim = 0
-
do i = 1, 1000
-
dist = dist + abs(left(i) - right(i))
-
sim = sim + left(i) * count(right == left(i))
-
end do
+
do i = 1, 1000
+
dist = dist + abs(left(i) - right(i))
+
sim = sim + left(i) * count(right == left(i))
+
end do
-
print*, "distance: ", dist
-
print*, "similarity: ", sim
+
print*, "distance: ", dist
+
print*, "similarity: ", sim
end program day_01
+30
2024/day_01.ml
···
+
let filename = "./day_01_input.txt"
+
let try_read ic = try Some (input_line ic) with End_of_file -> None
+
+
let line_to_ints s =
+
Str.split_delim (Str.regexp " ") s |> List.map int_of_string
+
+
let rec read_lines left right ic =
+
match try_read ic with
+
| Some line -> (
+
line_to_ints line |> fun ints ->
+
match ints with
+
| [ a; b ] -> read_lines (a :: left) (b :: right) ic
+
| _ -> failwith "invalid")
+
| None ->
+
close_in ic;
+
(List.sort compare left, List.sort compare right)
+
+
let calc_sum left right =
+
List.map2 ( - ) left right |> List.map abs |> List.fold_left ( + ) 0
+
+
let calc_sim left right =
+
List.map
+
(fun x -> x * (List.filter (fun y -> x == y) right |> List.length))
+
left
+
|> List.fold_left ( + ) 0
+
+
let () =
+
let left, right = open_in filename |> read_lines [] [] in
+
calc_sum left right |> Printf.sprintf "Sum %d" |> print_endline;
+
calc_sim left right |> Printf.sprintf "Part 2 Simularity %d" |> print_endline
-1000
2024/day_01_input.txt
···
-
64430 75582
-
87936 20843
-
98310 72035
-
98142 69076
-
73170 50561
-
65508 20716
-
72642 84718
-
63792 89556
-
88319 66913
-
38149 43160
-
88982 10253
-
34137 95932
-
79589 92389
-
49164 98263
-
49746 92762
-
53896 43420
-
21240 95725
-
88691 37648
-
47697 66763
-
38234 98154
-
74901 20452
-
70760 11404
-
16084 74024
-
77408 32178
-
81054 45709
-
68478 92252
-
52984 55239
-
14952 20843
-
42548 69422
-
21427 20329
-
92508 81533
-
22650 76459
-
48388 81843
-
49540 25697
-
65666 12373
-
45713 16199
-
42419 10468
-
64757 30375
-
58273 43473
-
10576 20540
-
31508 42210
-
21718 52578
-
55862 92252
-
29892 20716
-
35978 50547
-
18953 43473
-
51379 31038
-
16417 83883
-
66023 24679
-
28031 55268
-
69178 45771
-
56463 93602
-
33368 20147
-
16434 43473
-
97551 73418
-
46904 19198
-
25697 60996
-
37363 35781
-
11282 92252
-
35209 72035
-
66763 27103
-
85271 69322
-
33759 94633
-
17008 83883
-
97073 21870
-
24061 55053
-
53095 92252
-
12374 92762
-
25571 51808
-
37178 10953
-
88710 67938
-
64979 48065
-
49734 80760
-
73780 81067
-
55802 37177
-
78442 90493
-
97220 32178
-
39845 25697
-
27359 39117
-
66371 17473
-
50236 82028
-
54937 41865
-
11989 69107
-
61602 78467
-
83376 75395
-
84545 42210
-
24250 55446
-
29247 37936
-
48897 21653
-
89795 26960
-
60748 39097
-
32745 20716
-
66967 43473
-
63073 21718
-
71949 83590
-
30876 83883
-
43640 21718
-
37703 37133
-
19198 43473
-
43605 42609
-
35757 54910
-
20959 23081
-
29302 52984
-
56530 82308
-
95611 42671
-
60818 39516
-
18302 61539
-
25344 25697
-
91669 80760
-
67090 98098
-
44280 59977
-
17423 65400
-
56952 78467
-
23067 72035
-
45925 76133
-
84963 87050
-
29175 32178
-
89724 74826
-
85282 49648
-
86399 77097
-
34615 52896
-
47895 52578
-
68604 72035
-
30689 20716
-
66582 92521
-
72688 76209
-
47389 87846
-
66229 64769
-
32205 70746
-
95885 83814
-
56440 19941
-
87356 21436
-
67641 92252
-
20678 45960
-
31065 75217
-
95705 69076
-
90463 44022
-
51401 36472
-
73186 48543
-
45910 49551
-
26499 84718
-
94815 20415
-
46840 43473
-
47483 94710
-
11870 43473
-
28799 14080
-
24832 79589
-
83929 51875
-
39407 53253
-
73986 62364
-
66614 44738
-
75392 21277
-
70204 55613
-
99686 21718
-
85726 19198
-
47638 92252
-
81669 30026
-
70370 60748
-
53783 11004
-
54371 35046
-
72567 87098
-
87969 32178
-
81067 60748
-
61446 98023
-
76471 92252
-
64431 25697
-
42080 80760
-
14486 13466
-
82716 52984
-
49351 15539
-
36159 15090
-
56913 88064
-
96843 44738
-
66639 89714
-
91239 42210
-
65785 76459
-
49114 86785
-
58894 41438
-
45307 79589
-
38693 80286
-
21963 52722
-
46504 44738
-
22201 84718
-
15556 61539
-
86120 86377
-
21887 81067
-
32242 92762
-
61544 37648
-
29147 73990
-
24239 62852
-
30163 48652
-
95900 83883
-
71487 60590
-
69076 47403
-
68557 70174
-
80423 85726
-
92873 10245
-
59391 87955
-
15416 80760
-
90803 70939
-
25081 81067
-
10323 46564
-
75418 60748
-
92762 43409
-
32178 20716
-
72035 25025
-
30702 11797
-
70262 20843
-
10801 60970
-
69510 56933
-
38295 27487
-
57266 71215
-
39071 92542
-
20540 21718
-
57027 81151
-
77729 90745
-
96980 28442
-
65961 19198
-
55385 82179
-
86139 91952
-
72873 61041
-
95457 44738
-
84209 83883
-
93774 92762
-
67731 14982
-
81176 26473
-
50239 13336
-
74772 81067
-
91982 80690
-
40004 89466
-
52769 72035
-
40693 42210
-
50506 26856
-
71898 68597
-
99210 32178
-
45079 53505
-
17581 94678
-
83211 28309
-
52582 50257
-
62597 92762
-
20716 38593
-
18630 73077
-
20835 30809
-
75099 18088
-
56109 42210
-
31503 72884
-
60392 83711
-
26052 17008
-
49938 20540
-
16604 85679
-
94700 29256
-
52740 69859
-
84337 25174
-
46814 64723
-
68259 34542
-
79927 18036
-
57010 78467
-
73378 90472
-
83131 30214
-
84704 37648
-
36494 40475
-
43734 90827
-
85678 61539
-
65197 81067
-
80121 24363
-
97038 85579
-
59873 72035
-
54928 17827
-
46120 33920
-
68979 32133
-
88690 90929
-
38840 92762
-
66900 67817
-
59182 85839
-
15538 81151
-
60198 54586
-
57452 71692
-
12212 79875
-
62853 67888
-
67754 53532
-
86454 52984
-
94629 92403
-
80986 30351
-
76966 77097
-
78419 92762
-
12343 20540
-
26294 75804
-
18240 23339
-
72971 58631
-
69610 81067
-
96198 31081
-
25389 13525
-
29670 76459
-
39477 79589
-
58028 21718
-
77097 27842
-
95031 78097
-
32844 43989
-
12618 96437
-
82959 43688
-
40438 20716
-
58980 80760
-
26176 39610
-
81464 24846
-
31997 35781
-
82384 83883
-
54010 20844
-
63959 45452
-
43239 16738
-
45375 87524
-
36278 95715
-
96601 80760
-
82935 27550
-
13493 58808
-
17988 92762
-
59523 67650
-
69133 44178
-
59959 77097
-
89068 20843
-
31067 36430
-
55300 23059
-
36759 48277
-
91317 46947
-
58240 85726
-
22368 92356
-
60765 84751
-
72733 26888
-
19688 62073
-
90158 57933
-
11176 28442
-
53051 50769
-
76632 97012
-
98132 80760
-
73098 83281
-
46753 25697
-
44849 15301
-
62899 74187
-
71237 81067
-
56670 20649
-
18624 82808
-
32614 34732
-
98452 76464
-
51626 35781
-
55943 89986
-
59443 72035
-
96628 73132
-
77928 45659
-
76256 74161
-
13944 94048
-
12446 20843
-
70331 46956
-
46097 39097
-
46415 83883
-
29460 44307
-
73685 89046
-
53969 52578
-
82435 40606
-
65769 45167
-
89700 50621
-
80281 43473
-
97402 60748
-
11127 87361
-
50692 60748
-
43989 61539
-
40319 11156
-
85446 71698
-
58820 89274
-
77545 80760
-
34103 37577
-
83858 33573
-
23402 61991
-
82147 48488
-
15719 80760
-
16987 22112
-
41519 29897
-
29178 47932
-
92027 25765
-
92998 92252
-
52103 77097
-
64962 32490
-
81888 29503
-
92252 57018
-
88397 32178
-
13852 89473
-
73603 20540
-
95704 32178
-
36045 46227
-
38834 72035
-
85241 60748
-
94036 77097
-
90984 92762
-
44738 44738
-
48078 76459
-
40832 24578
-
78789 78634
-
42210 92252
-
16967 61124
-
76704 65696
-
69647 51055
-
41412 35781
-
50365 63580
-
33725 79129
-
90837 17116
-
25000 52578
-
55672 81986
-
50507 73820
-
82260 92762
-
58284 33808
-
79462 43473
-
76384 23808
-
49652 81151
-
24386 44424
-
76993 77003
-
11077 79166
-
58255 43047
-
81122 28757
-
63846 30206
-
69361 76459
-
19338 35781
-
28857 37648
-
33643 89353
-
61915 52984
-
54227 18855
-
16162 92252
-
21546 60184
-
15120 61012
-
63185 68250
-
44681 89512
-
25644 80760
-
12963 42210
-
41952 17962
-
46649 89796
-
46412 68405
-
32401 61539
-
81393 20540
-
13678 78467
-
68025 99213
-
27934 35781
-
91794 61539
-
98970 71396
-
18314 69562
-
19908 97620
-
69828 60768
-
89139 36928
-
71402 25697
-
64070 32178
-
55145 38138
-
65851 25697
-
98808 67787
-
57244 21718
-
18541 79589
-
88135 84731
-
77694 61539
-
52608 83313
-
67204 91715
-
47233 39097
-
99317 37648
-
84111 30506
-
71316 39097
-
24604 61539
-
28504 58867
-
64952 35781
-
72718 43275
-
55834 44738
-
30446 92252
-
37415 29159
-
41743 78467
-
26267 59675
-
33658 11262
-
50677 44738
-
71609 78322
-
26047 52977
-
31723 21718
-
44390 72035
-
53788 89828
-
84829 60748
-
57972 32178
-
93241 27703
-
38576 20540
-
44958 84718
-
94256 47639
-
41263 85109
-
75946 67054
-
20333 77097
-
55509 95680
-
39858 40117
-
88032 21718
-
98778 76619
-
89995 18411
-
28456 62071
-
61789 72035
-
78073 70754
-
77073 31065
-
86999 21718
-
42298 40782
-
50995 43473
-
32947 20843
-
40617 22994
-
84633 40716
-
19900 28627
-
17816 68538
-
32530 25156
-
17673 77097
-
38208 77097
-
54880 78467
-
10746 36942
-
36110 23213
-
80179 61360
-
55819 35781
-
28442 79589
-
88289 92066
-
83346 28171
-
37597 74543
-
45978 84718
-
52946 28442
-
64609 92762
-
24593 39097
-
92409 92252
-
60718 60223
-
26498 70229
-
14277 35781
-
90961 79589
-
19915 79965
-
68301 14227
-
56321 80760
-
15922 67051
-
80444 72035
-
49913 39097
-
97519 83883
-
81867 76459
-
72049 32178
-
98003 81151
-
29774 84718
-
83596 92936
-
65711 41869
-
94799 72035
-
52228 74833
-
35681 15295
-
86161 47398
-
99764 44738
-
13342 66763
-
19557 41667
-
85701 24392
-
67265 54679
-
24579 60748
-
99212 72720
-
11279 20540
-
81879 36662
-
42791 12924
-
98914 75630
-
29879 52984
-
87696 69076
-
54212 32065
-
30014 76459
-
43433 64434
-
31827 43749
-
27323 32614
-
47887 78467
-
12778 90971
-
38504 25697
-
11985 12152
-
88281 32178
-
60313 18405
-
84487 44738
-
10753 76459
-
11349 59672
-
58532 69076
-
37463 81151
-
74158 17588
-
47713 16319
-
52617 99026
-
75642 54241
-
86070 84718
-
89264 68926
-
13839 84718
-
16425 22018
-
15973 35781
-
97324 39267
-
74858 93659
-
30114 82028
-
91599 92765
-
47093 37648
-
50285 60748
-
14846 15314
-
89741 83883
-
27133 42151
-
38409 39097
-
34370 60748
-
43982 69423
-
22858 20843
-
57345 34197
-
40807 61764
-
75561 28363
-
14111 34713
-
49442 81067
-
61122 53151
-
97636 25131
-
43772 25697
-
55030 83358
-
52741 23263
-
74578 81559
-
50656 34834
-
62586 23884
-
99380 73924
-
41885 46691
-
95691 23340
-
68929 18409
-
32180 25515
-
27880 69609
-
15658 25697
-
40225 76459
-
54028 95026
-
51248 83206
-
55585 44495
-
34730 36987
-
72713 43473
-
48744 43473
-
50628 44738
-
66099 81067
-
84471 82826
-
74726 43646
-
63777 80760
-
38782 10687
-
62565 32178
-
30082 36088
-
66224 25697
-
17798 39097
-
65148 37648
-
50731 66803
-
60010 16037
-
71057 20540
-
79087 47464
-
63666 37648
-
61860 74023
-
46372 33274
-
40076 97575
-
81205 25697
-
29232 48419
-
91161 25173
-
80675 51474
-
45465 75816
-
80432 80760
-
84712 73906
-
32924 96322
-
27386 25697
-
35781 80760
-
28248 77822
-
33634 48276
-
93878 48409
-
26858 59450
-
63868 42103
-
94063 13352
-
26657 52984
-
65635 92762
-
47508 11445
-
87138 83597
-
33328 62612
-
70031 85726
-
81151 23518
-
42263 32662
-
85424 71871
-
21504 72035
-
76646 90060
-
36770 31991
-
76459 43473
-
58215 44495
-
20418 86232
-
68543 81067
-
71082 52984
-
24484 86494
-
70941 98749
-
71613 24014
-
98938 35781
-
42671 25697
-
11798 25697
-
55015 81601
-
92532 78131
-
10415 43260
-
89920 11599
-
36610 30402
-
11196 46252
-
61243 80760
-
47794 15435
-
10054 40848
-
90743 52578
-
12980 92252
-
43206 92762
-
23376 69724
-
45693 77097
-
79629 70562
-
69524 20540
-
30811 48749
-
76688 51485
-
50584 77097
-
46173 35918
-
22138 92762
-
98933 52984
-
55451 42210
-
97723 34368
-
39097 60748
-
29080 78467
-
58962 78467
-
71265 13782
-
14559 20716
-
14366 20540
-
68344 72035
-
48432 88048
-
38005 43473
-
85989 93533
-
98422 83883
-
20685 80045
-
69814 72035
-
11356 28819
-
39329 20843
-
52898 19198
-
43135 25697
-
20409 25697
-
52446 34899
-
63515 84718
-
19371 20540
-
16430 20540
-
45803 74304
-
66092 33425
-
80760 95646
-
64945 37648
-
43951 78467
-
87271 17766
-
91354 75924
-
32506 37648
-
15452 79052
-
87783 42991
-
90937 75439
-
68208 97868
-
91228 92252
-
35773 92762
-
74252 32178
-
96573 74280
-
29447 31544
-
61206 62085
-
75242 75894
-
76850 77838
-
22095 24247
-
78467 55285
-
27611 20540
-
18974 84363
-
74621 83883
-
19469 19323
-
26785 25697
-
99803 77726
-
96042 21449
-
61772 39950
-
21746 79309
-
44817 14075
-
65817 54251
-
90360 84880
-
40529 83883
-
63336 62916
-
57489 39191
-
41980 76639
-
61947 69076
-
72393 92252
-
72994 20540
-
38393 42671
-
61264 25490
-
28725 27770
-
68461 83883
-
68050 19198
-
97146 44738
-
13195 32178
-
48395 14399
-
55269 12291
-
43616 62312
-
76357 19177
-
50496 55565
-
97083 24002
-
32806 69076
-
71713 47157
-
91635 92762
-
23121 20540
-
27917 92762
-
61595 77858
-
96038 78467
-
51300 30664
-
99332 39795
-
49914 33272
-
87083 54823
-
39253 99039
-
98686 23548
-
63961 20540
-
76429 42671
-
84657 78621
-
18867 58861
-
28534 92703
-
20843 72035
-
40011 42210
-
28716 35781
-
64363 94627
-
41215 39358
-
74285 77374
-
37245 20843
-
53602 35781
-
73935 90042
-
35283 25697
-
84164 92252
-
26264 19198
-
49434 92252
-
67281 76459
-
47315 37648
-
21216 70552
-
57730 44738
-
55530 83883
-
23807 60687
-
79378 65500
-
81270 19442
-
89580 78935
-
81287 76459
-
37987 82563
-
29721 71638
-
76282 93445
-
82973 44738
-
43095 76459
-
57911 42481
-
15665 30034
-
97099 20843
-
77440 61539
-
61564 40937
-
38697 50046
-
91585 71537
-
66058 44507
-
96221 92762
-
80464 31623
-
52031 88911
-
74599 81151
-
44495 81151
-
37781 50336
-
42333 92252
-
25393 37648
-
31875 40879
-
25513 60748
-
52578 20540
-
83883 67476
-
13961 80760
-
86512 72429
-
52957 37648
-
70656 20843
-
32267 78467
-
67751 23702
-
83650 76459
-
11249 44738
-
82052 44240
-
60178 19059
-
78052 80760
-
92063 42210
-
47149 42671
-
82429 61080
-
24749 68627
-
26862 32614
-
77843 56271
-
24471 41563
-
15084 62867
-
15444 43417
-
15492 61539
-
22651 80760
-
62625 21763
-
49448 48757
-
47125 36097
-
45650 21134
-
76382 40592
-
28236 81067
-
24712 28270
-
26908 63823
-
51661 92252
-
33112 54575
-
59018 52984
-
12648 35781
-
47726 76268
-
16833 15099
-
17720 24491
-
64016 31467
-
62900 37648
-
66411 97080
-
47653 32178
-
78845 16864
-
98508 26852
-
83446 10379
-
50837 40936
-
85485 63694
-
41709 37648
-
84178 28689
-
27821 57472
-
89199 43473
-
95089 43852
-
80677 20716
-
84551 20125
-
84718 11853
-
14520 20843
-
61473 92762
-
69357 37320
-
36592 24917
-
88660 35781
-
92407 20540
-
17708 20540
-
27217 12607
-
51540 44495
-
93978 77706
-
83790 34181
-
46160 69737
-
21508 54282
-
20593 84718
-
12368 38902
-
46760 16081
-
46693 75780
-
90007 89913
-
63689 76234
-
98781 92745
-
77580 44738
-
24571 39242
-
37950 98910
-
63333 76587
-
14765 74779
-
41979 55432
-
65602 13148
-
34240 32614
-
40909 22506
-
25236 78757
-
56096 32614
-
85735 39877
-
37637 52969
-
34344 33132
-
53389 47303
-
66490 36750
-
18024 48801
-
45153 91679
-
94052 20540
-
67564 74190
-
54685 84718
-
89848 69076
-
15698 44738
-
67033 35486
-
23435 24004
-
99883 69819
-
32300 68680
-
82028 21625
-
19382 78452
-
40073 37648
-
86881 31642
-
42474 41279
-
59165 80760
-
60370 34541
-
74295 73389
-
98654 42210
-
87697 39399
-
68417 55320
-
32125 87304
-
23153 51288
-
32963 12352
-
18366 57673
-
74792 50327
-
78281 43473
-
41693 49359
-
41188 35781
-
19719 72035
-
44395 72831
-
75495 78467
-
14585 21023
-
94358 23804
-
13464 23423
-
58483 85726
-
44941 69076
-
91349 12344
-
95485 83883
-
58981 65861
-
43473 61539
-
51945 69762
-
40385 44738
-
32646 42174
-
73150 81067
-
12154 37648
-
55441 20843
-
98025 39097
-
15339 38796
-
31543 42210
-
65949 42245
-
31434 32614
-
57312 57203
-
91833 76885
-
23286 52984
-
58987 32178
-
12591 37648
-
37648 32316
-
97542 35781
-
33381 44140
-
69851 92540
-
60076 19198
-
86697 32614
-
25533 96431
-
68777 15175
-
47390 75651
-
94550 80760
-
61539 20843
+54
2024/day_02.f90
···
+
program day_02
+
implicit none
+
logical :: is_decrement, fail
+
integer :: io, i,x, spaces, res
+
integer, dimension(:), allocatable :: list
+
character(len=100) :: line
+
+
open(newunit=io, file='./day_02_input.txt', status='old', action='read')
+
+
res = 0
+
do i = 1, 1000
+
read(io, '(a)') line ! reading the line
+
spaces = 1 ! reset space count
+
do x = 1, len(trim(line))
+
! counting spaces to see how big of an array we need to allocate
+
if(iachar(line(x:x))== 32 ) then
+
spaces = spaces+1
+
end if
+
end do
+
+
allocate(list(spaces))
+
read(line, *) list !reading the ints into an array
+
fail = .false.
+
+
do x = 1, size(list) -1
+
if (list(x) == list(x+1)) then
+
fail = .true.
+
exit
+
end if
+
if(x == 1 .and. list(x) > list(x+1)) then
+
is_decrement = .true.
+
else if (x==1 .and. list(x) < list(x+1)) then
+
is_decrement = .false.
+
end if
+
+
if(is_decrement) then
+
if (list(x) < list(x+1) .or. abs(list(x) - list(x+1)) > 3) then
+
fail = .true.
+
exit
+
end if
+
else
+
if (list(x) > list(x+1) .or. abs(list(x) - list(x+1)) > 3) then
+
fail = .true.
+
exit
+
end if
+
end if
+
end do
+
if (fail .eqv. .false.) then
+
res = res + 1
+
endif
+
deallocate(list)
+
end do
+
print*, res
+
end program day_02
+50
2024/day_02.ml
···
+
let filename = "./day_02_input.txt"
+
let try_read ic = try Some (input_line ic) with End_of_file -> None
+
+
let is_values_safe a b direction =
+
match direction with
+
| "up" -> a < b && abs (a - b) < 4
+
| "down" -> a > b && abs (a - b) < 4
+
| _ -> false
+
+
let direction a b = if a < b then "up" else "down"
+
+
let is_line_safe list =
+
let a, b = (List.hd list, List.tl list |> List.hd) in
+
let direction = direction a b in
+
List.fold_left
+
(fun (acc, prev) x ->
+
if prev > -1 then (acc && is_values_safe prev x direction, x) else (acc, x))
+
(true, -1) list
+
|> fst
+
+
let is_line_safe_part_2 list =
+
List.mapi
+
(fun i _ -> List.filteri (fun j _ -> j <> i) list |> is_line_safe)
+
list
+
|> List.exists (fun x -> x)
+
+
let calculate_safe_score ic is_line_safe =
+
let rec calculate acc =
+
match try_read ic with
+
| Some line -> (
+
match
+
is_line_safe (String.split_on_char ' ' line |> List.map int_of_string)
+
with
+
| true -> calculate (acc + 1)
+
| false -> calculate acc)
+
| None ->
+
close_in ic;
+
acc
+
in
+
calculate 0
+
+
let () =
+
let ic = open_in filename in
+
calculate_safe_score ic is_line_safe
+
|> Printf.sprintf "Safe %d" |> print_endline;
+
+
let ic = open_in filename in
+
calculate_safe_score ic is_line_safe_part_2
+
|> Printf.sprintf "Part 2 Safe %d"
+
|> print_endline
+90
2024/day_02_part_2.f90
···
+
module day2_utils
+
implicit none
+
contains
+
subroutine is_safe(list, res)
+
implicit none
+
integer, allocatable, intent(in) :: list(:)
+
logical, intent(out):: res
+
integer :: i, diff
+
logical is_decrement
+
+
res = .true.
+
is_decrement = .false.
+
do i = 1, size(list) - 1
+
if(i == 1 .and. list(i) > list(i+1)) then
+
is_decrement = .true.
+
end if
+
diff = abs(list(i) - list(i+1))
+
if(is_decrement) then
+
if (list(i) < list(i+1) .or. diff > 3 .or. diff < 1) then
+
res = .false.
+
exit
+
end if
+
else
+
if (list(i) > list(i+1) .or. diff > 3 .or. diff < 1) then
+
res = .false.
+
exit
+
end if
+
end if
+
end do
+
end subroutine is_safe
+
subroutine safe_with_dampener(list, res)
+
implicit none
+
integer, allocatable, intent(in) :: list(:)
+
integer, allocatable :: work(:)
+
logical, intent(out):: res
+
integer :: i, x, idx
+
res = .true.
+
call is_safe(list, res)
+
if(.not. res) then
+
allocate(work(size(list)-1))
+
do i = 1, size(list)
+
idx = 1
+
do x = 1, size(list)
+
if (x /= i) then
+
work(idx) = list(x)
+
idx = idx + 1
+
end if
+
end do
+
res = .true.
+
call is_safe(work, res)
+
if(res) then
+
exit
+
end if
+
end do
+
end if
+
end subroutine safe_with_dampener
+
end module day2_utils
+
+
program day_02_part_2
+
use day2_utils
+
implicit none
+
logical :: is_decrement, safe
+
integer :: io, i, x, spaces, res
+
integer, dimension(:), allocatable :: list
+
character(len=100) :: line
+
+
open(newunit=io, file='./day_02_input.txt', status='old', action='read')
+
+
res = 0
+
do i = 1, 1000
+
read(io, '(a)') line ! reading the line
+
spaces = 1 ! reset space count
+
do x = 1, len(trim(line))
+
! counting spaces to see how big of an array we need to allocate
+
if(iachar(line(x:x))== 32 ) then
+
spaces = spaces+1
+
end if
+
end do
+
+
allocate(list(spaces))
+
read(line, *) list !reading the ints into an array
+
safe = .true. !set fail to false by default
+
call safe_with_dampener(list, safe) ! check if the array has a fail idx
+
if (safe) then
+
res = res + 1
+
endif
+
deallocate(list)
+
end do
+
print*, res
+
end program day_02_part_2
+65
2024/day_03.f90
···
+
program day_03
+
implicit none
+
logical :: find_a
+
integer ::io, ios, a, b, state, res
+
character(len=1) :: c
+
character(len=10) :: buffer
+
character(len=4) :: mul_cmd = 'mul('
+
+
res = 0
+
open(newunit=io, file='./day_03_input.txt', status='old', action='read', access='stream')
+
state = 0 ! 0 = find command, 1 = find number, 2 = calculate
+
find_a = .true.
+
buffer = ''
+
do
+
read(io, iostat=ios) c
+
if (ios /= 0) exit
+
select case(state)
+
case (0) ! find command
+
buffer = trim(buffer) // c
+
if(buffer == mul_cmd) then
+
state = 1
+
buffer = ''
+
else if(trim(buffer) /= mul_cmd(1:len(trim(buffer)))) then
+
state = 0
+
buffer = ''
+
end if
+
case (1) ! find digits
+
select case (iachar(c))
+
case (48:57) ! 0-9
+
buffer = trim(buffer) // c
+
case (44) ! ,
+
if (find_a .and. len(trim(buffer)) > 0) then
+
read(buffer, *) a
+
buffer = ''
+
find_a = .false.
+
else
+
state = 0 ! invalid
+
find_a = .true.
+
buffer = ''
+
end if
+
case (41) ! )
+
if(.not. find_a .and. len(trim(buffer)) > 0) then
+
read(buffer, *) b
+
state = 2
+
find_a = .true.
+
buffer = ''
+
else
+
state = 0
+
find_a = .true.
+
buffer = ''
+
end if
+
case default
+
state = 0
+
find_a = .true.
+
buffer = ''
+
end select
+
end select
+
if(state == 2) then
+
res = res + (a * b)
+
state = 0
+
buffer = ''
+
end if
+
end do
+
print*, res
+
end program day_03
+45
2024/day_03.ml
···
+
let filename = "./day_03_input.txt"
+
let try_read ic = try Some (input_line ic) with End_of_file -> None
+
+
let read_file ic =
+
let rec read acc =
+
match try_read ic with
+
| Some line -> read (line :: acc)
+
| None ->
+
close_in ic;
+
acc
+
in
+
read [] |> List.rev |> String.concat ""
+
+
let regex_mul = Str.regexp "mul(\\([0-9]+\\),\\([0-9]+\\))"
+
let regex_mul_part_2 = Str.regexp "mul(\\([0-9]+\\),\\([0-9]+\\))\\|don't()"
+
let regex_do_part_2 = Str.regexp "do()"
+
+
let calculate_total str regexp =
+
let rec calculate str regexp acc =
+
try
+
let _ = Str.search_forward regexp str 0 in
+
let cmd = Str.matched_group 0 str in
+
let new_str =
+
String.sub str (Str.match_end ()) (String.length str - Str.match_end ())
+
in
+
match cmd with
+
| "do()" -> calculate new_str regex_mul_part_2 acc
+
| "don't()" -> calculate new_str regex_do_part_2 acc
+
| cmd when String.starts_with ~prefix:"mul" cmd ->
+
let a = Str.matched_group 1 str |> int_of_string in
+
let b = Str.matched_group 2 str |> int_of_string in
+
calculate new_str regexp (acc + (a * b))
+
| _ -> acc
+
with Not_found -> acc
+
in
+
calculate str regexp 0
+
+
let () =
+
let ic = open_in filename in
+
let data = read_file ic in
+
calculate_total data regex_mul |> Printf.sprintf "Sum %d" |> print_endline;
+
+
calculate_total data regex_mul_part_2
+
|> Printf.sprintf "Part 2 Sum %d"
+
|> print_endline
+83
2024/day_03_part_2.f90
···
+
program day_03_part_2
+
implicit none
+
logical :: find_a, is_dont
+
integer ::io, ios, a, b, state, res
+
character(len=1) :: c
+
character(len=10) :: buffer
+
character(len=4) :: mul_cmd = 'mul('
+
character(len=7) :: dont_cmd = "don't()"
+
character(len=4) :: do_cmd = 'do()'
+
+
res = 0
+
open(newunit=io, file='./day_03_input.txt', status='old', action='read', access='stream')
+
state = 0 ! 0 = find command, 1 = find number, 2 = calculate
+
find_a = .true.
+
is_dont = .false.
+
buffer = ''
+
do
+
read(io, iostat=ios) c
+
if (ios /= 0) exit
+
select case(state)
+
case (0) ! find command
+
buffer = trim(buffer) // c
+
if(is_dont) then
+
if (trim(buffer) == do_cmd) then
+
state = 0
+
buffer = ''
+
is_dont = .false.
+
else if (trim(buffer) /= do_cmd(1:len(trim(buffer)))) then
+
state = 0
+
buffer = ''
+
end if
+
else
+
if (trim(buffer) == dont_cmd) then
+
state = 0
+
buffer = ''
+
is_dont = .true.
+
else if(trim(buffer) == mul_cmd) then
+
state = 1
+
buffer = ''
+
else if(trim(buffer) /= mul_cmd(1:len(trim(buffer))) .and. trim(buffer) /= dont_cmd(1:len(trim(buffer)))) then
+
state = 0
+
buffer = ''
+
end if
+
end if
+
case (1) ! find digits
+
select case (iachar(c))
+
case (48:57) ! 0-9
+
buffer = trim(buffer) // c
+
case (44) ! ,
+
if (find_a .and. len(trim(buffer)) > 0) then
+
read(buffer, *) a
+
buffer = ''
+
find_a = .false.
+
else
+
state = 0 ! invalid
+
find_a = .true.
+
buffer = ''
+
end if
+
case (41) ! )
+
if(.not. find_a .and. len(trim(buffer)) > 0) then
+
read(buffer, *) b
+
state = 2
+
find_a = .true.
+
buffer = ''
+
else
+
state = 0
+
find_a = .true.
+
buffer = ''
+
end if
+
case default
+
state = 0
+
find_a = .true.
+
buffer = ''
+
end select
+
end select
+
if(state == 2) then
+
res = res + (a * b)
+
state = 0
+
buffer = ''
+
end if
+
end do
+
print*, res
+
end program day_03_part_2
+78
2024/day_04.f90
···
+
module day_04_utils
+
implicit none
+
contains
+
recursive function find_xmas(arr, row, col,row_dir, col_dir, search_letter) result(found)
+
implicit none
+
character(len=140), intent(in), allocatable :: arr(:)
+
character(len=1), intent(in) :: search_letter
+
integer, intent(in) :: row, col, row_dir, col_dir
+
integer :: new_row, new_col
+
logical :: found
+
+
if(arr(row)(col:col) == search_letter) then
+
if(search_letter == 'S') then
+
found = .true.
+
else
+
new_row = row + row_dir
+
new_col = col + col_dir
+
if(new_row > len(arr(row)) .or. new_row < 1 .or. new_col > size(arr) .or. new_col < 1) then
+
found = .false.
+
else
+
select case(search_letter)
+
case('M')
+
found = find_xmas(arr, new_row, new_col, row_dir, col_dir, 'A')
+
case('A')
+
found = find_xmas(arr, new_row, new_col, row_dir, col_dir, 'S')
+
end select
+
end if
+
end if
+
else
+
found = .false.
+
end if
+
end function find_xmas
+
end module day_04_utils
+
program day_04
+
use day_04_utils
+
implicit none
+
character(len=140) , allocatable :: lines(:)
+
integer :: io, row, col, score, z
+
logical :: found
+
+
score = 0
+
open(newunit=io, file='./day_04_input.txt', status='old', action='read')
+
allocate(lines(140))
+
read(io, '(a)') lines
+
do row = 1, size(lines)
+
do col = 1, len(lines(row))
+
if (lines(row)(col:col) == 'X') then
+
do z = 1, 8
+
found = .false.
+
select case (z)
+
case(1)
+
found = find_xmas(lines, row, col-1, 0, -1, 'M')
+
case(2)
+
found = find_xmas(lines, row-1, col-1, -1, -1, 'M')
+
case(3)
+
found = find_xmas(lines, row-1, col, -1, 0, 'M')
+
case(4)
+
found = find_xmas(lines, row-1, col+1, -1, 1, 'M')
+
case(5)
+
found = find_xmas(lines, row, col+1, 0, 1, 'M')
+
case(6)
+
found = find_xmas(lines, row+1, col+1, 1, 1, 'M')
+
case(7)
+
found = find_xmas(lines, row+1, col, 1, 0, 'M')
+
case(8)
+
found = find_xmas(lines, row+1, col-1, 1, -1, 'M')
+
end select
+
if(found) then
+
score = score + 1
+
end if
+
end do
+
end if
+
end do
+
end do
+
deallocate(lines)
+
print*, score
+
+
end program day_04
+39
2024/day_04_part_2.f90
···
+
program day_04
+
implicit none
+
character(len=140) :: lines(140)
+
character(len=1) :: c
+
integer :: io, row, col, score, z
+
logical :: left_m, right_m
+
+
left_m = .false.
+
right_m = .false.
+
score = 0
+
open(newunit=io, file='./day_04_input.txt', status='old', action='read')
+
read(io, '(a)') lines
+
do row = 2, size(lines) - 1
+
do col = 2, len(lines(row)) - 1
+
if (lines(row)(col:col) == 'A') then
+
c = lines(row-1)(col-1:col-1)
+
if (c == 'S' .or. c == 'M') then
+
left_m = c == 'M'
+
c = lines(row-1)(col+1:col+1)
+
if (c == 'S' .or. c == 'M') then
+
right_m = c == 'M'
+
c = lines(row+1)(col-1:col-1)
+
if (right_m .and. c == 'S' .or. (.not. right_m .and. c == 'M')) then
+
c = lines(row+1)(col+1:col+1)
+
if (left_m .and. c == 'S' .or. (.not. left_m .and. c =='M')) then
+
score = score + 1
+
end if
+
end if
+
end if
+
end if
+
end if
+
left_m = .false.
+
right_m = .false.
+
c = ''
+
end do
+
end do
+
print*, score
+
+
end program day_04
+193
2024/day_05.f90
···
+
module day_05_utils
+
implicit none
+
contains
+
subroutine append_to_integer_array(arr, val)
+
implicit none
+
integer, allocatable, intent(inout) :: arr(:)
+
integer, intent(in) :: val
+
integer, allocatable :: temp(:)
+
if(.not. allocated(arr)) then
+
ERROR STOP 'Array not allocated'
+
end if
+
allocate(temp(size(arr) + 1))
+
temp(1:size(arr)) = arr
+
temp(size(arr) + 1) = val
+
call move_alloc(temp, arr)
+
end subroutine append_to_integer_array
+
function fix_and_get_middle_value(arr, left, right) result(res)
+
! we are going to fix the array swapping until its right
+
! there's probably a better way maybe? but I just want to get it done
+
implicit none
+
integer, allocatable, intent(in) :: arr(:), left(:), right(:)
+
integer, allocatable :: work(:), copy(:)
+
integer :: res, i, j, tmp
+
logical :: found
+
allocate(copy(size(arr)))
+
copy = arr
+
do
+
found = .false.
+
outer: do i = 1, size(copy)
+
if(i+1 < size(copy)) then ! if we can check forward
+
if(allocated(work)) then
+
deallocate(work)
+
end if
+
do j = 1, size(right) ! find value in right and save left to work
+
if (copy(i) == right(j)) then
+
if(.not. allocated(work)) then
+
allocate(work(1))
+
work(1) = left(j)
+
else
+
call append_to_integer_array(work, left(j))
+
end if
+
end if
+
end do
+
do j = i+1, size(copy)
+
if(any(work == copy(j))) then
+
tmp = copy(i)
+
copy(i) = copy(j)
+
copy(j) = tmp
+
found = .true.
+
exit outer
+
end if
+
end do
+
end if
+
+
if(.not. found) then ! if we are still valid lets keep going
+
if(allocated(work)) then
+
deallocate(work)
+
end if
+
if(i-1 > 0) then ! if we can check backwards
+
do j = 1, size(left) ! find value in left and save left to work
+
+
if (copy(i) == left(j)) then
+
if(.not. allocated(work)) then
+
allocate(work(1))
+
work(1) = right(j)
+
else
+
call append_to_integer_array(work, right(j))
+
end if
+
end if
+
end do
+
do j = 1, size(copy)
+
if(any(work == copy(j) .and. j < i)) then
+
tmp = copy(i)
+
copy(i) = copy(j)
+
copy(j) = tmp
+
found = .true.
+
exit outer
+
end if
+
end do
+
end if
+
else
+
exit outer
+
end if
+
end do outer
+
if(.not. found) exit
+
end do
+
res = copy((size(copy) + 1)/2)
+
deallocate(copy)
+
if(allocated(work)) then
+
deallocate(work)
+
end if
+
end function fix_and_get_middle_value
+
end module day_05_utils
+
program day_05
+
use day_05_utils
+
implicit none
+
integer :: io, ios, idx, a, b, ct, i, j, res, res_part2
+
integer, allocatable :: left(:), right(:), print_list(:), work(:)
+
character(len=100) ::line
+
logical :: found
+
+
open(newunit=io, file='./day_05_input.txt', status='old', action='read')
+
res = 0
+
res_part2 = 0
+
do
+
read(io, '(a)', iostat=ios) line
+
if(ios /= 0) exit !eof
+
idx = index(line, '|')
+
if(idx > 0) then ! rules
+
read(line(1:idx-1), *) a
+
read(line(idx+1:), *) b
+
if(.not. allocated(left)) then
+
allocate(left(1))
+
left(1) = a
+
else
+
call append_to_integer_array(left, a)
+
end if
+
if(.not. allocated(right)) then
+
allocate(right(1))
+
right(1) = b
+
else
+
call append_to_integer_array(right, b)
+
end if
+
end if
+
idx = index(line, ',')
+
if (idx > 0 ) then ! print_list
+
ct = 1
+
do i = 1 , len_trim(line)
+
if(line(i:i) == ',') then
+
ct = ct + 1
+
end if
+
end do
+
allocate(print_list(ct))
+
read(line, *) print_list
+
found = .false.
+
do i = 1, size(print_list)
+
if(i+1 < size(print_list)) then ! if we can check forward
+
do j = 1, size(right) ! find value in right and save left to work
+
if (print_list(i) == right(j)) then
+
if(.not. allocated(work)) then
+
allocate(work(1))
+
work(1) = left(j)
+
else
+
call append_to_integer_array(work, left(j))
+
end if
+
end if
+
end do
+
do j = 1, size(work)
+
if(any(print_list(i+1:size(print_list)) == work(j))) then
+
found = .true.
+
exit
+
end if
+
end do
+
deallocate(work)
+
end if
+
if(.not. found) then ! if we are still valid lets keep going
+
if(i-1 > 0) then ! if we can check backwards
+
do j = 1, size(left) ! find value in left and save left to work
+
if (print_list(i) == left(j)) then
+
if(.not. allocated(work)) then
+
allocate(work(1))
+
work(1) = right(j)
+
else
+
call append_to_integer_array(work, right(j))
+
end if
+
end if
+
end do
+
do j = 1, size(work)
+
if(any(print_list(1:i-1) == work(j))) then
+
found = .true.
+
exit
+
end if
+
end do
+
deallocate(work)
+
end if
+
else
+
exit
+
end if
+
end do
+
if (.not. found) then
+
res = res + print_list((size(print_list) + 1)/2)
+
else
+
res_part2 = res_part2 + fix_and_get_middle_value(print_list, left, right)
+
end if
+
deallocate(print_list)
+
end if
+
end do
+
+
deallocate(left)
+
deallocate(right)
+
print*, "Result ", res
+
print*, "Part 2 Result ", res_part2
+
end program day_05
+64
2024/day_06.f90
···
+
program day_06
+
implicit none
+
character(len=130) :: line, lines(130)
+
integer:: io, x,y, xd,yd, i, ct
+
+
open(newunit=io, file='./day_06_input.txt', status='old', action='read')
+
read(io, '(a)') lines
+
+
ct = 0
+
! find starting position
+
do i = 1, size(lines)
+
if (index(lines(i), '^') > 0) then
+
y = i
+
x = index(lines(i), '^')
+
xd = 0
+
yd = -1
+
exit
+
end if
+
end do
+
+
! move until we leave the bounds when we hit a valid spot mark it with an X and increase count
+
do
+
! are we going out of bounds?
+
if (x+xd < 1 .or. x+xd > len(lines(y)) .or. y+yd < 1 .or. y+yd > size(lines)) then
+
ct = ct + 1
+
lines(y)(x:x) = 'X'
+
exit
+
end if
+
+
! try to move
+
select case(lines(y+yd)(x+xd:x+xd))
+
case('.')
+
! valid move
+
ct = ct + 1
+
x = x + xd
+
y = y + yd
+
lines(y)(x:x) = 'X'
+
case('X')
+
! valid move but we've been here before
+
x = x + xd
+
y = y + yd
+
case('#')
+
! we are blocked lets rotate 90 degrees
+
if(xd == 0 .and. yd == -1) then
+
xd = 1
+
yd = 0
+
else if (xd == 1 .and. yd == 0) then
+
xd = 0
+
yd = 1
+
else if (xd == 0 .and. yd == 1) then
+
xd = -1
+
yd = 0
+
else if (xd == -1 .and. yd == 0) then
+
xd = 0
+
yd = -1
+
end if
+
case default
+
exit
+
end select
+
end do
+
print*, lines
+
print*, "distinct: ", ct
+
end program day_06
+
+97
2024/day_06_part_2.f90
···
+
program day_06_part_2
+
implicit none
+
character(len=130) :: line, lines(130), temp_lines(130)
+
integer:: io, x,y, xd,yd, i, j, ct, o_ct, init_x, init_y, init_xd, init_yd
+
+
open(newunit=io, file='./day_06_input.txt', status='old', action='read')
+
read(io, '(a)') lines
+
+
ct = 0
+
! find starting position
+
do i = 1, size(lines)
+
if (index(lines(i), '^') > 0) then
+
y = i
+
x = index(lines(i), '^')
+
lines(i)(x:x) = '.' ! replace with a dot to not confuse this part
+
xd = 0
+
yd = -1
+
init_x = x
+
init_y = y
+
init_xd = xd
+
init_yd = yd
+
exit
+
end if
+
end do
+
+
do i = 1, size(lines)
+
do j = 1, len(lines(i))
+
o_ct = 0
+
! reset positions
+
x = init_x
+
y = init_y
+
xd = init_xd
+
yd = init_yd
+
temp_lines = lines ! fresh board every run
+
if(temp_lines(i)(j:j) == '.') then
+
temp_lines(i)(j:j) = 'O' ! place obstacle to test
+
! move until we leave the bounds when we hit a valid spot mark it with an X and increase count
+
do
+
! are we going out of bounds?
+
if (x+xd < 1 .or. x+xd > len(temp_lines(y)) .or. y+yd < 1 .or. y+yd > size(temp_lines)) then
+
exit
+
end if
+
+
! try to move
+
select case(temp_lines(y+yd)(x+xd:x+xd))
+
case('.')
+
! valid move
+
x = x + xd
+
y = y + yd
+
case('O')
+
! we are blocked lets rotate 90 degrees and count obstacle
+
o_ct = o_ct + 1
+
if(xd == 0 .and. yd == -1) then
+
xd = 1
+
yd = 0
+
else if (xd == 1 .and. yd == 0) then
+
xd = 0
+
yd = 1
+
else if (xd == 0 .and. yd == 1) then
+
xd = -1
+
yd = 0
+
else if (xd == -1 .and. yd == 0) then
+
xd = 0
+
yd = -1
+
end if
+
case('#')
+
! we are blocked lets rotate 90 degrees
+
! change this to an O to try and detect when stuck
+
temp_lines(y+yd)(x+xd:x+xd) = 'O'
+
if(xd == 0 .and. yd == -1) then
+
xd = 1
+
yd = 0
+
else if (xd == 1 .and. yd == 0) then
+
xd = 0
+
yd = 1
+
else if (xd == 0 .and. yd == 1) then
+
xd = -1
+
yd = 0
+
else if (xd == -1 .and. yd == 0) then
+
xd = 0
+
yd = -1
+
end if
+
case default
+
exit
+
end select
+
if(o_ct > 100) then
+
exit ! probably stuck
+
end if
+
end do
+
end if
+
if(o_ct > 100) then ! we got stuck probably 100 is so arbitrary
+
ct = ct + 1
+
end if
+
end do
+
end do
+
print*, "block points: ", ct
+
end program day_06_part_2
+57
2024/day_07.f90
···
+
module day_07_utils
+
use iso_fortran_env, only: int64
+
implicit none
+
contains
+
recursive function test_values(arr, target, next_idx, current_value) result(pass)
+
implicit none
+
integer(kind=int64), intent(in) :: target, current_value, arr(:)
+
integer, intent(in) :: next_idx
+
logical :: pass
+
if(next_idx > size(arr)) then
+
pass = current_value == target
+
return
+
end if
+
pass = test_values(arr, target, next_idx + 1, current_value + arr(next_idx)) .or. &
+
test_values(arr, target, next_idx + 1, current_value * arr(next_idx))
+
end function test_values
+
logical function is_calibrated(arr, target)
+
implicit none
+
integer(kind=int64), intent(in) :: target, arr(:)
+
is_calibrated = test_values(arr, target, 2, arr(1))
+
end function is_calibrated
+
end module day_07_utils
+
program day_07
+
use iso_fortran_env, only: int64
+
use day_07_utils
+
implicit none
+
integer(kind=int64) :: test_number, res
+
integer(kind=int64), allocatable:: work(:)
+
integer :: io, ios, idx, i, ct
+
character(len=200) :: line, work_line
+
logical :: pass
+
res = 0
+
open(newunit=io, file='./day_07_input.txt', status='old', action='read')
+
do
+
read(io, '(a)', iostat=ios) line
+
if (ios /= 0) exit
+
idx = index(line, ':')
+
if (idx > 0) then
+
read(line(1:idx-1), *) test_number
+
ct = 0
+
work_line = trim(line(idx+1:len(trim(line))))
+
do i = 1 , len(trim(work_line))
+
if(work_line(i:i) == ' ') then
+
ct = ct + 1
+
end if
+
end do
+
allocate(work(ct))
+
read(work_line, *) work(:)
+
end if
+
pass = is_calibrated(work, test_number)
+
if(pass) then
+
res = res + test_number
+
end if
+
deallocate(work)
+
end do
+
print*, "Result: ", res
+
end program day_07
+68
2024/day_07_part_2.f90
···
+
module day_07_part_2_utils
+
use iso_fortran_env, only: int64
+
implicit none
+
contains
+
recursive function test_values(arr, target, next_idx, current_value) result(pass)
+
implicit none
+
integer(kind=int64), intent(in) :: target, current_value, arr(:)
+
integer, intent(in) :: next_idx
+
character(len=20) :: str_1, str_2, concat_str
+
integer(kind=int64) :: concat_value
+
logical :: pass
+
+
if(next_idx > size(arr)) then
+
pass = current_value == target
+
return
+
end if
+
+
write(str_1, '(I0)') current_value
+
write(str_2, '(I0)') arr(next_idx)
+
concat_str = trim(str_1) // trim(str_2)
+
read(concat_str, '(I20)') concat_value
+
+
pass = test_values(arr, target, next_idx + 1, current_value + arr(next_idx)) .or. &
+
test_values(arr, target, next_idx + 1, current_value * arr(next_idx)) .or. &
+
test_values(arr, target, next_idx + 1, concat_value)
+
end function test_values
+
logical function is_calibrated(arr, target)
+
implicit none
+
integer(kind=int64), intent(in) :: target, arr(:)
+
+
is_calibrated = test_values(arr, target, 2, arr(1))
+
end function is_calibrated
+
end module day_07_part_2_utils
+
program day_07_part_2
+
use iso_fortran_env, only: int64
+
use day_07_part_2_utils
+
implicit none
+
integer(kind=int64) :: test_number, res
+
integer(kind=int64), allocatable:: work(:)
+
integer :: io, ios, idx, i, ct
+
character(len=200) :: line, work_line
+
logical :: pass
+
res = 0
+
open(newunit=io, file='./day_07_input.txt', status='old', action='read')
+
do
+
read(io, '(a)', iostat=ios) line
+
if (ios /= 0) exit
+
idx = index(line, ':')
+
if (idx > 0) then
+
read(line(1:idx-1), *) test_number
+
ct = 0
+
work_line = trim(line(idx+1:len(trim(line))))
+
do i = 1 , len(trim(work_line))
+
if(work_line(i:i) == ' ') then
+
ct = ct + 1
+
end if
+
end do
+
allocate(work(ct))
+
read(work_line, *) work(:)
+
end if
+
pass = is_calibrated(work, test_number)
+
if(pass) then
+
res = res + test_number
+
end if
+
deallocate(work)
+
end do
+
print*, "Result: ", res
+
end program day_07_part_2
+142
2024/day_08.f90
···
+
module day_08_utils
+
implicit none
+
type node
+
character :: c
+
integer, allocatable :: x(:), y(:)
+
end type node
+
contains
+
subroutine append_to_integer_array(arr, val)
+
implicit none
+
integer, allocatable, intent(inout) :: arr(:)
+
integer, intent(in) :: val
+
integer, allocatable :: temp(:)
+
if(.not. allocated(arr)) then
+
ERROR STOP 'Array not allocated'
+
end if
+
allocate(temp(size(arr) + 1))
+
temp(1:size(arr)) = arr
+
temp(size(arr) + 1) = val
+
call move_alloc(temp, arr)
+
end subroutine append_to_integer_array
+
+
subroutine add_node(nodes, c, x, y)
+
type(node), allocatable, intent(inout) :: nodes(:)
+
type(node), allocatable :: temp(:)
+
character, intent(in) :: c
+
integer, intent(in) :: x, y
+
integer :: i
+
do i = 1, size(nodes)
+
if (nodes(i)%c == c) then
+
if(.not. allocated(nodes(i)%x)) then
+
allocate(nodes(i)%x(1))
+
nodes(i)%x(1) = x
+
else
+
call append_to_integer_array(nodes(i)%x, x)
+
end if
+
if(.not. allocated(nodes(i)%y)) then
+
allocate(nodes(i)%y(1))
+
nodes(i)%y(1) = y
+
else
+
call append_to_integer_array(nodes(i)%y, y)
+
end if
+
return
+
end if
+
end do
+
allocate(temp(size(nodes) + 1))
+
temp(1:size(nodes)) = nodes
+
allocate(temp(size(nodes) + 1)%x(1))
+
allocate(temp(size(nodes) + 1)%y(1))
+
temp(size(nodes) + 1)%c = c
+
temp(size(nodes) + 1)%x(1) = x
+
temp(size(nodes) + 1)%y(1) = y
+
call move_alloc(temp, nodes)
+
end subroutine add_node
+
end module day_08_utils
+
+
program day_08
+
use day_08_utils
+
implicit none
+
character(len=50) :: lines(50)
+
integer :: io, i, j, k, l, score, xdist, ydist
+
integer, allocatable :: anti_x(:), anti_y(:)
+
type(node), allocatable :: nodes(:)
+
logical :: found
+
+
open(newunit=io, file='day_08_input.txt', status='old', action='read')
+
read(io, '(A)') lines
+
score = 0
+
do i = 1, 50
+
do j = 1, 50
+
if(lines(i)(j:j) /= '.') then
+
if(.not. allocated(nodes)) then
+
allocate(nodes(1))
+
nodes(1)%c = lines(i)(j:j)
+
allocate(nodes(1)%x(1))
+
allocate(nodes(1)%y(1))
+
nodes(1)%x(1) = j
+
nodes(1)%y(1) = i
+
else
+
call add_node(nodes, lines(i)(j:j), j, i)
+
end if
+
end if
+
end do
+
end do
+
do i = 1, size(nodes)
+
do j = 1, size(nodes(i)%x)
+
do l = 1, size(nodes(i)%x)
+
if(nodes(i)%x(j) == nodes(i)%x(l) .and. nodes(i)%y(j) == nodes(i)%y(l)) cycle ! don't compare same values
+
xdist = nodes(i)%x(j) - nodes(i)%x(l)
+
ydist = nodes(i)%y(j) - nodes(i)%y(l)
+
if(nodes(i)%x(j) + xdist > 0 .and. nodes(i)%x(j) + xdist <= 50 .and. &
+
nodes(i)%y(j) + ydist > 0 .and. nodes(i)%y(j) + ydist <= 50) then
+
if(.not. allocated(anti_x)) then
+
allocate(anti_x(1))
+
anti_x(1) = nodes(i)%x(j) + xdist
+
allocate(anti_y(1))
+
anti_y(1) = nodes(i)%y(j) + ydist
+
score = score + 1
+
else
+
found = .false.
+
do k = 1, size(anti_x)
+
if(anti_x(k) == nodes(i)%x(j) + xdist .and. anti_y(k) == nodes(i)%y(j) + ydist) then
+
found = .true.
+
exit
+
end if
+
end do
+
if(.not. found) then
+
call append_to_integer_array(anti_x, nodes(i)%x(j) + xdist)
+
call append_to_integer_array(anti_y, nodes(i)%y(j) + ydist)
+
+
score = score + 1
+
end if
+
end if
+
end if
+
if(nodes(i)%x(l) - xdist > 0 .and. nodes(i)%x(l) - xdist <= 50 .and. &
+
nodes(i)%y(l) - ydist > 0 .and. nodes(i)%y(l) - ydist <= 50) then
+
if(.not. allocated(anti_x)) then
+
allocate(anti_x(1))
+
anti_x(1) = nodes(i)%x(l) - xdist
+
allocate(anti_y(1))
+
anti_y(1) = nodes(i)%y(l) - ydist
+
score = score + 1
+
else
+
found = .false.
+
do k = 1, size(anti_x)
+
if(anti_x(k) == nodes(i)%x(l) - xdist .and. anti_y(k) == nodes(i)%y(l) - ydist) then
+
found = .true.
+
exit
+
end if
+
end do
+
if(.not. found) then
+
call append_to_integer_array(anti_x, nodes(i)%x(l) - xdist)
+
call append_to_integer_array(anti_y, nodes(i)%y(l) - ydist)
+
+
score = score + 1
+
end if
+
end if
+
end if
+
end do
+
end do
+
end do
+
print*, "Total : ", score
+
end program day_08
+164
2024/day_08_part_2.f90
···
+
module day_08_utils
+
implicit none
+
type node
+
character :: c
+
integer, allocatable :: x(:), y(:)
+
end type node
+
contains
+
subroutine append_to_integer_array(arr, val)
+
implicit none
+
integer, allocatable, intent(inout) :: arr(:)
+
integer, intent(in) :: val
+
integer, allocatable :: temp(:)
+
if(.not. allocated(arr)) then
+
ERROR STOP 'Array not allocated'
+
end if
+
allocate(temp(size(arr) + 1))
+
temp(1:size(arr)) = arr
+
temp(size(arr) + 1) = val
+
call move_alloc(temp, arr)
+
end subroutine append_to_integer_array
+
+
subroutine add_node(nodes, c, x, y)
+
type(node), allocatable, intent(inout) :: nodes(:)
+
type(node), allocatable :: temp(:)
+
character, intent(in) :: c
+
integer, intent(in) :: x, y
+
integer :: i
+
do i = 1, size(nodes)
+
if (nodes(i)%c == c) then
+
if(.not. allocated(nodes(i)%x)) then
+
allocate(nodes(i)%x(1))
+
nodes(i)%x(1) = x
+
else
+
call append_to_integer_array(nodes(i)%x, x)
+
end if
+
if(.not. allocated(nodes(i)%y)) then
+
allocate(nodes(i)%y(1))
+
nodes(i)%y(1) = y
+
else
+
call append_to_integer_array(nodes(i)%y, y)
+
end if
+
return
+
end if
+
end do
+
allocate(temp(size(nodes) + 1))
+
temp(1:size(nodes)) = nodes
+
allocate(temp(size(nodes) + 1)%x(1))
+
allocate(temp(size(nodes) + 1)%y(1))
+
temp(size(nodes) + 1)%c = c
+
temp(size(nodes) + 1)%x(1) = x
+
temp(size(nodes) + 1)%y(1) = y
+
call move_alloc(temp, nodes)
+
end subroutine add_node
+
end module day_08_utils
+
+
program day_08
+
use day_08_utils
+
implicit none
+
character(len=50) :: lines(50)
+
integer :: io, i, j, k, l, score, xdist, ydist, next_x, next_y
+
integer, allocatable :: anti_x(:), anti_y(:)
+
type(node), allocatable :: nodes(:)
+
logical :: found
+
+
open(newunit=io, file='day_08_input.txt', status='old', action='read')
+
read(io, '(A)') lines
+
score = 0
+
do i = 1, 50
+
do j = 1, 50
+
if(lines(i)(j:j) /= '.') then
+
if(.not. allocated(nodes)) then
+
allocate(nodes(1))
+
nodes(1)%c = lines(i)(j:j)
+
allocate(nodes(1)%x(1))
+
allocate(nodes(1)%y(1))
+
nodes(1)%x(1) = j
+
nodes(1)%y(1) = i
+
else
+
call add_node(nodes, lines(i)(j:j), j, i)
+
end if
+
end if
+
end do
+
end do
+
do i = 1, size(nodes)
+
do j = 1, size(nodes(i)%x)
+
if(.not. allocated(anti_x)) then
+
allocate(anti_x(1))
+
anti_x(1) = nodes(i)%x(j)
+
allocate(anti_y(1))
+
anti_y(1) = nodes(i)%y(j)
+
score = score + 1
+
else
+
found = .false.
+
do k = 1, size(anti_x)
+
if(anti_x(k) == nodes(i)%x(j) .and. anti_y(k) == nodes(i)%y(j)) then
+
found = .true.
+
exit
+
end if
+
end do
+
if(.not. found) then
+
call append_to_integer_array(anti_x, nodes(i)%x(j))
+
call append_to_integer_array(anti_y, nodes(i)%y(j))
+
+
score = score + 1
+
end if
+
end if
+
do l = 1, size(nodes(i)%x)
+
if(nodes(i)%x(j) == nodes(i)%x(l) .and. nodes(i)%y(j) == nodes(i)%y(l)) cycle ! don't compare same values
+
xdist = nodes(i)%x(j) - nodes(i)%x(l)
+
ydist = nodes(i)%y(j) - nodes(i)%y(l)
+
next_x = nodes(i)%x(j) + xdist
+
next_y = nodes(i)%y(j) + ydist
+
do
+
if(next_x> 0 .and. next_x <= 50 .and. &
+
next_y > 0 .and. next_y <= 50) then
+
found = .false.
+
do k = 1, size(anti_x)
+
if(anti_x(k) == next_x .and. anti_y(k) == next_y) then
+
found = .true.
+
exit
+
end if
+
end do
+
if(.not. found) then
+
call append_to_integer_array(anti_x, next_x)
+
call append_to_integer_array(anti_y, next_y)
+
+
score = score + 1
+
end if
+
next_x = next_x + xdist
+
next_y = next_y + ydist
+
else
+
exit
+
end if
+
end do
+
next_x = nodes(i)%x(l) - xdist
+
next_y = nodes(i)%y(l) - ydist
+
do
+
if(next_x > 0 .and. next_x <= 50 .and. &
+
next_y > 0 .and. next_y <= 50) then
+
found = .false.
+
do k = 1, size(anti_x)
+
if(anti_x(k) == next_x .and. anti_y(k) == next_y) then
+
found = .true.
+
exit
+
end if
+
end do
+
if(.not. found) then
+
call append_to_integer_array(anti_x, next_x)
+
call append_to_integer_array(anti_y, next_y)
+
+
score = score + 1
+
end if
+
next_x = next_x - xdist
+
next_y = next_y - ydist
+
+
else
+
exit
+
end if
+
end do
+
end do
+
end do
+
end do
+
print*, "Total : ", score
+
end program day_08
+152
2024/day_09.f90
···
+
module day_09_utils
+
implicit none
+
contains
+
subroutine swap_to_first_positive_integer_from_end(arr, idx)
+
implicit none
+
integer, allocatable, intent(inout) :: arr(:)
+
integer, intent(in) :: idx
+
integer, allocatable :: temp(:)
+
integer :: i, res
+
do i = 0, size(arr) - 1
+
if(arr(size(arr) - i) > -1) then
+
arr(idx) = arr(size(arr) - i)
+
allocate(temp(size(arr) - (i +1)))
+
temp = arr(1:size(arr) - (i+1))
+
call move_alloc(temp, arr)
+
return
+
end if
+
end do
+
end subroutine swap_to_first_positive_integer_from_end
+
subroutine append_to_integer_array_times(arr, val, times)
+
implicit none
+
integer, allocatable, intent(inout) :: arr(:)
+
integer, intent(in) :: val, times
+
integer, allocatable :: temp(:)
+
if(.not. allocated(arr)) then
+
ERROR STOP 'Array not allocated'
+
end if
+
allocate(temp(size(arr) + times))
+
temp(1:size(arr)) = arr
+
temp(size(arr) + 1:size(temp)) = val
+
call move_alloc(temp, arr)
+
end subroutine append_to_integer_array_times
+
end module day_09_utils
+
program day_09
+
use iso_fortran_env, only: int64
+
use day_09_utils
+
implicit none
+
integer :: io, ios, i, j, block_n, ct, block_start, block_end, space_start, space_end
+
integer(kind=int64) :: res
+
character(len=1) :: c
+
integer, allocatable :: system(:), work(:), done(:)
+
logical :: is_space, space_block_start
+
+
open(newunit=io, file='./day_09_input.txt', status='old', action='read', access='stream')
+
is_space = .false.
+
block_n = 0
+
do
+
read(io, iostat=ios) c
+
if (ios /= 0) exit
+
read(c, *, iostat=ios) i
+
if(ios /= 0) exit
+
if (i == 0) then
+
is_space = .false.
+
cycle
+
end if
+
if (.not. allocated(system)) then
+
allocate(system(i))
+
system(1:i) = block_n
+
is_space = .true.
+
block_n = block_n + 1
+
else
+
if (is_space) then
+
call append_to_integer_array_times(system, -1, i)
+
is_space = .false.
+
else
+
call append_to_integer_array_times(system, block_n, i)
+
block_n = block_n + 1
+
is_space = .true.
+
end if
+
end if
+
end do
+
allocate(work(size(system)))
+
work = system
+
ct = count(work > -1)
+
outer: do
+
do i = 1, size(work)
+
if (i == ct) exit outer ! we are done
+
if(work(i) < 0) then
+
call swap_to_first_positive_integer_from_end(work, i)
+
exit
+
end if
+
end do
+
end do outer
+
res = 0
+
do i = 1, size(work)
+
if(work(i) > -1) then
+
res = res + ((i-1) * work(i))
+
else
+
end if
+
end do
+
print *, res
+
! start_part_2
+
res = 0
+
deallocate(work)
+
allocate(work(size(system)))
+
work = system
+
block_n = -1
+
block_start = -1
+
block_end = -1
+
do i = size(work), 1, -1
+
if(block_n == -1 .and. work(i) /= -1) then
+
! we are starting a block
+
block_end = i
+
block_n = work(i)
+
if(allocated(done) .and. count(done == block_n) > 0) then
+
block_n = -1
+
block_start = -1
+
block_end = -1
+
cycle
+
else if(.not. allocated(done)) then
+
allocate(done(1))
+
done(1) = block_n
+
else
+
call append_to_integer_array_times(done, block_n, 1)
+
end if
+
else if (block_n /= -1 .and. block_n /= work(i)) then
+
! we are ending the block
+
block_start = i
+
+
! lets try to move the block
+
space_block_start = .true.
+
do j = 1, size(work)
+
if (j > block_start) exit
+
if(space_block_start .and. work(j) == -1) then
+
space_start = j
+
space_block_start = .false.
+
else if (.not. space_block_start .and. work(j) /= -1) then
+
space_end = j
+
space_block_start = .true.
+
if(space_end - space_start >= block_end - block_start) then
+
work(space_start:space_start + (block_end - (block_start +1))) = block_n
+
work(block_start+1:block_end) = -1
+
exit
+
end if
+
space_end = -1
+
space_start = -1
+
end if
+
end do
+
block_n = work(i)
+
block_end = i
+
block_start = -1
+
end if
+
end do
+
do i = 1, size(work)
+
if(work(i) /= -1) then
+
res = res + ((i-1) * work(i))
+
end if
+
end do
+
print *, res
+
end program day_09
+
+
+5
2024/dune
···
+
(executable (name day_01)
+
(libraries str))
+
(executable (name day_02))
+
(executable (name day_03)
+
(libraries str))
+1
2024/dune-project
···
+
(lang dune 3.6)
+51
2025/day_01.cbl
···
+
IDENTIFICATION DIVISION.
+
PROGRAM-ID. day_01.
+
AUTHOR. Trey Bastian.
+
ENVIRONMENT DIVISION.
+
INPUT-OUTPUT SECTION.
+
FILE-CONTROL.
+
SELECT input-file ASSIGN TO "./input.txt"
+
ORGANIZATION IS LINE SEQUENTIAL.
+
DATA DIVISION.
+
FILE SECTION.
+
FD input-file.
+
01 input-line.
+
02 direction PIC X.
+
02 move-text PIC XXX.
+
WORKING-STORAGE SECTION.
+
01 dial-position PIC 9(2) VALUE 50.
+
01 move-num PIC S9(3).
+
01 zero-count PIC 9(4) VALUE ZEROS.
+
01 eof PIC X.
+
88 eof-y VALUE "Y".
+
88 eof-n VALUE "N".
+
+
+
PROCEDURE DIVISION.
+
OPEN INPUT input-file.
+
SET eof-n to TRUE.
+
PERFORM UNTIL eof-y
+
READ input-file AT END
+
SET eof-y to TRUE
+
NOT AT END
+
MOVE FUNCTION NUMVAL(move-text) TO move-num
+
IF direction = "L"
+
COMPUTE move-num = 0 - move-num
+
END-IF
+
+
COMPUTE dial-position = FUNCTION MOD(dial-position +
+
move-num, 100)
+
+
if dial-position < 0
+
ADD 100 to dial-position
+
END-IF
+
+
if dial-position = 0
+
ADD 1 to zero-count
+
END-IF
+
END-READ
+
END-PERFORM.
+
CLOSE input-file.
+
DISPLAY zero-count.
+
STOP-RUN.
+
+67
2025/day_01_part2.cbl
···
+
IDENTIFICATION DIVISION.
+
PROGRAM-ID. day_01_part2.
+
AUTHOR. Trey Bastian.
+
ENVIRONMENT DIVISION.
+
INPUT-OUTPUT SECTION.
+
FILE-CONTROL.
+
SELECT input-file ASSIGN TO "./input.txt"
+
ORGANIZATION IS LINE SEQUENTIAL.
+
DATA DIVISION.
+
FILE SECTION.
+
FD input-file.
+
01 input-line.
+
02 direction PIC X.
+
02 move-text PIC XXX.
+
WORKING-STORAGE SECTION.
+
01 dial-position PIC 9(2) VALUE 50.
+
01 new-position PIC 9(2).
+
01 move-num PIC S9(3).
+
01 zero-count PIC 9(4) VALUE ZEROS.
+
01 eof PIC X.
+
88 eof-y VALUE "Y".
+
88 eof-n VALUE "N".
+
+
+
PROCEDURE DIVISION.
+
OPEN INPUT input-file.
+
SET eof-n to TRUE.
+
PERFORM UNTIL eof-y
+
READ input-file AT END
+
SET eof-y to TRUE
+
NOT AT END
+
MOVE FUNCTION NUMVAL(move-text) TO move-num
+
IF move-num > 99
+
COMPUTE zero-count = zero-count + (move-num / 100)
+
END-IF
+
+
IF direction = "L"
+
COMPUTE move-num = 0 - move-num
+
END-IF
+
+
COMPUTE new-position = FUNCTION MOD(dial-position +
+
move-num, 100)
+
+
if new-position < 0
+
ADD 100 to new-position
+
END-IF
+
+
EVALUATE new-position
+
WHEN 0
+
ADD 1 to zero-count
+
WHEN < dial-position AND direction = "R" AND
+
dial-position <> 0
+
ADD 1 to zero-count
+
WHEN > dial-position AND direction = "L" AND
+
dial-position <> 0
+
ADD 1 to zero-count
+
END-EVALUATE
+
+
+
MOVE new-position TO dial-position
+
+
END-READ
+
END-PERFORM.
+
CLOSE input-file.
+
DISPLAY zero-count.
+
STOP-RUN.
+
+76
2025/day_02.cbl
···
+
IDENTIFICATION DIVISION.
+
PROGRAM-ID. day_02.
+
AUTHOR. Trey Bastian.
+
ENVIRONMENT DIVISION.
+
INPUT-OUTPUT SECTION.
+
FILE-CONTROL.
+
SELECT input-file ASSIGN TO "./input.txt"
+
ORGANIZATION IS LINE SEQUENTIAL.
+
DATA DIVISION.
+
FILE SECTION.
+
FD input-file.
+
01 input-line PIC X(4096).
+
WORKING-STORAGE SECTION.
+
01 ptr PIC 9(4) Value 1.
+
01 len PIC 9(4).
+
01 left-val PIC 9(32).
+
01 right-val PIC 9(32).
+
01 grouping PIC X(65).
+
+
01 val-string PIC Z(32).
+
01 val-string-len PIC 9(2).
+
01 val-string-start-idx PIC 9(2).
+
01 val-string-half PIC 9(2).
+
01 result PIC 9(32) VALUE ZEROS.
+
+
01 eof PIC X.
+
88 eof-y VALUE "Y".
+
88 eof-n VALUE "N".
+
PROCEDURE DIVISION.
+
OPEN INPUT input-file.
+
SET eof-n to TRUE.
+
PERFORM UNTIL eof-y
+
READ input-file AT END
+
SET eof-y to TRUE
+
NOT AT END
+
INSPECT input-line TALLYING len FOR CHARACTERS BEFORE
+
SPACE
+
+
PERFORM UNTIL ptr > len
+
UNSTRING input-line DELIMITED BY "," INTO grouping WITH
+
POINTER ptr
+
END-UNSTRING
+
+
UNSTRING grouping DELIMITED BY "-" INTO left-val,
+
right-val
+
END-UNSTRING
+
+
PERFORM VARYING left-val FROM left-val BY 1 UNTIL
+
left-val > right-val
+
MOVE left-val TO val-string
+
+
COMPUTE val-string-len = FUNCTION LENGTH(FUNCTION
+
TRIM(val-string))
+
IF FUNCTION MOD(val-string-len, 2) = 0
+
+
COMPUTE val-string-start-idx =
+
(FUNCTION LENGTH(val-string) - val-string-len ) + 1
+
COMPUTE val-string-half = val-string-len / 2
+
+
IF val-string(val-string-start-idx:val-string-half)
+
= val-string(val-string-start-idx +
+
val-string-half:val-string-half)
+
+
ADD left-val TO result
+
END-IF
+
END-IF
+
END-PERFORM
+
+
END-PERFORM
+
+
END-READ
+
END-PERFORM.
+
CLOSE input-file.
+
DISPLAY result.
+
STOP-RUN.
+
+103
2025/day_02_part2.cbl
···
+
IDENTIFICATION DIVISION.
+
PROGRAM-ID. day_02_part2.
+
AUTHOR. Trey Bastian.
+
ENVIRONMENT DIVISION.
+
INPUT-OUTPUT SECTION.
+
FILE-CONTROL.
+
SELECT input-file ASSIGN TO "./input.txt"
+
ORGANIZATION IS LINE SEQUENTIAL.
+
DATA DIVISION.
+
FILE SECTION.
+
FD input-file.
+
01 input-line PIC X(4096).
+
WORKING-STORAGE SECTION.
+
01 ptr PIC 9(4) Value 1.
+
01 len PIC 9(4).
+
01 left-val PIC 9(32).
+
01 right-val PIC 9(32).
+
01 grouping PIC X(65).
+
+
01 val-string PIC Z(32).
+
01 val-string-len PIC 9(2).
+
01 val-string-start-idx PIC 9(2).
+
01 val-string-half PIC 9(2).
+
01 val-window PIC 9(2) VALUE 1.
+
01 c-idx PIC 9(2).
+
01 s-left PIC Z(16).
+
01 s-right PIC Z(16).
+
01 no-match PIC X VALUE "N".
+
01 result PIC 9(32) VALUE ZEROS.
+
+
01 eof PIC X.
+
88 eof-y VALUE "Y".
+
88 eof-n VALUE "N".
+
PROCEDURE DIVISION.
+
OPEN INPUT input-file.
+
SET eof-n to TRUE.
+
PERFORM UNTIL eof-y
+
READ input-file AT END
+
SET eof-y to TRUE
+
NOT AT END
+
INSPECT input-line TALLYING len FOR CHARACTERS BEFORE
+
SPACE
+
+
PERFORM UNTIL ptr > len
+
UNSTRING input-line DELIMITED BY "," INTO grouping WITH
+
POINTER ptr
+
END-UNSTRING
+
+
UNSTRING grouping DELIMITED BY "-" INTO left-val,
+
right-val
+
END-UNSTRING
+
+
PERFORM VARYING left-val FROM left-val BY 1 UNTIL
+
left-val > right-val
+
MOVE left-val TO val-string
+
+
COMPUTE val-string-len = FUNCTION LENGTH(FUNCTION
+
TRIM(val-string))
+
+
COMPUTE val-string-start-idx =
+
(FUNCTION LENGTH(val-string) - val-string-len ) + 1
+
+
COMPUTE val-string-half = val-string-len / 2
+
+
PERFORM VARYING val-window FROM 1 BY 1
+
UNTIL val-window > val-string-half
+
COMPUTE c-idx = val-string-start-idx + val-window
+
MOVE "N" to no-match
+
PERFORM VARYING c-idx
+
FROM c-idx
+
BY val-window
+
UNTIL c-idx
+
> FUNCTION LENGTH(val-string)
+
+
MOVE val-string(val-string-start-idx:val-window)
+
TO s-left
+
+
IF (c-idx + val-window
+
> FUNCTION LENGTH(val-string))
+
MOVE val-string(c-idx:) TO s-right
+
ELSE
+
MOVE val-string(c-idx:val-window) TO s-right
+
END-IF
+
+
IF NOT s-left = s-right
+
MOVE "Y" to no-match
+
EXIT PERFORM
+
END-IF
+
END-PERFORM
+
IF no-match = "N"
+
ADD left-val to result
+
EXIT PERFORM
+
END-IF
+
END-PERFORM
+
END-PERFORM
+
END-PERFORM
+
+
END-READ
+
END-PERFORM.
+
CLOSE input-file.
+
DISPLAY result.
+
STOP-RUN.
+
+63
2025/day_03.cbl
···
+
IDENTIFICATION DIVISION.
+
PROGRAM-ID. day_03.
+
AUTHOR. Trey Bastian.
+
ENVIRONMENT DIVISION.
+
INPUT-OUTPUT SECTION.
+
FILE-CONTROL.
+
SELECT input-file ASSIGN TO "./input.txt"
+
ORGANIZATION IS LINE SEQUENTIAL.
+
DATA DIVISION.
+
FILE SECTION.
+
FD input-file.
+
01 input-line PIC Z(4096).
+
WORKING-STORAGE SECTION.
+
01 idx PIC 9(4).
+
01 idx-2 PIC 9(4).
+
01 len PIC 9(4).
+
+
01 maxim PIC 9 VALUE 0.
+
01 digit PIC 9 VALUE 0.
+
+
01 joltage PIC XX.
+
01 result PIC 9(10) VALUE 0.
+
+
+
01 eof PIC X.
+
88 eof-y VALUE "Y".
+
88 eof-n VALUE "N".
+
+
PROCEDURE DIVISION.
+
OPEN INPUT input-file.
+
SET eof-n to TRUE.
+
PERFORM UNTIL eof-y
+
READ input-file AT END
+
SET eof-y to TRUE
+
NOT AT END
+
MOVE FUNCTION LENGTH(FUNCTION TRIM(input-line)) TO len
+
MOVE 0 TO maxim
+
*first pass leave something on the right
+
PERFORM VARYING idx FROM 1 UNTIL idx > len - 1
+
MOVE FUNCTION NUMVAL(input-line(idx:1)) TO digit
+
IF maxim < digit
+
MOVE digit TO maxim
+
MOVE idx TO idx-2
+
END-IF
+
END-PERFORM
+
* need the next index
+
MOVE maxim TO joltage(1:1)
+
MOVE 0 TO maxim
+
ADD 1 TO idx-2
+
PERFORM VARYING idx-2 FROM idx-2 UNTIL idx-2 > len
+
MOVE FUNCTION NUMVAL(input-line(idx-2:1)) TO digit
+
IF maxim < digit
+
MOVE digit TO maxim
+
END-IF
+
END-PERFORM
+
MOVE maxim TO joltage(2:1)
+
ADD FUNCTION NUMVAL(joltage) TO result
+
END-READ
+
END-PERFORM.
+
CLOSE input-file.
+
DISPLAY result.
+
STOP-RUN.
+
+64
2025/day_03_part2.cbl
···
+
IDENTIFICATION DIVISION.
+
PROGRAM-ID. day_03_part2.
+
AUTHOR. Trey Bastian.
+
ENVIRONMENT DIVISION.
+
INPUT-OUTPUT SECTION.
+
FILE-CONTROL.
+
SELECT input-file ASSIGN TO "./input.txt"
+
ORGANIZATION IS LINE SEQUENTIAL.
+
DATA DIVISION.
+
FILE SECTION.
+
FD input-file.
+
01 input-line PIC Z(4096).
+
WORKING-STORAGE SECTION.
+
01 idx PIC 9(4) VALUE 1.
+
01 idx-2 PIC 9(4).
+
01 len PIC 9(4).
+
+
01 maxim PIC 9 VALUE 0.
+
01 digit PIC 9 VALUE 0.
+
01 remaining PIC 99 VALUE 12.
+
01 rem-idx PIC 99 VALUE 1.
+
+
01 joltage PIC X(12).
+
01 result PIC 9(32) VALUE 0.
+
+
+
01 eof PIC X.
+
88 eof-y VALUE "Y".
+
88 eof-n VALUE "N".
+
+
PROCEDURE DIVISION.
+
OPEN INPUT input-file.
+
SET eof-n to TRUE.
+
PERFORM UNTIL eof-y
+
READ input-file AT END
+
SET eof-y to TRUE
+
NOT AT END
+
MOVE FUNCTION LENGTH(FUNCTION TRIM(input-line)) TO len
+
MOVE 1 TO idx
+
MOVE 12 TO remaining
+
MOVE 1 TO rem-idx
+
PERFORM UNTIL remaining < 1
+
MOVE 0 TO maxim
+
PERFORM VARYING idx FROM idx UNTIL idx >
+
(len - remaining + 1)
+
MOVE FUNCTION NUMVAL(input-line(idx:1)) to digit
+
IF maxim < digit
+
MOVE digit TO maxim
+
MOVE idx TO idx-2
+
END-IF
+
END-PERFORM
+
MOVE maxim TO joltage(rem-idx:1)
+
ADD 1 TO rem-idx
+
SUBTRACT 1 FROM remaining
+
MOVE idx-2 TO idx
+
ADD 1 TO idx
+
END-PERFORM
+
ADD FUNCTION NUMVAL(joltage) TO result
+
END-READ
+
END-PERFORM.
+
CLOSE input-file.
+
DISPLAY result.
+
STOP-RUN.
+
+5 -2
README.md
···
# Advent of Code Repo
This repository contains my solutions to the Advent of Code challenges.
-
I stream all my solutions live on Twitch at [twitch.tv/treybastian](https://twitch.tv/treybastian).
+
## 2025 - COBOL
+
You'll need to install GNUCobol to run these solutions.
+
+
On MacOS you can install it with Homebrew: `brew install gnucobol`
## 2024 - Fortran
You'll need GNUFortran to run these solutions.
-
On MacOS, you can install it with Homebrew with `brew install gcc`.
+
On MacOS, you can install it with Homebrew: `brew install gcc`.