My yearly advent-of-code solutions
1module day_07_utils
2 use iso_fortran_env, only: int64
3 implicit none
4contains
5 recursive function test_values(arr, target, next_idx, current_value) result(pass)
6 implicit none
7 integer(kind=int64), intent(in) :: target, current_value, arr(:)
8 integer, intent(in) :: next_idx
9 logical :: pass
10 if(next_idx > size(arr)) then
11 pass = current_value == target
12 return
13 end if
14 pass = test_values(arr, target, next_idx + 1, current_value + arr(next_idx)) .or. &
15 test_values(arr, target, next_idx + 1, current_value * arr(next_idx))
16 end function test_values
17 logical function is_calibrated(arr, target)
18 implicit none
19 integer(kind=int64), intent(in) :: target, arr(:)
20 is_calibrated = test_values(arr, target, 2, arr(1))
21 end function is_calibrated
22end module day_07_utils
23program day_07
24 use iso_fortran_env, only: int64
25 use day_07_utils
26 implicit none
27 integer(kind=int64) :: test_number, res
28 integer(kind=int64), allocatable:: work(:)
29 integer :: io, ios, idx, i, ct
30 character(len=200) :: line, work_line
31 logical :: pass
32 res = 0
33 open(newunit=io, file='./day_07_input.txt', status='old', action='read')
34 do
35 read(io, '(a)', iostat=ios) line
36 if (ios /= 0) exit
37 idx = index(line, ':')
38 if (idx > 0) then
39 read(line(1:idx-1), *) test_number
40 ct = 0
41 work_line = trim(line(idx+1:len(trim(line))))
42 do i = 1 , len(trim(work_line))
43 if(work_line(i:i) == ' ') then
44 ct = ct + 1
45 end if
46 end do
47 allocate(work(ct))
48 read(work_line, *) work(:)
49 end if
50 pass = is_calibrated(work, test_number)
51 if(pass) then
52 res = res + test_number
53 end if
54 deallocate(work)
55 end do
56 print*, "Result: ", res
57end program day_07