diff --git a/src/Algorithms.rs b/src/Algorithms.rs index 52639ee..267a217 100644 --- a/src/Algorithms.rs +++ b/src/Algorithms.rs @@ -303,3 +303,76 @@ pub fn getNumPrimesBig(numberOfPrimes: num::BigInt) -> Vec{ primes.sort(); return primes; } + +//This function returns all the divisors of goalNumber +pub fn getDivisors(goalNumber: i64) -> Vec{ + let mut divisors = Vec::::new(); + + //Start by checking that the number is positive + if(goalNumber <= 0){ + return divisors; + } + //If the number is 1 return just itself + else if(goalNumber == 1){ + divisors.push(1); + return divisors; + } + + //Start at 3 and loop through all numbers < sqrt(goalNumber) looking for a number that divides it evenly + let topPossibleDivisor = (goalNumber as f64).sqrt().ceil() as i64; + let mut possibleDivisor = 1i64; + while(possibleDivisor <= topPossibleDivisor){ + //If you find one add it and the number it creates to the list + if((goalNumber % possibleDivisor) == 0){ + divisors.push(possibleDivisor); + //Account for the possibility of sqrt(goalNumber) being a divisor + if(possibleDivisor != topPossibleDivisor){ + divisors.push(goalNumber / possibleDivisor); + } + //Take care of a few occations where a number was added twice + if(divisors.last().unwrap() == &(possibleDivisor + 1)){ + possibleDivisor += 1; + } + } + possibleDivisor += 1; + } + + //Sort the list before returning it (for neatness) + divisors.sort(); + return divisors; +} +pub fn getDivisorsBig(goalNumber: num::BigInt) -> Vec{ + let mut divisors = Vec::::new(); + //Start by checking that he number is positive + if(goalNumber <= num::BigInt::from(0)){ + return divisors; + } + //If the number is 1 return just itself + else if(goalNumber == num::BigInt::from(1)){ + divisors.push(num::BigInt::from(1)); + return divisors; + } + + //Start at 3 and loop through all numbers < sqrt(goalNumber) looking for a number that divides it evenly + let topPossibleDivisor = goalNumber.sqrt(); + let mut possibleDivisor = num::BigInt::from(1); + while(&possibleDivisor <= &topPossibleDivisor){ + //If you find one add it and the number it creates to the list + if((&goalNumber % &possibleDivisor) == num::BigInt::from(0)){ + divisors.push(num::BigInt::new(possibleDivisor.sign(), possibleDivisor.to_u32_digits().1)); + //Account for the possibility of sqrt(goalNumber) being a divisor + if(&possibleDivisor != &topPossibleDivisor){ + divisors.push(num::BigInt::new((&goalNumber / &possibleDivisor).sign(), (&goalNumber / &possibleDivisor).to_u32_digits().1)); + } + //Take care of a few occations where the number was added twice + if(divisors.last().unwrap() == &(&possibleDivisor + num::BigInt::from(1))){ + possibleDivisor += num::BigInt::from(1); + } + } + possibleDivisor += 1; + } + + //Sort the list before returning it (for neatness) + divisors.sort(); + return divisors; +} diff --git a/src/lib.rs b/src/lib.rs index 9764734..65a4ff7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -87,6 +87,22 @@ mod AlgorithmsTests{ let answer2 = super::Algorithms::getNumPrimesBig(numPrimes2); assert_eq!(correctAnswer2, answer2); } + #[test] + fn testGetDivisors(){ + //Test1 + let mut correctAnswer1 = Vec::::new(); + correctAnswer1.extend_from_slice(&[1, 2, 4, 5, 10, 20, 25, 50, 100]); + let topNum1 = 100; + let answer1 = super::Algorithms::getDivisors(topNum1); + assert_eq!(correctAnswer1, answer1); + + //Test2 + let mut correctAnswer2 = Vec::::new(); + correctAnswer2.extend_from_slice(&[num::BigInt::from(1), num::BigInt::from(2), num::BigInt::from(4), num::BigInt::from(5), num::BigInt::from(10), num::BigInt::from(20), num::BigInt::from(25), num::BigInt::from(50), num::BigInt::from(100)]); + let topNum2 = num::BigInt::from(100); + let answer2 = super::Algorithms::getDivisorsBig(topNum2); + assert_eq!(correctAnswer2, answer2); + } }