|
1 | | -! In program name, - is not allowed |
2 | | -!works till 100938872634753805466563377840038871040 |
3 | | -! Commenting out of the reasonable bounds for calculation |
4 | 1 | program prime_check |
5 | | - character(len=10) :: argument |
6 | | - Character(26) :: low = 'abcdefghijklmnopqrstuvwxyz' |
7 | | - Character(26) :: cap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
8 | | - integer :: check_capital_letters, check_small_letters, i, decimal_check, even_check, remainder, flag_prime |
9 | | - integer(kind = 16):: number |
10 | | - ! Anything not equal to single argument, Print Error |
11 | | - IF(COMMAND_ARGUMENT_COUNT().NE.1)THEN |
12 | | - write(*,'(g0.8)')"Usage: please input a non-negative integer" |
13 | | - STOP |
14 | | - ENDIF |
15 | | - |
16 | | - CALL GET_COMMAND_ARGUMENT(1,argument) |
17 | | - if (argument == "") then |
18 | | - write(*,'(g0.8)')"Usage: please input a non-negative integer" |
19 | | - STOP |
20 | | - endif |
21 | | - ! Scan for letters |
22 | | - check_capital_letters = scan(argument, cap) |
23 | | - check_small_letters = scan(argument, low) |
24 | | - decimal_check = scan(argument, '.') |
25 | | - ! If capital letters exist, print error |
26 | | - if (check_capital_letters > 0) then |
27 | | - write(*,'(g0.8)')"Usage: please input a non-negative integer" |
28 | | - STOP |
29 | | - endif |
30 | | - ! If small letters exist, print error |
31 | | - if (check_small_letters > 0) then |
32 | | - write(*,'(g0.8)')"Usage: please input a non-negative integer" |
33 | | - STOP |
34 | | - endif |
| 2 | + implicit none |
| 3 | + integer :: argc, ios, i |
| 4 | + character(len=256) :: arg |
| 5 | + integer :: number |
35 | 6 |
|
36 | | - ! Decimal Check |
37 | | - if (decimal_check > 0) then |
38 | | - write(*,'(g0.8)')"Usage: please input a non-negative integer" |
39 | | - STOP |
40 | | - endif |
41 | | - ! read the cmd line arg into number |
42 | | - read (argument, '(I10)') number |
| 7 | + argc = command_argument_count() |
| 8 | + if (argc /= 1) call usage() |
43 | 9 |
|
44 | | - ! negative number |
45 | | - if (number < 0) then |
46 | | - write(*,'(g0.8)')"Usage: please input a non-negative integer" |
47 | | - STOP |
48 | | - endif |
| 10 | + call get_command_argument(1, arg) |
| 11 | + arg = adjustl(trim(arg)) |
| 12 | + if (len_trim(arg) == 0) call usage() |
49 | 13 |
|
50 | | - ! ! Maximum Limit |
51 | | - ! if (number > 100938872634753805466563377840038871040) then |
52 | | - ! write(*,'(g0.8)')"Input is out of the reasonable bounds for calculation" |
53 | | - ! STOP |
54 | | - ! endif |
| 14 | + do i = 1, len_trim(arg) |
| 15 | + if (arg(i:i) < '0' .or. arg(i:i) > '9') call usage() |
| 16 | + end do |
55 | 17 |
|
56 | | - ! 2 is Prime |
57 | | - if (number == 2) then |
58 | | - write(*,'(g0.8)')"Prime" |
59 | | - STOP |
60 | | - endif |
61 | | - ! 0, 1 and even numbers are Even |
62 | | - even_check = modulo(number, 2) |
63 | | - if ((number == 0) .or. (number == 1) .or. ( even_check == 0 )) then |
64 | | - write(*,'(g0.8)')"Composite" |
65 | | - STOP |
66 | | - endif |
67 | | - ! Check Prime |
68 | | - max = number / 2 |
69 | | - flag_prime = 1 |
70 | | - do i = 3, max |
71 | | - remainder = modulo(number, i) |
72 | | - if (remainder == 0) then |
73 | | - flag_prime = 0 |
74 | | - exit |
75 | | - end if |
76 | | - end do |
| 18 | + read(arg, *, iostat=ios) number |
| 19 | + if (ios /= 0 .or. number < 0) call usage() |
77 | 20 |
|
78 | | - if(flag_prime == 1) then |
79 | | - write(*,'(g0.8)') "Prime" |
80 | | - else |
81 | | - write(*,'(g0.8)') "Composite" |
82 | | - end if |
83 | | -end program |
| 21 | + if (is_prime(number)) then |
| 22 | + print *, "Prime" |
| 23 | + else |
| 24 | + print *, "Composite" |
| 25 | + end if |
| 26 | + |
| 27 | +contains |
| 28 | + subroutine usage() |
| 29 | + print *, "Usage: please input a non-negative integer" |
| 30 | + stop |
| 31 | + end subroutine usage |
| 32 | + |
| 33 | + pure function is_prime(n) result(prime) |
| 34 | + integer, intent(in) :: n |
| 35 | + logical :: prime |
| 36 | + integer :: k, w, offsets(8) |
| 37 | + |
| 38 | + ! Wheel offsets for 30k + {1,7,11,13,17,19,23,29} |
| 39 | + offsets = [1, 7, 11, 13, 17, 19, 23, 29] |
| 40 | + |
| 41 | + if (n < 2) then |
| 42 | + prime = .false. |
| 43 | + return |
| 44 | + elseif (n <= 3) then |
| 45 | + prime = .true. |
| 46 | + return |
| 47 | + elseif (mod(n,2) == 0 .or. mod(n,3) == 0 .or. mod(n,5) == 0) then |
| 48 | + prime = .false. |
| 49 | + return |
| 50 | + end if |
| 51 | + |
| 52 | + prime = .true. |
| 53 | + w = 0 |
| 54 | + k = 7 ! start from the first wheel candidate after 5 |
| 55 | + |
| 56 | + do while (k*k <= n) |
| 57 | + do w = 1, 8 |
| 58 | + if (mod(n, k + offsets(w) - 1) == 0) then |
| 59 | + prime = .false. |
| 60 | + return |
| 61 | + end if |
| 62 | + end do |
| 63 | + k = k + 30 |
| 64 | + end do |
| 65 | + |
| 66 | + end function is_prime |
| 67 | + |
| 68 | +end program prime_check |
0 commit comments