Files
CPPClasses/testAlgorithms.cpp
2021-06-30 14:10:17 -04:00

721 lines
17 KiB
C++

//myClasses/Algorithms.cpp
//Matthew Ellison
// Created: 11-14-18
//Modified: 06-29-21
//This is the file that tests all my algorithms, both for speed and accuracy
/*
Copyright (C) 2021 Matthew Ellison
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <vector>
#include <string>
#include <random>
#include <gmpxx.h>
#include "Algorithms.hpp"
#include "Stopwatch.hpp"
//Defines a type for functions so there can be an array of functions
typedef bool (*boolFn)();
//A function to test every set of funtions in Algorithms.hpp
//Some of the functions are overloaded, so I test all overloaded functions in each function
bool testGetPrimes();
bool testGetNumPrimes();
bool testIsPrime();
bool testGetFactors();
bool tetsGetDivisors();
bool testGetSum();
bool testGetProduct();
bool testIsFound();
bool testGetPermutations();
bool testGetFib();
bool testGetAllFib();
bool testBubbleSort();
bool testQuickSort();
bool testSearch();
bool testFindMin();
bool testFindMax();
bool testFindNumOccurrence();
bool testFactorial();
bool testIsPalindrome();
bool testToBin();
bool testPrintVector();
int main(){
mee::Stopwatch timer;
bool passedTest = false;
std::vector<boolFn> functions {testGetPrimes, testGetNumPrimes, testIsPrime, testGetFactors, tetsGetDivisors, testGetSum, testGetProduct, testIsFound, testGetPermutations,
testGetFib, testGetAllFib, testBubbleSort, testQuickSort, testSearch, testFindMin, testFindMax, testFindNumOccurrence, testFactorial, testIsPalindrome, testToBin,
testPrintVector};
std::vector<std::string> names {"getPrimes", "getNumPrimes", "isPrime", "getFactors", "getDivisors", "getSum", "getProduct", "isFound", "getPermutations",
"getFib", "getAllFib", "bubbleSort", "quickSort", "search", "findMin", "findMax", "findNumOccurrence", "factorial", "isPalindrome", "toBin",
"testPrintVector"};
//Start doing tests and print out the results of each
for(int cnt = 0;cnt < functions.size();++cnt){
timer.start();
passedTest = functions[cnt]();
timer.stop();
if(passedTest){
std::cout << "Function " << names.at(cnt) << "() passed the test\n";
}
else{
std::cout << "Function " << names.at(cnt) << "() failed the test\n";
}
std::cout << "The test took " << timer.getStr() << "\n\n" << std::endl;
}
return 0;
}
bool testGetPrimes(){
std::vector<uint64_t> correctAnswer {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
uint64_t topNum = 100;
std::vector<uint64_t> answer = mee::getPrimes(topNum);
if(correctAnswer != answer){
return false;
}
//If the false was not triggered it must have passed all tests
return true;
}
bool testGetNumPrimes(){
std::vector<uint64_t> correctAnswer {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
uint64_t numPrimes = 25;
std::vector<uint64_t> answer = mee::getNumPrimes(numPrimes);
if(correctAnswer != answer){
return false;
}
//If the false was not triggered it must have passed all tests
return true;
}
bool testIsPrime(){
//Test 1
int64_t num = 2;
bool correctAnswer = true;
bool answer = mee::isPrime(num);
if(correctAnswer != answer){
return false;
}
//Test 2
num = 97;
correctAnswer = true;
answer = mee::isPrime(num);
if(correctAnswer != answer){
return false;
}
//Test 3
num = 1000;
correctAnswer = false;
answer = mee::isPrime(num);
if(correctAnswer != answer){
return false;
}
//Test 4
num = 1;
correctAnswer = false;
answer = mee::isPrime(num);
if(correctAnswer != answer){
return false;
}
//If the false was not triggered it must have passed all tests
return true;
}
bool testGetFactors(){
std::vector<uint64_t> correctAnswer {2, 2, 5, 5};
uint64_t number = 100;
std::vector<uint64_t> answer = mee::getFactors(number);
if(correctAnswer != answer){
return false;
}
correctAnswer = {2, 7, 7};
number = 98;
answer = mee::getFactors(number);
if(correctAnswer != answer){
return false;
}
//If a false was not triggered it must have passed all tests
return true;
}
bool tetsGetDivisors(){
std::vector<uint64_t> correctAnswer {1, 2, 4, 5, 10, 20, 25, 50, 100};
uint64_t topNum = 100;
std::vector<uint64_t> answer = mee::getDivisors(topNum);
if(correctAnswer != answer){
return false;
}
//If the false was not triggered it must have passed all tests
return true;
}
bool testGetSum(){
uint64_t correctAnswer = 1060;
uint64_t topNum = 100;
uint64_t answer = mee::getSum(mee::getPrimes(topNum));
if(correctAnswer != answer){
return false;
}
//If the false was not triggered it must have passed all tests
return true;
}
bool testGetProduct(){
uint64_t correctAnswer = 0;
std::vector<uint64_t> numbers = {};
uint64_t answer = mee::getProduct(numbers);
if(correctAnswer != answer){
return false;
}
correctAnswer = 57600;
numbers = {2, 2, 3, 3, 4, 4, 100};
answer = mee::getProduct(numbers);
if(correctAnswer != answer){
return false;
}
//If a false was not triggered it must have passed all tests
return true;
}
bool testIsFound(){
bool correctAnswer = true;
std::vector<uint64_t> testVector = mee::getPrimes((uint64_t)100);
uint64_t searchFor = 79;
bool answer = mee::isFound(testVector, searchFor);
if(answer != correctAnswer){
std::cout << "isFound() is failed at test 1" << std::endl;
return false;
}
searchFor = 97;
answer = mee::isFound(testVector, searchFor);
if(answer != correctAnswer){
std::cout << "isFound() is failed at test 2" << std::endl;
return false;
}
searchFor = 88;
correctAnswer = false;
answer = mee::isFound(testVector, searchFor);
if(answer != correctAnswer){
std::cout << "isFound() is failed at test 3" << std::endl;
return false;
}
//If the false was not triggered it must have passed all tests
return true;
}
bool testGetPermutations(){
std::string permString = "012";
std::vector<std::string> correctAnswer {"012", "021", "102", "120", "201", "210"};
std::vector<std::string> answer = mee::getPermutations(permString);
if(answer != correctAnswer){
return false;
}
//If the false was not triggered it must have passed all tests
return true;
}
bool testGetFib(){
//Test the imbeded type getFib function
uint64_t correctAnswer = 144;
uint64_t number = 12;
uint64_t answer = mee::getFib(number);
if(correctAnswer != answer){
std::cout << "getFit() failed at test 1" << std::endl;
return false;
}
number = 20;
correctAnswer = 6765;
answer = mee::getFib(number);
if(correctAnswer != answer){
std::cout << "getFit() failed at test 2" << std::endl;
return false;
}
//Test the gmp integer function
mpz_class mpzNumber = 12;
mpz_class longCorrectAnswer = 144;
mpz_class longAnswer = mee::getFib(mpzNumber);
if(longCorrectAnswer != longAnswer){
std::cout << "getFib() for mpz failed at test 3" << std::endl;
return false;
}
mpzNumber = 4782;
longCorrectAnswer = "1070066266382758936764980584457396885083683896632151665013235203375314520604694040621889147582489792657804694888177591957484336466672569959512996030461262748092482186144069433051234774442750273781753087579391666192149259186759553966422837148943113074699503439547001985432609723067290192870526447243726117715821825548491120525013201478612965931381792235559657452039506137551467837543229119602129934048260706175397706847068202895486902666185435124521900369480641357447470911707619766945691070098024393439617474103736912503231365532164773697023167755051595173518460579954919410967778373229665796581646513903488154256310184224190259846088000110186255550245493937113651657039447629584714548523425950428582425306083544435428212611008992863795048006894330309773217834864543113205765659868456288616808718693835297350643986297640660000723562917905207051164077614812491885830945940566688339109350944456576357666151619317753792891661581327159616877487983821820492520348473874384736771934512787029218636250627816";
longAnswer = mee::getFib(mpzNumber);
if(longCorrectAnswer != longAnswer){
std::cout << "getFib() for mpzfailed at test 4" << std::endl;
return false;
}
//If the false was not triggered it must have passed all tests
return true;
}
bool testGetAllFib(){
std::vector<uint64_t> correctAnswer {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89};
uint64_t highestNumber = 100;
std::vector<uint64_t> answer = mee::getAllFib(highestNumber);
if(correctAnswer != answer){
return false;
}
correctAnswer = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987};
highestNumber = 1000;
answer = mee::getAllFib(highestNumber);
if(correctAnswer != answer){
return false;
}
//If a false was not triggered it must have passed all tests
return true;
}
bool testBubbleSort(){
unsigned int NUM_TO_GENERATE = 10000;
std::default_random_engine generator(std::random_device{}());
std::uniform_int_distribution<int> dist(1, INT_MAX);
std::vector<int> nums;
//Run through the appropriate number of numbers to generate and add them to the vector
for(int cnt = 0;cnt < NUM_TO_GENERATE;++cnt){
nums.push_back(dist(generator));
}
//Sort the numbers with my algorithm
mee::bubbleSort(nums);
//Make sure each number is not < the one in behind it
for(int cnt = 1;cnt < nums.size();++cnt){
if(nums.at(cnt) < nums.at(cnt - 1)){
return false;
std::cout << "nums.size() " << nums.size() << "\ncnt " << cnt << std::endl;
}
}
//If the false was not triggered then everything must have been sorted correctly
return true;
}
bool testQuickSort(){
unsigned int NUM_TO_GENERATE = 10000;
std::default_random_engine generator(std::random_device{}());
std::uniform_int_distribution<int> dist(1, INT_MAX);
std::vector<int> nums;
//Run through the appropriate number of numbers to generate and add them to the vector
for(int cnt = 0;cnt < NUM_TO_GENERATE;++cnt){
nums.push_back(dist(generator));
}
//Sort the numbers with my algorithm
mee::quickSort(nums);
//Make sure each number is not < the one in behind it
for(int cnt = 1;cnt < nums.size();++cnt){
if(nums.at(cnt) < nums.at(cnt - 1)){
return false;
}
}
//If the false was not triggered then everything must have been sorted correctly
return true;
}
bool testSearch(){
int64_t found = -1;
//Create a vector of numbers
std::vector<int> nums {1, 20, 3, 40, 5, 60, 7, 80, 9};
//Search for one that is in the vector
found = mee::search(nums, 1);
if(found != 0){ //This number is in the vector, if it was not found in the vector there is a problem
return false;
}
//Search for another that is in the vector
found = mee::search(nums, 9);
if(found != 8){ //This number is in the vector, if it was not found in the vector there is a problem
return false;
}
//Search for another that is in the vector
found = mee::search(nums, 60);
if(found != 5){ //This number is in the vector, if it was not found in the vector there is a problem
return false;
}
//Search for a number that is not in the vector
found = mee::search(nums, 6);
if(found != -1){
return false;
}
//If it didn't trigger a false then everything went through correctly
return true;
}
bool testFindMin(){
std::vector<int> arr {1, 2, 3, 4, 5, 6, 7, 8, 9};
int answer = 0;
//Test first
answer = mee::findMin(arr);
if(answer != 1){
return false;
}
//Test last
answer = 0;
arr = {9, 8, 7, 6, 5, 4, 3, 2, 1};
answer = mee::findMin(arr);
if(answer != 1){
return false;
}
//Test middle
answer = 0;
arr = {9, 5, 3, 6, 8, 1, 7, 2, 4};
answer = mee::findMin(arr);
if(answer != 1){
return false;
}
//Test negative
answer = 0;
arr = {-1, -2, -3, -4, -5, -6, -7, -8, -9};
answer = mee::findMin(arr);
if(answer != -9){
return false;
}
//If it hasn't failed a test then return true for passing all the tests
return true;
}
bool testFindMax(){
std::vector<int> arr {1, 2, 3, 4, 5, 6, 7, 8, 9};
int answer = 0;
//Test last
answer = mee::findMax(arr);
if(answer != 9){
return false;
}
//Test first
answer = 0;
arr = {9, 8, 7, 6, 5, 4, 3, 2, 1};
answer = mee::findMax(arr);
if(answer != 9){
return false;
}
//Test middle
answer = 0;
arr = {9, 5, 3, 6, 8, 1, 7, 2, 4};
answer = mee::findMax(arr);
if(answer != 9){
return false;
}
//Test negative
answer = 0;
arr = {-1, -2, -3, -4, -5, -6, -7, -8, -9};
answer = mee::findMax(arr);
if(answer != -1){
return false;
}
//If it hasn't failed a test then return true for passing all the tests
return true;
}
bool testFindNumOccurrence(){
//Test 1
std::string testString = "abcdefgdd";
char testChar = 'a';
int correctAnswer = 1;
int answer = mee::findNumOccurrence(testString, testChar);
if(correctAnswer != answer){
return false;
}
//Test 2
testChar = 'd';
correctAnswer = 3;
answer = mee::findNumOccurrence(testString, testChar);
if(correctAnswer != answer){
return false;
}
//Test 3
testChar = 'h';
correctAnswer = 0;
answer = mee::findNumOccurrence(testString, testChar);
if(correctAnswer != answer){
return false;
}
//If it hasn't failed a test then return true for passing all the tests
return true;
}
bool testFactorial(){
//Test 1
int num = 1;
int correctAnswer = 1;
int answer = mee::factorial(num);
if(correctAnswer != answer){
return false;
}
//Test 2
num = 10;
correctAnswer = 3628800;
answer = mee::factorial(num);
if(correctAnswer != answer){
return false;
}
//Test 3
num = -5;
correctAnswer = 1;
answer = mee::factorial(num);
if(correctAnswer != answer){
return false;
}
//If it hasn't failed a test then return true for passing all the tests
return true;
}
bool testIsPalindrome(){
//Test 1
std::string str = "101";
bool correctAnswer = true;
bool answer = mee::isPalindrome(str);
if(correctAnswer != answer){
return false;
}
//Test 2
str = "100";
correctAnswer = false;
answer = mee::isPalindrome(str);
if(correctAnswer != answer){
return false;
}
//Test 3
str = "";
correctAnswer = true;
answer = mee::isPalindrome(str);
if(correctAnswer != answer){
return false;
}
//If it hasn't failed a test then return true for passing all the tests
return true;
}
bool testToBin(){
//Test 1
int num = 7;
std::string correctAnswer = "111";
std::string answer = mee::toBin(num);
if(correctAnswer != answer){
return false;
}
//Test 2
num = 0;
correctAnswer = "0";
answer = mee::toBin(num);
if(correctAnswer != answer){
return false;
}
//Test 3
num = 1000000;
correctAnswer = "11110100001001000000";
answer = mee::toBin(num);
if(correctAnswer != answer){
return false;
}
//Test 4
uint64_t num2 = 8;
correctAnswer = "1000";
answer = mee::toBin(num2);
if(correctAnswer != answer){
return false;
}
//If it hasn't failed a test then return true for passing all the tests
return true;
}
bool testPrintVector(){
//Test 1
std::vector<int> nums;
std::string correctAnswer = "[]";
std::string answer = mee::printVector(nums);
if(correctAnswer != answer){
return false;
}
//Test 2
nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
correctAnswer = "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]";
answer = mee::printVector(nums);
if(correctAnswer != answer){
return false;
}
//Test 3
nums = {-3, -2, -1, 0, 1, 2, 3};
correctAnswer = "[-3, -2, -1, 0, 1, 2, 3]";
answer = mee::printVector(nums);
if(correctAnswer != answer){
return false;
}
//Test 4
std::vector<std::string> strings = {"A", "B", "C"};
correctAnswer = "[A, B, C]";
answer = mee::printVector(strings);
if(correctAnswer != answer){
return false;
}
//Test 5
strings = {"abc", "def", "ghi"};
correctAnswer = "[abc, def, ghi]";
answer = mee::printVector(strings);
if(correctAnswer != answer){
return false;
}
//If it hasn't failed a test then return true for passing all the tests
return true;
}
/* Results:
Function getPrimes() passed the test
The test took 9.400 microseconds
Function getNumPrimes() passed the test
The test took 6.400 microseconds
Function isPrime() passed the test
The test took 200.000 nanoseconds
Function getFactors() passed the test
The test took 5.400 microseconds
Function getDivisors() passed the test
The test took 2.000 microseconds
Function getSum() passed the test
The test took 8.500 microseconds
Function getProduct() passed the test
The test took 1.200 microseconds
Function isFound() passed the test
The test took 7.100 microseconds
Function getPermutations() passed the test
The test took 8.800 microseconds
Function getFib() passed the test
The test took 221.400 microseconds
Function getAllFib() passed the test
The test took 4.100 microseconds
Function bubbleSort() passed the test
The test took 1.186 seconds
Function quickSort() passed the test
The test took 3.580 milliseconds
Function search() passed the test
The test took 1.300 microseconds
Function findMin() passed the test
The test took 1.700 microseconds
Function findMax() passed the test
The test took 1.600 microseconds
Function findNumOccurrence() passed the test
The test took 1.400 microseconds
Function factorial() passed the test
The test took 200.000 nanoseconds
Function isPalindrome() passed the test
The test took 1.400 microseconds
Function toBin() passed the test
The test took 9.300 microseconds
Function testPrintVector() passed the test
The test took 9.900 microseconds
*/