@@ -33,3 +33,102 @@ pub fn is_palindromic_chars(chars: Vec<u8>) -> bool {
33
33
}
34
34
true
35
35
}
36
+
37
+ use std:: collections:: HashMap ;
38
+
39
+ #[ derive( Debug , Default , Clone , PartialEq , Eq ) ]
40
+ pub struct PrimeFactorization {
41
+ pub map : HashMap < u64 , u32 > ,
42
+ }
43
+
44
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
45
+ pub struct PrimeFactor {
46
+ pub prime : u64 ,
47
+ pub power : u32 ,
48
+ }
49
+
50
+ impl PrimeFactorization {
51
+ pub fn add_prime_factor ( & mut self , prime : u64 , power : u32 ) {
52
+ use std:: collections:: hash_map:: Entry ;
53
+ match self . map . entry ( prime) {
54
+ Entry :: Occupied ( mut entry) => * entry. get_mut ( ) += power,
55
+ Entry :: Vacant ( entry) => {
56
+ entry. insert ( power) ;
57
+ } ,
58
+ }
59
+ }
60
+
61
+ pub fn remove_prime_factor ( & mut self , prime : u64 , power : u32 ) {
62
+ let current = self . map . get_mut ( & prime) . unwrap ( ) ;
63
+ * current = current. checked_sub ( power) . unwrap ( ) ;
64
+ }
65
+
66
+ pub fn merge ( & mut self , other : & PrimeFactorization ) {
67
+ for ( prime, power) in & other. map {
68
+ self . add_prime_factor ( * prime, * power) ;
69
+ }
70
+ }
71
+
72
+ pub fn num_factors ( & self ) -> u32 {
73
+ self . map . iter ( ) . map ( |( _, power) | power + 1 ) . product ( )
74
+ }
75
+
76
+ pub fn value ( & self ) -> u64 {
77
+ self . map . iter ( ) . map ( |( prime, power) | prime. pow ( * power) ) . product ( )
78
+ }
79
+
80
+ pub fn into_vec ( self ) -> Vec < PrimeFactor > {
81
+ self . map . into_iter ( ) . map ( |( prime, power) | PrimeFactor { prime, power } ) . collect ( )
82
+ }
83
+ }
84
+
85
+ pub fn prime_factorization ( mut n : u64 ) -> PrimeFactorization {
86
+ let mut result = Default :: default ( ) ;
87
+
88
+ if n == 1 {
89
+ result
90
+ } else if n == 2 || n == 3 {
91
+ result. add_prime_factor ( n, 1 ) ;
92
+ result
93
+ } else {
94
+ while n > 3 {
95
+ let mut reduced = false ;
96
+ let upper_factor = ( n as f64 ) . sqrt ( ) . floor ( ) as u64 ;
97
+ for i in 2 ..=upper_factor {
98
+ if n % i == 0 {
99
+ result. add_prime_factor ( i, 1 ) ;
100
+ n /= i;
101
+ reduced = true ;
102
+ break ;
103
+ }
104
+ }
105
+ if !reduced {
106
+ // This is a prime.
107
+ result. add_prime_factor ( n, 1 ) ;
108
+ n = 1 ;
109
+ }
110
+ }
111
+
112
+ if n == 3 {
113
+ result. add_prime_factor ( 3 , 1 ) ;
114
+ } else if n == 2 {
115
+ result. add_prime_factor ( 2 , 1 ) ;
116
+ }
117
+
118
+ result
119
+ }
120
+ }
121
+
122
+ #[ cfg( test) ]
123
+ mod tests {
124
+ use super :: * ;
125
+
126
+ #[ test]
127
+ fn test_primie_factorization ( ) {
128
+ assert_eq ! ( prime_factorization( 1 ) . into_vec( ) , vec![ ] ) ;
129
+ assert_eq ! ( prime_factorization( 2 ) . into_vec( ) , vec![ PrimeFactor { prime: 2 , power: 1 } ] ) ;
130
+ assert_eq ! ( prime_factorization( 3 ) . into_vec( ) , vec![ PrimeFactor { prime: 3 , power: 1 } ] ) ;
131
+ assert_eq ! ( prime_factorization( 4 ) . into_vec( ) , vec![ PrimeFactor { prime: 2 , power: 2 } ] ) ;
132
+ assert_eq ! ( prime_factorization( 500 ) . into_vec( ) , vec![ PrimeFactor { prime: 5 , power: 3 } , PrimeFactor { prime: 2 , power: 2 } ] ) ;
133
+ }
134
+ }
0 commit comments