extern crate num; //This function returns a list of all Fibonacci numbers <= goalNumber pub fn getAllFib(goalNumber: u64) -> Vec{ let mut fibNums = Vec::new(); //A list to save the Fibonacci numbers //If the number is <= 0 return an empty list if(goalNumber <= 0){ return fibNums; } //This means that at least 2 1's are elements fibNums.push(1); fibNums.push(1); //Loop to generate the rest of the Fibonacci numbers while(fibNums[fibNums.len() - 1] <= goalNumber){ fibNums.push(fibNums[fibNums.len() - 1] + fibNums[fibNums.len() - 2]); } //At this point the most recent number is > goalNumber, so remove it and return the rest of the list fibNums.remove(fibNums.len() - 1); return fibNums; } pub fn getAllFibBig(goalNumber: num::BigInt) -> Vec{ let mut fibNums = Vec::new(); //A list to save the Fibonacci numbers in //If the number is <= 0 return an empty list if(goalNumber <= num::BigInt::from(0)){ return fibNums; } //This means that at least 2 1's are elements fibNums.push(num::BigInt::from(1)); fibNums.push(num::BigInt::from(1)); while(fibNums[fibNums.len() - 1] <= goalNumber){ fibNums.push(&fibNums[fibNums.len() - 1] + &fibNums[fibNums.len() - 2]); } //At this point the most recent number is > goalNumber, so remove it and return the rest of the list fibNums.remove(fibNums.len() - 1); return fibNums; } //This function returns all the divisors of goalSubscript pub fn getFib(goalSubscript: i64) -> i64{ //Setup the variables let mut fibNums = [1, 1, 0]; //If the number is <= 0 return 0 if(goalSubscript <= 0){ return 0; } //Loop through the list, generating Fibonacci numbers until it finds the correct subscript let mut fibLoc = 2; while(fibLoc < goalSubscript){ fibNums[(fibLoc % 3) as usize] = fibNums[((fibLoc - 1) % 3) as usize] + fibNums[((fibLoc - 2) % 3) as usize]; fibLoc += 1; } //Return the proper number. The location counter is 1 off of the subscript return fibNums[((fibLoc - 1) % 3) as usize]; } pub fn getFibBig(goalSubscript: num::BigInt) -> num::BigInt{ //Setup the variables let mut fibNums = [num::BigInt::from(1), num::BigInt::from(1), num::BigInt::from(0)]; //If the number is <= 0 return 0 if(goalSubscript <= num::BigInt::from(0)){ return num::BigInt::from(0); } //Loop through the list, generating Fibonacci numbers until it finds the correct subscript let mut fibLoc = 2; while(num::BigInt::from(fibLoc) < goalSubscript){ fibNums[(fibLoc % 3) as usize] = &fibNums[((fibLoc - 1) % 3) as usize] + &fibNums[((fibLoc - 2) % 3) as usize]; fibLoc += 1; } //Return the proper number. The location counter is 1 off of the subscript let temp = &fibNums[((fibLoc - 1) % 3) as usize]; return num::BigInt::new(temp.to_u32_digits().0, temp.to_u32_digits().1); } //This function returns all factors of goalNumber pub fn getFactors(mut goalNumber: i64) -> Vec{ //You need to get all the primes that could be factors of this number so you can test them let topPossiblePrime = (goalNumber as f64).sqrt().ceil() as i64; let primes = getPrimes(topPossiblePrime); let mut factors = Vec::::new(); //You need to step through each prime and see if it is a factor in the number let mut cnt = 0; while(cnt < primes.len()){ //If the prime is a factor you need to add it to the factor list if((goalNumber % primes[cnt]) == 0){ factors.push(primes[cnt]); goalNumber /= primes[cnt]; } //Otherwise advance the location in primes you are looking at //By not advancing if the prime is a factor you allow for multiple of the same prime number as a factor else{ cnt += 1; } } //If you didn't get any factors the number itself must be a prime if(factors.len() == 0){ factors.push(goalNumber); goalNumber /= goalNumber; } //TODO: If for some reason the goalNumber is not 1 throw an error if(goalNumber != 1){ } //Return the list of factors return factors; } pub fn getFactorsBig(mut goalNumber: num::BigInt) -> Vec{ //You need to get all the rpimes that could be factors of this number so you can test them let topPossiblePrime = goalNumber.sqrt(); let primes = getPrimesBig(topPossiblePrime); let mut factors = Vec::::new(); //You need to step through each prime and see if it is a factor in the number let mut cnt = 0; while(cnt < primes.len()){ //If the prime is a factor you need to add it to the factor list if((&goalNumber % &primes[cnt]) == num::BigInt::from(0)){ factors.push(num::BigInt::new(primes[cnt].sign(), primes[cnt].to_u32_digits().1)); goalNumber /= &primes[cnt]; } //Otherwise advance the location in primes you are looking at //By not advancing if the prime is a factor you allow for multiple of the same prime number as a factor else{ cnt += 1; } } //If you didn't get any factors the number itself must be a prime if(factors.len() == 0){ factors.push(goalNumber); goalNumber = num::BigInt::from(1); } //TODO: If for some reason the goalNumber is not 1 throw an error if(goalNumber != num::BigInt::from(1)){ } //Return the list of factors return factors; } //This function returns a list with all the prime numbers <= goalNumber pub fn getPrimes(goalNumber: i64) -> Vec{ let mut primes = Vec::::new(); let mut foundFactor = false; //If the number is 1, 0, or negative return an empty list if(goalNumber <= 1){ return primes; } //Otherwise the number is at least 2, so 2 should be added to the list else{ primes.push(2); } //We can now start at 3 and skip all even number, because they cannot be prime for possiblePrime in (3..=goalNumber).step_by(2){ //Check all current primes, up to sqrt(possiblePrime), to see if there is a divisor let topPossibleFactor = (possiblePrime as f64).sqrt().ceil(); //We can safely assume that there will be at least 1 element in the primes list because of 2 being added before this let mut primesCnt = 0; while(primes[primesCnt] <= topPossibleFactor as i64){ if((possiblePrime % primes[primesCnt]) == 0){ foundFactor = true; break; } else{ primesCnt += 1; } //Check if the index has gone out of range if(primesCnt >= primes.len()){ break; } } //If you didn't find a factor then the current number must be prime if(!foundFactor){ primes.push(possiblePrime); } else{ foundFactor = false; } } //Sort the list before returning it primes.sort(); return primes; } pub fn getPrimesBig(goalNumber: num::BigInt) -> Vec{ let mut primes = Vec::::new(); let mut foundFactor = false; //If the number is 1, 0, or negative return an empty list if(goalNumber <= num::BigInt::from(0)){ return primes; } //Otherwise the number is at least 2, so 2 should be added to the list else{ primes.push(num::BigInt::from(2)); } //We can now start at 3 and skip all even number, because they cannot be prime let mut possiblePrime = num::BigInt::from(3); while(possiblePrime <= goalNumber){ //Check for all currentprimes, up to sqrt(possiblePrime), to see if there is a divisor let topPossibleFactor = possiblePrime.sqrt() + num::BigInt::from(1); //We can safely assume that there will be at least 2 element in the primes list because of 2 being added before this let mut primesCnt = 0; while(primes[primesCnt] <= topPossibleFactor){ if((&possiblePrime % &primes[primesCnt]) == num::BigInt::from(0)){ foundFactor = true; break; } else{ primesCnt += 1; } //Check if the index has gone out of range if(primesCnt >= primes.len()){ break; } } //If you didn't find a factor then the current number must be prime if(!foundFactor){ primes.push(num::BigInt::new(possiblePrime.sign(), possiblePrime.to_u32_digits().1)); } else{ foundFactor = false; } possiblePrime += num::BigInt::from(2); } //Sort the list before returning it primes.sort(); return primes; } //This function gets a certain number of primes pub fn getNumPrimes(numberOfPrimes: i64) -> Vec{ let mut primes = Vec::::new(); //Holds the prime numbers let mut foundFactor = false; //A flag for whether a factor of the current number has been found //If the number is 0 or negative return an empty list if(numberOfPrimes <= 0){ return primes; } //Otherwise the number is at least 2, so 2 should be added to the list else{ primes.push(2); } //We can now start at 3 and skip all even numbers, because the cannot be prime let mut possiblePrime = 3; while((primes.len() as i64) < numberOfPrimes){ //Check all current primes, up to sqrt)possiblePrime), to see if there is a divisor let topPossibleFactor = (possiblePrime as f64).sqrt().ceil() as i64; //We can safely assume that there will be at least 1 element in primes list because of 2 being added before this let mut primesCnt = 0; while(primes[primesCnt] <= topPossibleFactor){ if((possiblePrime as i64 % primes[primesCnt]) == 0){ foundFactor = true; break; } else{ primesCnt += 1; } //Check if the index has gone out of range if(primesCnt >= primes.len()){ break; } } //If you didn't find a factor then the current number must be prime if(!foundFactor){ primes.push(possiblePrime as i64); } else{ foundFactor = false; } possiblePrime += 2; } //Sort the list before returning it primes.sort(); return primes; } pub fn getNumPrimesBig(numberOfPrimes: num::BigInt) -> Vec{ let mut primes = Vec::::new(); //Holds the prime numbers let mut foundFactor = false; //A flag for whether a factor of the current number has been found //If the number is 0 or negative return an empty list if(numberOfPrimes <= num::BigInt::from(1)){ return primes; } //Otherwise the number is at least 2, so 2 should be added to the list else{ primes.push(num::BigInt::from(2)); } //We can now start at 3 and skip all even numbers, because they cannot be prime let mut possiblePrime = num::BigInt::from(3); while(numberOfPrimes > num::BigInt::from(primes.len())){ //Check all current primes, up to sqrt(possiblePrime), to see if there is a divisor let topPossibleFactor = ((&possiblePrime).sqrt() + num::BigInt::from(1)); //We can safely assume that there will be at least 1 element in the primes list because of 2 being added before this let mut primesCnt = 0; while(primes[primesCnt] <= topPossibleFactor){ if((&possiblePrime % &primes[primesCnt]) == num::BigInt::from(0)){ foundFactor = true; break; } else{ primesCnt += 1; } //Check if the index has gone out of bounds if(primesCnt >= primes.len()){ break; } } //If you didn't find a factor then the current number must be prime if(!foundFactor){ primes.push(num::BigInt::new(possiblePrime.sign(), possiblePrime.to_u32_digits().1)); } else{ foundFactor = false; } //Advance to the next number possiblePrime += 2; } //Sort the list before returning it 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; } //This is a function that creates all permutations of a string and returns a vector of those permutations. pub fn getPermutations(master: String) -> Vec::{ return getPermutationsFull(master, 0); } fn getPermutationsFull(masterOrg: String, num: i32) -> Vec::{ let mut master = masterOrg; let mut perms = Vec::::new(); //Check if the number is out of bounds if((num >= master.len() as i32) || (num < 0)){ //Do nothing and return an empty array } //If this is the last possible recurse just return the current string else if(num == (master.len() - 1) as i32){ perms.push(master); } //If there are more possible recurses, recurse with the current permutation else{ let mut temp = getPermutationsFull(master.clone(), num + 1); perms.extend(temp); //You need to swap the current letter with every possible letter after it //The ones needed to swap before will happen automatically when the function recurses let mut cnt = 1; while((num + cnt) < master.len() as i32){ master = swapString(master.clone(), num, (num + cnt)); temp = getPermutationsFull(master.clone(), num + 1); perms.extend(temp); master = swapString(master.clone(), num, (num + cnt)); cnt += 1; } //The array is not necessarily in alpha-numeric order. So if this is the full array sort it before returning perms.sort(); } //Return the array that was built return perms; } pub fn swapString(strng: String, first: i32, second: i32) -> String{ let mut bytes = Vec::::new(); bytes.extend_from_slice(strng.as_bytes()); let temp = bytes[first as usize]; bytes[first as usize] = bytes[second as usize]; bytes[second as usize] = temp; let mut swappedString = "".to_string(); for loc in 0..bytes.len(){ swappedString = format!("{}{}", swappedString, (bytes[loc] as char)); } return swappedString; } //This function returns the gcd of two numbers pub fn gcd(in1: i32, in2: i32) -> i32{ let mut num1 = in1; let mut num2 = in2; while((num1 != 0) && (num2 != 0)){ if(num1 > num2){ num1 %= num2; } else{ num2 %= num1; } } return num1 | num2; } //Returns the factorial of the number passed in pub fn factorial(num: i64) -> i64{ let mut fact = 1; for cnt in 1 ..= num{ fact *= cnt; } return fact; }