diff --git a/CSCI251-A3 - Spring 2019.pdf b/CSCI251-A3 - Spring 2019.pdf new file mode 100644 index 0000000..739a040 Binary files /dev/null and b/CSCI251-A3 - Spring 2019.pdf differ diff --git a/auxiliary.cpp b/auxiliary.cpp new file mode 100644 index 0000000..69c355e --- /dev/null +++ b/auxiliary.cpp @@ -0,0 +1,168 @@ +// License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html + +#include +#include + +#include "auxiliary.h" +#include "general_functions.h" + +using namespace std; + +processArguments::processArguments( + int theArgc, const char* const theArgv[]): + argc(theArgc), argv(theArgv) +{ + checkIfArgcWithinRange(); + checkIfArg2Is0Or1OnlyAndSetMintOrMelt(); + checkIfCorrectNumberOfArgumentsForMintOrMelt(); + checkIf3rdOnwardArgsAreNotPositveInt(); + setRemainingDataMemberValues(); + printProcessedArguments(); +} + +void processArguments::checkIfArgcWithinRange() +{ + if (argc < 5 or argc > 6) + { + cerr + << "For Mint, no. of arguments must be 6 and for Melt no." + << " of arguments must be 5 but recived " << argc + << " argument(s).\n"; + exit(1); + } +} + +void processArguments::checkIfArg2Is0Or1OnlyAndSetMintOrMelt() +{ + string secondArgumentIncorrect = + string("Second argument can be only 0 for Mint and 1 for Melt") + + ". But it is '" + argv[1] + "'.\n"; + if (is_whole_number(argv[1])) + { + mintOrMelt = stoi(argv[1]); + if (mintOrMelt > 1 or mintOrMelt < 0) + { + cerr << secondArgumentIncorrect; + exit(1); + } + } + else + { + cerr << secondArgumentIncorrect; + exit(1); + } +} + +void processArguments::checkIfCorrectNumberOfArgumentsForMintOrMelt() +{ + if (mintOrMelt == mint and argc != 6) + { + cerr + << "For Mint, no. of arguments can be excatly 6 only. But " + << "recived " << argc << ".\n"; + exit(1); + } + else if (mintOrMelt == melt and argc != 5) + { + cerr + << "For Melt, no. of arguments can be excatly 5 only. But " + << "recived " << argc << ".\n"; + exit(1); + } +} + +void processArguments::checkIf3rdOnwardArgsAreNotPositveInt() +{ + checkIfArgumentIsNotPositiveInt(argv[2], "3rd"); + checkIfArgumentIsNotPositiveInt(argv[3], "4th"); + checkIfArgumentIsNotPositiveInt(argv[4], "5th"); + if (mintOrMelt == mint) + { + checkIfArgumentIsNotPositiveInt(argv[5], "6th"); + } +} + +void processArguments::checkIfArgumentIsNotPositiveInt ( + const char* argument, string itsIndex) +{ + if (! is_natural_number(argument)) + { + cerr + << "All arguments from 3rd onward must be positive " + << "integer but " << itsIndex << " i.e. '" << argument + << "' is not.\n"; + exit(1); + } +} + +void processArguments::setRemainingDataMemberValues() +{ + seed = stoi(argv[2]); + length= stoi(argv[3]); + size= stoi(argv[4]); + if (mintOrMelt == mint) + { + mod= stoi(argv[5]); + } +} + + +string processArguments::codewordType() const +{ + if (mintOrMelt == mint) + { + return "mint"; + } + else if (mintOrMelt == melt) + { + return "melt"; + } + else + { + cerr_and_exit( + 2, + "Unexpected Internal", + __FILE__, + __func__, + __LINE__); + } +} + +short processArguments::codewordInt() const +{ + return mintOrMelt; +} + +int processArguments::randomGeneratorSeed() const +{ + return seed; +} + +int processArguments::codewordLength() const +{ + return length; +} + +int processArguments::codebookSize() const +{ + return size; +} + +int processArguments::modulus() const +{ + return mod; +} + +void processArguments::printProcessedArguments() const +{ + cout + << "Mode: " << codewordType() << " " + << "Seed: " << seed << " " + << "Codeword Length: " << length << " " + << "Codebook size: " << size; + if (mintOrMelt == mint) + { + cout << " Modulus: " << mod; + } + cout << endl; +} diff --git a/auxiliary.h b/auxiliary.h new file mode 100644 index 0000000..4df351f --- /dev/null +++ b/auxiliary.h @@ -0,0 +1,41 @@ +// License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html + +#ifndef _AUXILIARY_H_ +#define _AUXILIARY_H_ + +#include + +class processArguments +{ + public: + processArguments(int theArgc, const char* const theArgv[]); + std::string codewordType() const; + short codewordInt() const; + int randomGeneratorSeed() const; + int codewordLength() const; + int codebookSize() const; + int modulus() const; + private: + short mint = 0; + short melt = 1; + short mintOrMelt; + int seed; + int length; + int size; + int mod; + int argc; + const char* const *argv; + // if any of the checks fail, program exits immediately w/ + // error code 1 + void checkIfArgcWithinRange(); + void checkIfArg2Is0Or1Only(); + void checkIfArg2Is0Or1OnlyAndSetMintOrMelt(); + void checkIfCorrectNumberOfArgumentsForMintOrMelt(); + void checkIf3rdOnwardArgsAreNotPositveInt(); + void checkIfArgumentIsNotPositiveInt( + const char* argument, std::string itsIndex); + void setRemainingDataMemberValues(); + void printProcessedArguments() const; +}; + +#endif diff --git a/cfc.cpp b/cfc.cpp new file mode 100644 index 0000000..99710be --- /dev/null +++ b/cfc.cpp @@ -0,0 +1,153 @@ +// License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html + +#include +#include +#include + +#include "cfc.h" +#include "generateValue.h" + +using namespace std; + +driver::driver(processArguments &theProgArgs): +ProgramArguments(theProgArgs) +{ + if (ProgramArguments.codewordType() == "mint") + { + Mint aMint(Mint::zeroSymbol, ProgramArguments.modulus()); + processMintOrMelt(aMint); + } + else if (ProgramArguments.codewordType() == "melt") + { + Melt aMelt(Melt::zeroSymbol); + processMintOrMelt(aMelt); + } + else + { + cerr_and_exit( + 2, + "unexpected", + __FILE__, + __func__, + __LINE__, + "ProgArgs.codewordType() is neither mint nor melt. Its " + + ProgramArguments.codewordType() +'.' + ); + } +} + +void driver::processMint(Codebook> &theCodebook) +{ + // adding rest of the randomly generated codewords + for (int i=1; i < ProgramArguments.codebookSize(); i++) + { + Codeword aCodeword; + for (int j=0; j < ProgramArguments.codewordLength(); j++) + { + int randomNumber = generateMint( + ProgramArguments.randomGeneratorSeed(), + ProgramArguments.modulus() + ); + Mint aMint(randomNumber, ProgramArguments.modulus()); + aCodeword.push_back(aMint); + } + theCodebook.push_back(aCodeword); + } + theCodebook.Display(); +} + +void driver::processMelt(Codebook> &theCodebook) +{ + // adding rest of the randomly generated codewords + for (int i=1; i < ProgramArguments.codebookSize(); i++) + { + Codeword aCodeword; + for (int j=0; j < ProgramArguments.codewordLength(); j++) + { + char randomCharacter = generateMelt( + ProgramArguments.randomGeneratorSeed() + ); + Melt aMelt(randomCharacter); + aCodeword.push_back(aMelt); + } + theCodebook.push_back(aCodeword); + } + theCodebook.Display(); +} + +void driver::processMint(Codebook> &theCodebook) +{ + cerr_and_exit( + 2, + "unexpected", + __FILE__, + __func__, + __LINE__, + "function called for processing Melt cases." + ); +} + +void driver::processMelt(Codebook> &theCodebook) +{ + cerr_and_exit( + 2, + "unexpected", + __FILE__, + __func__, + __LINE__, + "function called for processing Mint cases." + ); +} + + Mint::Mint(int Number, int Modulus) : modulus(Modulus) + { + if (Number < modulus and Number >= 0) + { + number = Number; + } + else if (Number > modulus) + { + number = Number%modulus; + } + else if (Number < 0) + { + + } + } + + int Mint::getNumber() const + { + return number; + } + + int Mint::getSymbol() const + { + return getNumber(); + } + + int Mint::operator-(const Mint mint2) const + { + int beforeModulating = number - mint2.getNumber(); + int afterModulating = modulate(beforeModulating, modulus); + return afterModulating; + } + + Melt::Melt(char Character) + { + character = tolower(Character); + } + + char Melt::getCharacter() const + { + return character; + } + + char Melt::getSymbol() const + { + return getCharacter(); + } + +int Melt::operator-(const Melt melt2) const +{ + return (character != melt2.getCharacter()); +} diff --git a/cfc.h b/cfc.h new file mode 100644 index 0000000..1b8a4df --- /dev/null +++ b/cfc.h @@ -0,0 +1,457 @@ +// License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html + +#ifndef _CFC_H_ +#define _CFC_H_ + +#include + +#include "auxiliary.h" +#include "general_functions.h" + +class Mint +{ + public: + Mint() {}; + Mint(int Number, int Modulus); + int getNumber() const; + // standard function to be used for template codeword. + // it just 'return getNumber();' + int getSymbol() const; + int operator-(const Mint mint2) const; + static const int zeroSymbol = 0; + private: + int number; + int modulus; +}; + +class Melt +{ + public: + Melt() {}; + Melt(char Character); + char getCharacter() const; + // standard function to be used for template codeword. + // it just 'return getCharacter();' + char getSymbol() const; + int operator-(const Melt melt2) const; + static const char zeroSymbol = 'a'; + private: + char character; +}; + +template +class Codeword +{ + public: + Codeword(); + Codeword(std::vector &aTVector); + Codeword(const Codeword &aCodeword); + void push_back(T symbol); + std::vector getCodeword() const; + int getWeight() const; + // return -1 if encounters error i.e.: + // If size of own codeword and codeword passed as argument + // mismatch However It Will Not Happen Within Runtime Of This + // Program. This is just defensive programming. + int Distance(const Codeword &aCodeword) const; + void Display() const; + int size() const; + T getSymbolByIndex(int index) const; + //bool isZeroCodeword() const; + private: + void Weight(); + void incrementalWeight(); + //void calculateIfZeroCodeword(); + std::vector codeword; + int weight = 0; + //bool isZerocodeword; +}; + +template +class Codebook +{ + public: + Codebook(); + Codebook(std::vector &aTVector); + Codebook(const Codebook &aCodebook); + void push_back(T codeword); + std::vector getCodebook() const; + void Display() const; + int getMinimumWeight() const; + std::vector> getDistance() const; + int getMinimumDistance() const; + private: + // this function simply calls other three private functions + void doCalculations(); + void minimumWeight(); + void calcDistance(); + void minimumDistance(); + void doIncrementalCalculations(); + void minimumIncrementalWeight(); + void calcIncrementalDistance(); + void minimumIncrementalDistance(); + int minWeight = 0; + std::vector> distance; + int minDistance = 0; + std::vector codebook; + inline void updateIfNewMinimumDistance(int aDistance); +}; + +class driver +{ + public: + driver(processArguments &ProgArgs); + private: + template + void processMintOrMelt(U aMintOrMelt); + void processMint(Codebook> &theCodebook); + void processMelt(Codebook> &theCodebook); + // placeholder functions which are never called and + // will print error and quit if called + void processMint(Codebook> &theCodebook); + void processMelt(Codebook> &theCodebook); + processArguments &ProgramArguments; +}; + + +/******TEMPLATE CLASES AND FUNCTIONS DEFINITION STARTS FROM HERE******/ + + +template +void driver::processMintOrMelt(U aMintOrMelt) +{ + Codebook> theCodebook; + Codeword aCodeword; + for (int i=0; i < 1 &&i < ProgramArguments.codebookSize(); i++) + { + for (int j=0; j < ProgramArguments.codewordLength(); j++) + { + aCodeword.push_back(aMintOrMelt); + } + theCodebook.push_back(aCodeword); + } + if (typeid(U) == typeid(Mint)) + { + processMint(theCodebook); + } + else if (typeid(U) == typeid(Melt)) + { + processMelt(theCodebook); + } +} + +template +Codeword::Codeword() +{ +} + +template +Codeword::Codeword(std::vector &aTVector) +{ + for (T symbol: aTVector) + { + codeword.push_back(symbol); + } + Weight(); +} + +template +Codeword::Codeword(const Codeword &aCodeword) +{ + codeword = aCodeword.getCodeword(); + weight = aCodeword.getWeight(); +} + +template +void Codeword::push_back(T symbol) +{ + codeword.push_back(symbol); + incrementalWeight(); +} + +template +std::vector Codeword::getCodeword() const +{ + return codeword; +} + +template +int Codeword::getWeight() const +{ + return weight; +} + +template +int Codeword::Distance(const Codeword &aCodeword) const +{ + int distance = 0; + if (codeword.size() != aCodeword.size()) + { + cerr_only( + "Internal", + __FILE__, + __func__, + __LINE__, + "For calculating Codeword Distance, no. of symbols in own" + " codeword and codeword passed as argument mismatch. " + "Though technically a possiblity, it should not happen " + "within the run of this program." + ); + distance = -1; + } + else + { + for (int i=0; i < size(); i++) + { + distance += codeword[i] - aCodeword.getSymbolByIndex(i); + } + } + return distance; +} + +template +void Codeword::Display() const +{ + for(T symbol: codeword) + { + std::cout << symbol.getSymbol() << " "; + } + std::cout << " Weight: " << weight << std::endl; +} + +template +int Codeword::size() const +{ + return codeword.size(); +} + +template +T Codeword::getSymbolByIndex(int index) const +{ + if (codeword.size() > index) + { + return codeword[index]; + } + else + { + cerr_only( + "internal", + __FILE__, + __func__, + __LINE__, + "Index symbol requqested is greater than cointainer size " + "An empty symbol of same type will be returned but this " + "will therefore give garbage result." + ); + T emptySymbol; + return emptySymbol; + } +} + +template +void Codeword::Weight() +{ + weight = 0; + for (T symbol: codeword) + { + if (symbol.getSymbol() != symbol.zeroSymbol) + { + weight++; + } + } +} + +template +void Codeword::incrementalWeight() +{ + if (codeword[codeword.size()-1].getSymbol() + != codeword[0].zeroSymbol) + { + weight++; + } +} + +template +Codebook::Codebook() +{ +} + +template +Codebook::Codebook(std::vector &aTVector) +{ + for (T codeword: aTVector) + { + codebook.push_back(codeword); + } + doCalculations(); +} + +template +Codebook::Codebook(const Codebook &aCodebook) +{ + minWeight = aCodebook.getMinimumWeight(); + distance = aCodebook.getDistance(); + minDistance = aCodebook.getMinimumDistance(); + codebook = aCodebook.getCodebook(); +} + +template +void Codebook::push_back(T codeword) +{ + codebook.push_back(codeword); + doIncrementalCalculations(); +} + +template +std::vector Codebook::getCodebook() const +{ + return codebook; +} + +template +void Codebook::Display() const +{ + for (T codeword: codebook) + { + codeword.Display(); + } + std::cout + << "Minimum Weight: " << minWeight << '\n' + << "Minimum Distance: " << minDistance << '\n' + << "Distances Table:" << std::endl; + for (auto row: distance) + { + for (int eachDistance: row) + { + std::cout << eachDistance << " "; + } + std::cout << "\b\n"; + } + std::cout << std::flush; +} + +template +int Codebook::getMinimumWeight() const +{ + return minWeight; +} + +template +std::vector> Codebook::getDistance() const +{ + return distance; +} + +template +int Codebook::getMinimumDistance() const +{ + return minDistance; +} + +template +void Codebook::doCalculations() +{ + minimumWeight(); + calcDistance(); + minimumDistance(); +} + +template +void Codebook::minimumWeight() +{ + for (T codeword: codebook) + { + int weight = codeword.getWeight(); + if (weight < minWeight or minWeight == 0) + { + minWeight = weight; + } + } +} + +template +void Codebook::calcDistance() +{ + int i = 0; + for (T codeword: codebook) + { + distance.emplace_back(); + for(T otherCodeword: codebook) + { + int aDistance = codeword.Distance(otherCodeword); + distance[i].push_back(aDistance); + } + } +} + +template +void Codebook::minimumDistance() +{ + for (std::vector distanceVector: distance) + { + for (int aDistance: distanceVector) + { + if ((aDistance < minDistance + and aDistance != 0) + or minDistance == 0) + { + minDistance = aDistance; + } + } + } +} + +template +void Codebook::doIncrementalCalculations() +{ + minimumIncrementalWeight(); + calcIncrementalDistance(); + minimumDistance(); +} + +template +void Codebook::minimumIncrementalWeight() +{ + int weight = codebook[codebook.size()-1].getWeight(); + if (weight < minWeight or minWeight == 0) + { + minWeight = weight; + } +} + +template +void Codebook::calcIncrementalDistance() +{ + int lastCodeword = codebook.size()-1; + + // Adding new column to table + // previous codewords - new codeowrd + for (int i=0; i < distance.size(); i++) + { + int aDistance = codebook[i].Distance(codebook[lastCodeword]); + distance[i].push_back(aDistance); + } + + // Adding new row to table + // new codeword - all Codewords + distance.emplace_back(); + for(T aCodeword: codebook) + { + int aDistance = codebook[lastCodeword].Distance(aCodeword); + distance[distance.size()-1].push_back(aDistance); + } +} + +template +void Codebook::minimumIncrementalDistance() +{ + for (int aDistance: distance[distance.size()-1]) + { + if (aDistance < minDistance or minDistance == 0) + { + minDistance = aDistance; + } + } +} + +#endif diff --git a/driver.cpp b/driver.cpp new file mode 100644 index 0000000..2eca9c5 --- /dev/null +++ b/driver.cpp @@ -0,0 +1,15 @@ +// License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html + +#include + +#include "auxiliary.h" +#include "cfc.h" + +using namespace std; + +int main (const int argc, const char* const argv[]) +{ + processArguments progArgs(argc, argv); + driver runProgram(progArgs); + return 0; +} diff --git a/general_functions.cpp b/general_functions.cpp new file mode 100644 index 0000000..e3f840d --- /dev/null +++ b/general_functions.cpp @@ -0,0 +1,207 @@ +// License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html + +#include +#include +#include +#include +#include +#include +#include + +#include "general_functions.h" + +using namespace std; + +bool is_natural_number(const char* c_str) +{ + bool answer = false; + if (is_whole_number(c_str)) + { + if (stoi(c_str) > 0) + { + answer = true; + } + } + return answer; +} + +bool is_whole_number(const char* c_str) +{ + bool answer = false; + int c_str_length = strlen(c_str); + if (c_str_length < 1) + { + // nothing needs to be done + } + else if (! isdigit(c_str[0])) + { + // nothing needs to be done + } + else + { + answer = true; + // c_str[0] is checked in else if statement. + for (int i=1; i < (c_str_length-1); i++) + if (! isdigit(c_str[i])) + { + answer = false; + } + } + return answer; +} + +void get_textfile_lines(string filename, vector &file_lines) +{ + ifstream file(filename); + + if (! file.good()) + { + cerr << "Failed to open/read file: " << filename\ + << ". Non-exhaustive list of possible reasons:\n"\ + << "1. File does not exist.\n"\ + << "2. Unable to read file due to:\n"\ + << "2.1 Don't have read access to file\n"\ + << "2.2 File is opened elsewhere and some program have a "\ + << "lock on file.\n"; + exit(2); + } + +// cout << "Reading file: " << filename << endl; + + int i=0; + while (file.good()) + { + file_lines.push_back(""); + getline(file, file_lines[i]); + i++; + } + + file.close(); +} + +int random_int(int minimum, int maximum) +{ + static random_device seed; + static mt19937 random_number_generator(seed()); + uniform_int_distribution range( + minimum, maximum); + return range(random_number_generator); +} + +// SOURCE: cppreference.com +float random_float(float minimum, float maximum) +{ + static random_device seed; + static mt19937 random_number_generator(seed()); + uniform_real_distribution<> range( + minimum, maximum); + return range(random_number_generator); +} + +void string_to_vector( + string &a_string, + vector &str_vector, + char delimeter) +{ + stringstream str_stream(a_string); + string str = ""; + while(getline(str_stream, str, delimeter)) + { + if (str.length() > 1 and str != "\n") + { + str_vector.push_back(str); + } + } +} + +void pick_random_string( + string &str, const vector &str_vector) +{ + int vector_size = str_vector.size(); + if (vector_size < 1) + { + str = ""; + } + else + { + int i = random_int(0, vector_size-1); + str = str_vector[i]; + } +} + +int modulate(int number, int modulus) +{ + int after_modulation; + if (number >= 0) + { + after_modulation = number % modulus; + } + else if (number < 0) + { + after_modulation = ( + modulus - (absolute_number(number)%modulus)); + } + else + { + // OK, I know this is too much + cerr_and_exit( + 2, + "internal", + __FILE__, + __func__, + __LINE__, + "argument 1 'number' is neither >=0 nor < 0. " + "NOTE: this is just hypothetical situation following " + "defensive programming and should never happen in practice" + ); + } + return after_modulation; +} + + +void cerr_and_exit( + int exit_code, + string error_name, + string file_name, + string function_name, + int line_number, + string additional_message) +{ + cerr_only( + error_name, + file_name, + function_name, + line_number, + additional_message); + exit(exit_code); +} + +void cerr_only( + string error_name, + string file_name, + string function_name, + int line_number, + string additional_message) +{ + if (error_name.size() > 0) + { + error_name[0] = toupper(error_name[0]); + if (error_name[-1] != ' ') + { + error_name += ' '; + } + } + cerr + << error_name << "error occured at:\n" + << "Source code file name: " << file_name << "\n" + << "Function name: " << function_name << "\n" + << "Line number: " << line_number << "\n" + << additional_message; + if (additional_message != "") + { + if (additional_message[-1] != '\n') + { + cerr << '\n'; + } + } +} diff --git a/general_functions.h b/general_functions.h new file mode 100644 index 0000000..ea6bdf3 --- /dev/null +++ b/general_functions.h @@ -0,0 +1,82 @@ +// License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html + +#ifndef _GENERAL_FUNCTIONS_H_ +#define _GENERAL_FUNCTIONS_H_ + +#include +#include + +bool is_natural_number(const char* c_str); + +bool is_whole_number(const char* c_str); + +void get_textfile_lines( + std::string filename, std::vector &file_lines); + +int random_int(int minimum, int maximum); + +float random_float(float minimum, float maximum); + +int modulate(int number, int modulus); + +void cerr_and_exit( + int exit_code, + std::string error_name, + std::string file_name, + std::string function_name, + int line_number, + std::string additional_message = ""); + +void cerr_only( + std::string error_name, + std::string file_name, + std::string function_name, + int line_number, + std::string additional_message); + +/* Its a good practice to prototype all functions including which are + * defined in header file itself such as inline functions before defining + * any function. This way, even if we use one function in another + * function, we do not have to worry about function undefined error + * possibilities. + */ + +inline int absolute_number(int number); + +inline int smaller_number(int a, int b); + +inline int bigger_number(int a, int b); + +inline int absolute_number(int number) +{ + if (number < 0) + return -(number); + else + return number; +} + +inline int smaller_number(int a, int b) +{ + if (a > b) + return b; + else + return a; +} + +inline int bigger_number(int a, int b) +{ + if (a < b) + return b; + else + return a; +} + +void string_to_vector( + std::string &a_string, + std::vector &str_vector, + char delimeter = ','); + +void pick_random_string( + std::string &str, const std::vector &str_vector); + +#endif diff --git a/makefile b/makefile new file mode 100644 index 0000000..ac92622 --- /dev/null +++ b/makefile @@ -0,0 +1,28 @@ +# License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html + +compiler = "CC" +standardCpp11 = "--std=c++11" + +ifeq ($(compiler), "CC") +# gcc, g++, clang etc. follows double-dash '--' convention for non one +# character arguments but banshee CC uses single dash '-' +standardCpp11 = "-std=c++11" +endif + +CFC: auxiliary.o cfc.o driver.o general_functions.o libgenVal.a + $(compiler) $(standardCpp11) -o CFC *.o libgenVal.a + +auxiliary.o: auxiliary.cpp general_functions.h + $(compiler) $(standardCpp11) -c auxiliary.cpp + +cfc.o: cfc.cpp general_functions.h generateValue.h + $(compiler) $(standardCpp11) -c cfc.cpp + +driver.o: driver.cpp auxiliary.h cfc.h + $(compiler) $(standardCpp11) -c driver.cpp + +general_functions.o: general_functions.cpp + $(compiler) $(standardCpp11) -c general_functions.cpp + +clean: + rm *.o diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..a317940 --- /dev/null +++ b/readme.txt @@ -0,0 +1,27 @@ +# License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html + +NOTE: will not compile if libgenVal.a and generateValue.h are missing +NOTE 2: general_function.h & general_function.cpp files are carried from previous assignments and additional functions related to this assignment added. + +Compile on banshee as: +$ gmake +OR +$ gmake CFC +OR +$ CC -std=c++11 -o CFC *.cpp libgenVal.a + +Assumptions and program behaviour +In: +int difference = Mint1 - Mint2; +both Mint have same modulus, otherwise, it would not make sense. +Plus In: +int difference = Melt2 - Melt2; +Both Mint and Melt, return an int even though usual expected return for operator-() is another object of same type. This is as per specification, Codeword expects an int return when calculating difference bewtween two objects of same type. + +If user give number to Mint object higher than its modulus or less than 0 than Mint itself modulates it before storing in int number variable. So, number passed to Mint and returned by calling Mint.getNumber() function may not be same. NOTE: this is a hypothetical scenerio when someone else may use our written classes and functions as library. The program itself gives number which is within modulus range. + +Error exit code list: +[For exact cause, see stderr] +1 - error related to arguments +2 - Program internal hypothetical errors which should never happen. +3 - Technically possible errors but which should not happen within the runtime of this program.