95 lines
3.2 KiB
Fortran
95 lines
3.2 KiB
Fortran
program day2
|
|
implicit none
|
|
integer, parameter :: path_length = 100
|
|
character(path_length) :: fname
|
|
integer :: n_arguments
|
|
integer, allocatable :: intcode(:)
|
|
integer :: n_codes
|
|
logical :: run_successful
|
|
|
|
n_arguments = command_argument_count()
|
|
if (n_arguments .eq. 1) then
|
|
call get_command_argument(1, fname)
|
|
print *, "File: ", fname
|
|
else
|
|
print *, "Wrong number of arguments: ", n_arguments
|
|
stop
|
|
end if
|
|
|
|
intcode = read_intcode(fname)
|
|
n_codes = size(intcode)
|
|
print "(4i5)", intcode
|
|
print *, "Running intcode"
|
|
call execute_intcode(intcode, n_codes, run_successful)
|
|
if (run_successful) then
|
|
print *, "Clean exit"
|
|
else
|
|
print *, "ERROR!"
|
|
end if
|
|
print *
|
|
print "(4i5)", intcode
|
|
print *
|
|
print *, "Value at position 0: ", intcode(0 + 1)
|
|
deallocate(intcode)
|
|
|
|
contains
|
|
function read_intcode(fname)
|
|
integer, parameter :: fstr_len = 10000
|
|
character(*), intent(in) :: fname
|
|
integer, allocatable :: read_intcode(:)
|
|
character(fstr_len) :: fstr
|
|
integer :: fstr_true_len
|
|
integer :: n_values = 0
|
|
integer :: i
|
|
open(10, file=fname)
|
|
read(10, "(A)") fstr
|
|
close(10)
|
|
fstr_true_len = len_trim(fstr)
|
|
do i=1, fstr_true_len
|
|
if (fstr(i:i) .eq. ',') n_values = n_values + 1
|
|
end do
|
|
allocate(read_intcode(0:n_values))
|
|
read(fstr, *) read_intcode
|
|
end function read_intcode
|
|
|
|
subroutine execute_intcode(intcode, icodelen, clean_exit)
|
|
integer, intent(inout) :: intcode(0:)
|
|
integer, intent(in) :: icodelen
|
|
logical, intent(out) :: clean_exit
|
|
integer, parameter :: max_iterations = 10000
|
|
integer :: code_line
|
|
integer :: opcode
|
|
integer :: ipos_1
|
|
integer :: ipos_2
|
|
integer :: opos
|
|
integer :: op_result
|
|
!print "(4i5)", intcode
|
|
clean_exit = .false.
|
|
do code_line = 0, max_iterations
|
|
if (code_line * 4 .ge. icodelen) then
|
|
print *, "Overran intcode looking for opcode at line ", code_line
|
|
return
|
|
end if
|
|
opcode = intcode(code_line * 4)
|
|
if (opcode .eq. 99) then
|
|
print *, "Finished at line ", code_line
|
|
clean_exit = .true.
|
|
return
|
|
end if
|
|
ipos_1 = intcode(code_line * 4 + 1)
|
|
ipos_2 = intcode(code_line * 4 + 2)
|
|
opos = intcode(code_line * 4 + 3)
|
|
if (opcode .eq. 1) then
|
|
op_result = intcode(ipos_1) + intcode(ipos_2)
|
|
intcode(opos) = op_result
|
|
else if (opcode .eq. 2) then
|
|
op_result = intcode(ipos_1) * intcode(ipos_2)
|
|
intcode(opos) = op_result
|
|
else
|
|
print *, "Unknown opcode at line", code_line, " - ", opcode
|
|
return
|
|
end if
|
|
end do
|
|
end subroutine execute_intcode
|
|
end program day2
|