My yearly advent-of-code solutions
1program day_03
2 implicit none
3 logical :: find_a
4 integer ::io, ios, a, b, state, res
5 character(len=1) :: c
6 character(len=10) :: buffer
7 character(len=4) :: mul_cmd = 'mul('
8
9 res = 0
10 open(newunit=io, file='./day_03_input.txt', status='old', action='read', access='stream')
11 state = 0 ! 0 = find command, 1 = find number, 2 = calculate
12 find_a = .true.
13 buffer = ''
14 do
15 read(io, iostat=ios) c
16 if (ios /= 0) exit
17 select case(state)
18 case (0) ! find command
19 buffer = trim(buffer) // c
20 if(buffer == mul_cmd) then
21 state = 1
22 buffer = ''
23 else if(trim(buffer) /= mul_cmd(1:len(trim(buffer)))) then
24 state = 0
25 buffer = ''
26 end if
27 case (1) ! find digits
28 select case (iachar(c))
29 case (48:57) ! 0-9
30 buffer = trim(buffer) // c
31 case (44) ! ,
32 if (find_a .and. len(trim(buffer)) > 0) then
33 read(buffer, *) a
34 buffer = ''
35 find_a = .false.
36 else
37 state = 0 ! invalid
38 find_a = .true.
39 buffer = ''
40 end if
41 case (41) ! )
42 if(.not. find_a .and. len(trim(buffer)) > 0) then
43 read(buffer, *) b
44 state = 2
45 find_a = .true.
46 buffer = ''
47 else
48 state = 0
49 find_a = .true.
50 buffer = ''
51 end if
52 case default
53 state = 0
54 find_a = .true.
55 buffer = ''
56 end select
57 end select
58 if(state == 2) then
59 res = res + (a * b)
60 state = 0
61 buffer = ''
62 end if
63 end do
64 print*, res
65end program day_03