program day3 implicit none character(100) :: arg integer :: search_low, search_high integer :: i, num_valid, num_valid2, n_arguments num_valid = 0 num_valid2 = 0 n_arguments = command_argument_count() if (n_arguments .ne. 2) then print *, "Wrong number of arguments: ", n_arguments stop else call get_command_argument(1, arg) read (arg, *) search_low call get_command_argument(2, arg) read (arg, *) search_high end if do i=search_low, search_high if ((n_digits(i) .eq. 6) .and. (.not. decreases(i)) .and. (has_duplicate(i))) then num_valid = num_valid + 1 if (has_strict_double(i)) then num_valid2 = num_valid2 + 1 write(*, 21) num_valid2, i else write(*, 20) num_valid, i end if end if end do write(*, 30) num_valid write(*, 31) num_valid2 20 format(' ', i6, ': ', i6) 21 format('* ', i6, ': ', i6) 30 format('Number found for criteria 1: ', i6) 31 format('Number found for criteria 2: ', i6) contains function n_digits(val) implicit none integer, intent(in) :: val integer :: n_digits n_digits = floor(log10(real(val))) + 1 end function n_digits function decreases(val) implicit none integer, intent(in) :: val logical :: decreases integer :: dig, dig_2, n_dig, i, remainder decreases = .false. n_dig = n_digits(val) remainder = val dig = huge(dig) do i = 1,n_dig dig_2 = mod(remainder, 10) remainder = remainder / 10 if (dig_2 .gt. dig) then decreases = .true. return else dig = dig_2 end if end do end function decreases function has_duplicate(val) implicit none integer, intent(in) :: val logical :: has_duplicate integer :: i, dig, dig_2, n_dig, remainder has_duplicate = .false. n_dig = n_digits(val) remainder = val dig = -1 do i = 1,n_dig dig_2 = mod(remainder, 10) remainder = remainder / 10 if (dig_2 .eq. dig) then has_duplicate = .true. return else dig = dig_2 end if end do end function has_duplicate function has_strict_double(val) result(hd) implicit none integer, intent(in) :: val logical :: hd integer :: i, dig_1, dig_2, dig_3, dig_4, n_dig, remainder hd = .false. n_dig = n_digits(val) remainder = val dig_1 = -1 dig_2 = -2 dig_3 = -3 do i = 1,n_dig+1 dig_4 = mod(remainder, 10) remainder = remainder / 10 if ((dig_3 .eq. dig_2) .and. (dig_2 .ne. dig_1) .and. (dig_4 .ne. dig_3)) then hd = .true. return else dig_1 = dig_2 dig_2 = dig_3 dig_3 = dig_4 end if end do end function has_strict_double end program day3