Skip to content

Commit b054a53

Browse files
authored
Modify Prime Number in Fortran (#5121)
Improve Prime Number Fortran code snippet
1 parent 3fa547d commit b054a53

File tree

1 file changed

+62
-77
lines changed

1 file changed

+62
-77
lines changed

archive/f/fortran/prime-number.f95

Lines changed: 62 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,68 @@
1-
! In program name, - is not allowed
2-
!works till 100938872634753805466563377840038871040
3-
! Commenting out of the reasonable bounds for calculation
41
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
356

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()
439

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()
4913

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
5517

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()
7720

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

Comments
 (0)