Skip to content

Commit

Permalink
Re-added function that appeared unused, and re-added default features
Browse files Browse the repository at this point in the history
  • Loading branch information
ejmahler committed Feb 6, 2024
1 parent 4c723ea commit 72eebbf
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ categories = ["algorithms", "compression", "multimedia::encoding", "science"]
license = "MIT OR Apache-2.0"

[features]
default = []
default = ["avx", "sse", "neon"]

# On x86_64, the "avx" feature enables compilation of AVX-acclerated code.
# Similarly, the "sse" feature enables compilation of SSE-accelerated code.
Expand Down
68 changes: 68 additions & 0 deletions src/math_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,52 @@ impl PrimeFactors {
self.power_three > 0 && self.power_two == 0 && self.other_factors.len() == 0
}

// Divides the number by the given prime factor. Returns None if the resulting number is one.
#[allow(unused)]
pub fn remove_factors(mut self, factor: PrimeFactor) -> Option<Self> {
if factor.count == 0 {
return Some(self);
}
if factor.value == 2 {
self.power_two = self.power_two.checked_sub(factor.count).unwrap();
self.n >>= factor.count;
self.total_factor_count -= factor.count;
if self.power_two == 0 {
self.distinct_factor_count -= 1;
}
if self.n > 1 {
return Some(self);
}
} else if factor.value == 3 {
self.power_three = self.power_three.checked_sub(factor.count).unwrap();
self.n /= 3.pow(factor.count);
self.total_factor_count -= factor.count;
if self.power_two == 0 {
self.distinct_factor_count -= 1;
}
if self.n > 1 {
return Some(self);
}
} else {
let found_factor = self
.other_factors
.iter_mut()
.find(|item| item.value == factor.value)
.unwrap();
found_factor.count = found_factor.count.checked_sub(factor.count).unwrap();
self.n /= factor.value.pow(factor.count);
self.total_factor_count -= factor.count;
if found_factor.count == 0 {
self.distinct_factor_count -= 1;
self.other_factors.retain(|item| item.value != factor.value);
}
if self.n > 1 {
return Some(self);
}
}
None
}

// returns true if we have any factors whose value is less than or equal to the provided factor
pub fn has_factors_leq(&self, factor: usize) -> bool {
self.power_two > 0
Expand Down Expand Up @@ -653,6 +699,28 @@ mod unit_tests {
}
}

#[test]
fn test_remove_factors() {
// For every possible factor of a bunch of factors, they removing each and making sure the result is internally consistent
for n in 2..200 {
let factors = PrimeFactors::compute(n);

for i in 0..=factors.get_power_of_two() {
if let Some(removed_factors) = factors
.clone()
.remove_factors(PrimeFactor { value: 2, count: i })
{
assert_eq!(removed_factors.get_product(), factors.get_product() >> i);
assert_internally_consistent(&removed_factors);
} else {
// If the method returned None, this must be a power of two and i must be equal to the product
assert!(n.is_power_of_two());
assert!(i == factors.get_power_of_two());
}
}
}
}

#[test]
fn test_partial_factors() {
#[derive(Debug)]
Expand Down

0 comments on commit 72eebbf

Please sign in to comment.