My yearly advent-of-code solutions
at main 2.5 kB view raw
1program day_03_part_2 2 implicit none 3 logical :: find_a, is_dont 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 character(len=7) :: dont_cmd = "don't()" 9 character(len=4) :: do_cmd = 'do()' 10 11 res = 0 12 open(newunit=io, file='./day_03_input.txt', status='old', action='read', access='stream') 13 state = 0 ! 0 = find command, 1 = find number, 2 = calculate 14 find_a = .true. 15 is_dont = .false. 16 buffer = '' 17 do 18 read(io, iostat=ios) c 19 if (ios /= 0) exit 20 select case(state) 21 case (0) ! find command 22 buffer = trim(buffer) // c 23 if(is_dont) then 24 if (trim(buffer) == do_cmd) then 25 state = 0 26 buffer = '' 27 is_dont = .false. 28 else if (trim(buffer) /= do_cmd(1:len(trim(buffer)))) then 29 state = 0 30 buffer = '' 31 end if 32 else 33 if (trim(buffer) == dont_cmd) then 34 state = 0 35 buffer = '' 36 is_dont = .true. 37 else if(trim(buffer) == mul_cmd) then 38 state = 1 39 buffer = '' 40 else if(trim(buffer) /= mul_cmd(1:len(trim(buffer))) .and. trim(buffer) /= dont_cmd(1:len(trim(buffer)))) then 41 state = 0 42 buffer = '' 43 end if 44 end if 45 case (1) ! find digits 46 select case (iachar(c)) 47 case (48:57) ! 0-9 48 buffer = trim(buffer) // c 49 case (44) ! , 50 if (find_a .and. len(trim(buffer)) > 0) then 51 read(buffer, *) a 52 buffer = '' 53 find_a = .false. 54 else 55 state = 0 ! invalid 56 find_a = .true. 57 buffer = '' 58 end if 59 case (41) ! ) 60 if(.not. find_a .and. len(trim(buffer)) > 0) then 61 read(buffer, *) b 62 state = 2 63 find_a = .true. 64 buffer = '' 65 else 66 state = 0 67 find_a = .true. 68 buffer = '' 69 end if 70 case default 71 state = 0 72 find_a = .true. 73 buffer = '' 74 end select 75 end select 76 if(state == 2) then 77 res = res + (a * b) 78 state = 0 79 buffer = '' 80 end if 81 end do 82 print*, res 83end program day_03_part_2