@@ -50,6 +50,91 @@ impl Prime {
5050 }
5151}
5252
53+ pub struct Spf {
54+ spf_max_limit : usize ,
55+ spf : Vec < u64 >
56+ }
57+
58+ /// A struct representing the smallest prime factor (SPF) computation.
59+ impl Spf {
60+ /// Creates a new `Spf` instance with a given maximum limit.
61+ ///
62+ /// # Arguments
63+ ///
64+ /// * `max_limit` - The maximum limit up to which the smallest prime factors are computed.
65+ ///
66+ /// # Returns
67+ ///
68+ /// A new `Spf` instance with precomputed smallest prime factors up to `max_limit`.
69+ pub fn new ( max_limit : usize ) -> Spf {
70+ let mut spf = vec ! [ 0 ; max_limit + 1 ] ;
71+ for i in 2 ..=max_limit {
72+ if spf[ i] == 0 {
73+ for j in ( i..=max_limit) . step_by ( i) {
74+ if spf[ j] == 0 {
75+ spf[ j] = i as u64 ;
76+ }
77+ }
78+ }
79+ }
80+ Spf {
81+ spf_max_limit : max_limit,
82+ spf : spf,
83+ }
84+ }
85+
86+ /// Retrieves the smallest prime factor of a given number.
87+ ///
88+ /// # Arguments
89+ ///
90+ /// * `x` - The number for which the smallest prime factor is to be retrieved.
91+ ///
92+ /// # Returns
93+ ///
94+ /// The smallest prime factor of `x`.
95+ ///
96+ /// # Panics
97+ ///
98+ /// Panics if `x` is greater than the `max_limit` specified during the creation of the `Spf` instance.
99+ pub fn get_spf ( & self , x : u64 ) -> u64 {
100+ if x as usize > self . spf_max_limit {
101+ panic ! ( "x cannot be greater than max_limit!" ) ;
102+ }
103+ self . spf [ x as usize ]
104+ }
105+
106+ /// Factorizes a given number into its prime factors.
107+ ///
108+ /// # Arguments
109+ ///
110+ /// * `x` - The number to be factorized.
111+ ///
112+ /// # Returns
113+ ///
114+ /// A vector containing the prime factors of `x`.
115+ ///
116+ /// # Panics
117+ ///
118+ /// Panics if `x` is greater than the `max_limit` specified during the creation of the `Spf` instance.
119+ ///
120+ /// # Complexity
121+ ///
122+ /// The factorization process takes O(log n) time after the SPF computation.
123+ pub fn factorize ( & self , x : u64 ) -> Vec < u64 > {
124+ if x as usize > self . spf_max_limit {
125+ panic ! ( "x cannot be greater than max_limit!" ) ;
126+ }
127+ let mut factors: Vec < u64 > = Vec :: new ( ) ;
128+ let mut y: usize = x as usize ;
129+ while y != 1 {
130+ factors. push ( self . spf [ y] ) ;
131+ y /= self . spf [ y] as usize ;
132+ }
133+ factors. sort ( ) ;
134+ factors
135+ }
136+ }
137+
53138/// A struct that provides methods for modular exponentiation and modular inverse calculations.
54139pub struct Modexp { }
55140
@@ -271,4 +356,37 @@ mod tests {
271356 fn test_composite_mod ( ) {
272357 let comb: Comb = Comb :: new ( 4 , 14 ) ;
273358 }
359+
360+ #[ test]
361+ pub fn test_spf ( ) {
362+ let spf: Spf = Spf :: new ( 10000000 ) ;
363+ assert_eq ! ( spf. get_spf( 7 ) , 7 ) ;
364+ assert_eq ! ( spf. get_spf( 25 ) , 5 ) ;
365+ assert_eq ! ( spf. get_spf( 2491 ) , 47 ) ;
366+ assert_eq ! ( spf. get_spf( 10000000 ) , 2 ) ;
367+ assert_eq ! ( spf. get_spf( 81 ) , 3 ) ;
368+ }
369+
370+ #[ test]
371+ fn test_get_factors_via_spf ( ) {
372+ let spf: Spf = Spf :: new ( 10000000 ) ;
373+ assert_eq ! ( spf. factorize( 1000429 ) , vec![ 1000429 ] ) ;
374+ assert_eq ! ( spf. factorize( 24 ) , vec![ 2 , 2 , 2 , 3 ] ) ;
375+ assert_eq ! ( spf. factorize( 45 ) , vec![ 3 , 3 , 5 ] ) ;
376+ assert_eq ! ( spf. factorize( 346789 ) , vec![ 239 , 1451 ] ) ;
377+ }
378+
379+ #[ test]
380+ #[ should_panic( expected = "x cannot be greater than max_limit!" ) ]
381+ fn test_spf_factorize_above_limit ( ) {
382+ let spf: Spf = Spf :: new ( 15 ) ;
383+ spf. factorize ( 16 ) ;
384+ }
385+
386+ #[ test]
387+ #[ should_panic( expected = "x cannot be greater than max_limit!" ) ]
388+ fn test_spf_above_limit ( ) {
389+ let spf: Spf = Spf :: new ( 15 ) ;
390+ spf. get_spf ( 16 ) ;
391+ }
274392}
0 commit comments