@@ -4,11 +4,12 @@ module Primes
4
4
5
5
using Base. Iterators: repeated
6
6
7
+ import Base: start, next, done, eltype, iteratorsize, iteratoreltype
7
8
using Base: BitSigned
8
9
using Base. Checked: checked_neg
9
10
10
11
export isprime, primes, primesmask, factor, ismersenneprime, isrieselprime,
11
- nextprime, prevprime, prime, prodfactors, radical, totient
12
+ nextprime, nextprimes, prevprime, prevprimes , prime, prodfactors, radical, totient
12
13
13
14
include (" factorization.jl" )
14
15
@@ -528,6 +529,11 @@ function totient(n::Integer)
528
529
totient (factor (abs (n)))
529
530
end
530
531
532
+ # add: checked add (when makes sense), result of same type as first argument
533
+
534
+ add (n:: BigInt , x:: Int ) = n+ x
535
+ add (n:: Integer , x:: Int ) = Base. checked_add (n, oftype (n, x))
536
+
531
537
# add_! : "may" mutate the Integer argument (only for BigInt currently)
532
538
533
539
# modify a BigInt in-place
@@ -541,7 +547,7 @@ function add_!(n::BigInt, x::Int)
541
547
end
542
548
543
549
# checked addition, without mutation
544
- add_! (n:: Integer , x:: Int ) = Base . checked_add (n, oftype (n, x) )
550
+ add_! (n:: Integer , x:: Int ) = add (n, x )
545
551
546
552
"""
547
553
nextprime(n::Integer, i::Integer=1; interval::Integer=1)
@@ -664,4 +670,114 @@ julia> prime(3)
664
670
prime (:: Type{T} , i:: Integer ) where {T<: Integer } = i < 0 ? throw (DomainError (i)) : nextprime (T (2 ), i)
665
671
prime (i:: Integer ) = prime (Int, i)
666
672
673
+
674
+ struct NextPrimes{T<: Integer }
675
+ start:: T
676
+ end
677
+
678
+ Base. start (np:: NextPrimes ) = np. start < 2 ? np. start : add (np. start, - 1 )
679
+ Base. next (np:: NextPrimes , state) = (p = nextprime (add (state, 1 )); (p, p))
680
+ Base. done (np:: NextPrimes , state) = false
681
+
682
+ Base. iteratorsize (:: Type{<:NextPrimes} ) = Base. IsInfinite ()
683
+ Base. iteratoreltype (:: Type{<:NextPrimes} ) = Base. HasEltype () # default
684
+
685
+ Base. eltype (:: Type{NextPrimes{T}} ) where {T} = T
686
+
687
+ """
688
+ nextprimes(start::Integer)
689
+
690
+ Returns an iterator over all primes greater than or equal to `start`,
691
+ in ascending order.
692
+ """
693
+ nextprimes (start:: Integer ) = NextPrimes (start)
694
+
695
+ """
696
+ nextprimes(T::Type=Int)
697
+
698
+ Returns an iterator over all primes, with type `T`.
699
+ Equivalent to `nextprimes(T(1))`.
700
+ """
701
+ nextprimes (:: Type{T} ) where {T<: Integer } = nextprimes (one (T))
702
+ nextprimes () = nextprimes (Int)
703
+
704
+ """
705
+ nextprimes(start::Integer, n::Integer)
706
+
707
+ Returns an array of the first `n` primes greater than or equal to `start`.
708
+
709
+ # Example
710
+
711
+ ```
712
+ julia> nextprimes(10, 3)
713
+ 3-element Array{Int64,1}:
714
+ 11
715
+ 13
716
+ 17
717
+ ```
718
+ """
719
+ nextprimes (start:: T , n:: Integer ) where {T<: Integer } =
720
+ iterate (x-> nextprime (add (x, 1 )), nextprime (start), n)
721
+
722
+ struct PrevPrimes{T<: Integer }
723
+ start:: T
724
+ end
725
+
726
+ start (np:: PrevPrimes ) = np. start+ one (np. start) # allow wrap-around
727
+ next (np:: PrevPrimes , state) = (p = prevprime (state- one (state)); (p, p))
728
+ done (np:: PrevPrimes , state) = state == 2
729
+
730
+ iteratorsize (:: Type{<:PrevPrimes} ) = Base. SizeUnknown ()
731
+ iteratoreltype (:: Type{<:PrevPrimes} ) = Base. HasEltype () # default
732
+
733
+ eltype (:: Type{PrevPrimes{T}} ) where {T} = T
734
+
735
+ """
736
+ prevprimes(start::Integer)
737
+
738
+ Returns an iterator over all primes less than or equal to `start`,
739
+ in descending order.
740
+
741
+ # Example
742
+
743
+ ```
744
+ julia> collect(prevprimes(10))
745
+ 4-element Array{Int64,1}:
746
+ 7
747
+ 5
748
+ 3
749
+ 2
750
+ ```
751
+ """
752
+ prevprimes (start:: Integer ) = PrevPrimes (max (one (start), start))
753
+
754
+ """
755
+ prevprimes(start::Integer, n::Integer)
756
+
757
+ Returns an array of the first `n` primes less than or equal to `start`,
758
+ in descending order.
759
+
760
+ # Example
761
+
762
+ ```
763
+ julia> prevprimes(10, 3)
764
+ 3-element Array{Int64,1}:
765
+ 7
766
+ 5
767
+ 3
768
+ ```
769
+ """
770
+ prevprimes (start:: T , n:: Integer ) where {T<: Integer } =
771
+ iterate (x-> prevprime (add (x, - 1 )), prevprime (start), n)
772
+
773
+ function iterate (f, x:: T , n:: Integer ) where T
774
+ v = Vector {T} (n)
775
+ n != 0 && (@inbounds v[1 ] = x)
776
+ @inbounds for i = 2 : n
777
+ x = f (x)
778
+ v[i] = x
779
+ end
780
+ v
781
+ end
782
+
667
783
end # module
0 commit comments