Upload files to ''
This commit is contained in:
		
							parent
							
								
									31452569af
								
							
						
					
					
						commit
						00ae951bd7
					
				
							
								
								
									
										
											BIN
										
									
								
								CSCI251-A3 - Spring 2019.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								CSCI251-A3 - Spring 2019.pdf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										168
									
								
								auxiliary.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								auxiliary.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,168 @@
 | 
			
		||||
// License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html
 | 
			
		||||
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										41
									
								
								auxiliary.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								auxiliary.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
			
		||||
// License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html
 | 
			
		||||
 | 
			
		||||
#ifndef _AUXILIARY_H_
 | 
			
		||||
#define _AUXILIARY_H_
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
							
								
								
									
										153
									
								
								cfc.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								cfc.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,153 @@
 | 
			
		||||
// License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html
 | 
			
		||||
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
 | 
			
		||||
#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<Codeword<Mint>> &theCodebook)
 | 
			
		||||
{
 | 
			
		||||
    // adding rest of the randomly generated codewords
 | 
			
		||||
    for (int i=1; i < ProgramArguments.codebookSize(); i++)
 | 
			
		||||
    {
 | 
			
		||||
        Codeword<Mint> 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<Codeword<Melt>> &theCodebook)
 | 
			
		||||
{
 | 
			
		||||
    // adding rest of the randomly generated codewords
 | 
			
		||||
    for (int i=1; i < ProgramArguments.codebookSize(); i++)
 | 
			
		||||
    {
 | 
			
		||||
        Codeword<Melt> 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<Codeword<Melt>> &theCodebook)
 | 
			
		||||
{
 | 
			
		||||
    cerr_and_exit(
 | 
			
		||||
        2,
 | 
			
		||||
        "unexpected",
 | 
			
		||||
        __FILE__,
 | 
			
		||||
        __func__,
 | 
			
		||||
        __LINE__,
 | 
			
		||||
        "function called for processing Melt cases."
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void driver::processMelt(Codebook<Codeword<Mint>> &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());
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										457
									
								
								cfc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										457
									
								
								cfc.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,457 @@
 | 
			
		||||
// License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html
 | 
			
		||||
 | 
			
		||||
#ifndef _CFC_H_
 | 
			
		||||
#define _CFC_H_
 | 
			
		||||
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#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<typename T>
 | 
			
		||||
class Codeword
 | 
			
		||||
{
 | 
			
		||||
    public:
 | 
			
		||||
        Codeword();
 | 
			
		||||
        Codeword(std::vector<T> &aTVector);
 | 
			
		||||
        Codeword(const Codeword<T> &aCodeword);
 | 
			
		||||
        void push_back(T symbol);
 | 
			
		||||
        std::vector<T> 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<T> &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<T> codeword;
 | 
			
		||||
        int weight = 0;
 | 
			
		||||
        //bool isZerocodeword;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
class Codebook
 | 
			
		||||
{
 | 
			
		||||
    public:
 | 
			
		||||
        Codebook();
 | 
			
		||||
        Codebook(std::vector<T> &aTVector);
 | 
			
		||||
        Codebook(const Codebook<T> &aCodebook);
 | 
			
		||||
        void push_back(T codeword);
 | 
			
		||||
        std::vector<T> getCodebook() const;
 | 
			
		||||
        void Display() const;
 | 
			
		||||
        int getMinimumWeight() const;
 | 
			
		||||
        std::vector<std::vector<int>> 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<std::vector<int>> distance;
 | 
			
		||||
        int minDistance = 0;
 | 
			
		||||
        std::vector<T> codebook;
 | 
			
		||||
        inline void updateIfNewMinimumDistance(int aDistance);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class driver
 | 
			
		||||
{
 | 
			
		||||
    public:
 | 
			
		||||
        driver(processArguments &ProgArgs);
 | 
			
		||||
    private:
 | 
			
		||||
        template<typename U>
 | 
			
		||||
        void processMintOrMelt(U aMintOrMelt);
 | 
			
		||||
        void processMint(Codebook<Codeword<Mint>> &theCodebook);
 | 
			
		||||
        void processMelt(Codebook<Codeword<Melt>> &theCodebook);
 | 
			
		||||
        // placeholder functions which are never called and
 | 
			
		||||
        // will print error and quit if called
 | 
			
		||||
        void processMint(Codebook<Codeword<Melt>> &theCodebook);
 | 
			
		||||
        void processMelt(Codebook<Codeword<Mint>> &theCodebook);
 | 
			
		||||
        processArguments &ProgramArguments;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******TEMPLATE CLASES AND FUNCTIONS DEFINITION STARTS FROM HERE******/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename U>
 | 
			
		||||
void driver::processMintOrMelt(U aMintOrMelt)
 | 
			
		||||
{
 | 
			
		||||
    Codebook<Codeword<U>> theCodebook;
 | 
			
		||||
    Codeword<U> 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<typename T>
 | 
			
		||||
Codeword<T>::Codeword()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
Codeword<T>::Codeword(std::vector<T> &aTVector)
 | 
			
		||||
{
 | 
			
		||||
    for (T symbol: aTVector)
 | 
			
		||||
    {
 | 
			
		||||
        codeword.push_back(symbol);
 | 
			
		||||
    }
 | 
			
		||||
    Weight();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
Codeword<T>::Codeword(const Codeword<T> &aCodeword)
 | 
			
		||||
{
 | 
			
		||||
    codeword = aCodeword.getCodeword();
 | 
			
		||||
    weight = aCodeword.getWeight();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void Codeword<T>::push_back(T symbol)
 | 
			
		||||
{
 | 
			
		||||
    codeword.push_back(symbol);
 | 
			
		||||
    incrementalWeight();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
std::vector<T> Codeword<T>::getCodeword() const
 | 
			
		||||
{
 | 
			
		||||
    return codeword;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
int Codeword<T>::getWeight() const
 | 
			
		||||
{
 | 
			
		||||
    return weight;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
int Codeword<T>::Distance(const Codeword<T> &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<typename T>
 | 
			
		||||
void Codeword<T>::Display() const
 | 
			
		||||
{
 | 
			
		||||
    for(T symbol: codeword)
 | 
			
		||||
    {
 | 
			
		||||
        std::cout << symbol.getSymbol() << " ";
 | 
			
		||||
    }
 | 
			
		||||
    std::cout << "   Weight: "  << weight << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
int Codeword<T>::size() const
 | 
			
		||||
{
 | 
			
		||||
    return codeword.size();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
T Codeword<T>::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<typename T>
 | 
			
		||||
void Codeword<T>::Weight()
 | 
			
		||||
{
 | 
			
		||||
    weight = 0;
 | 
			
		||||
    for (T symbol: codeword)
 | 
			
		||||
    {
 | 
			
		||||
        if (symbol.getSymbol() != symbol.zeroSymbol)
 | 
			
		||||
        {
 | 
			
		||||
            weight++;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void Codeword<T>::incrementalWeight()
 | 
			
		||||
{
 | 
			
		||||
    if (codeword[codeword.size()-1].getSymbol()
 | 
			
		||||
        != codeword[0].zeroSymbol)
 | 
			
		||||
    {
 | 
			
		||||
        weight++;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
Codebook<T>::Codebook()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
Codebook<T>::Codebook(std::vector<T> &aTVector)
 | 
			
		||||
{
 | 
			
		||||
    for (T codeword: aTVector)
 | 
			
		||||
    {
 | 
			
		||||
        codebook.push_back(codeword);
 | 
			
		||||
    }
 | 
			
		||||
    doCalculations();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
Codebook<T>::Codebook(const Codebook<T> &aCodebook)
 | 
			
		||||
{
 | 
			
		||||
    minWeight = aCodebook.getMinimumWeight();
 | 
			
		||||
    distance = aCodebook.getDistance();
 | 
			
		||||
    minDistance = aCodebook.getMinimumDistance();
 | 
			
		||||
    codebook = aCodebook.getCodebook();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void Codebook<T>::push_back(T codeword)
 | 
			
		||||
{
 | 
			
		||||
    codebook.push_back(codeword);
 | 
			
		||||
    doIncrementalCalculations();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
std::vector<T> Codebook<T>::getCodebook() const
 | 
			
		||||
{
 | 
			
		||||
    return codebook;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void Codebook<T>::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<typename T>
 | 
			
		||||
int Codebook<T>::getMinimumWeight() const
 | 
			
		||||
{
 | 
			
		||||
    return minWeight;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
std::vector<std::vector<int>> Codebook<T>::getDistance() const
 | 
			
		||||
{
 | 
			
		||||
    return distance;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
int Codebook<T>::getMinimumDistance() const
 | 
			
		||||
{
 | 
			
		||||
    return minDistance;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void Codebook<T>::doCalculations()
 | 
			
		||||
{
 | 
			
		||||
    minimumWeight();
 | 
			
		||||
    calcDistance();
 | 
			
		||||
    minimumDistance();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void Codebook<T>::minimumWeight()
 | 
			
		||||
{
 | 
			
		||||
    for (T codeword: codebook)
 | 
			
		||||
    {
 | 
			
		||||
        int weight = codeword.getWeight();
 | 
			
		||||
        if (weight < minWeight or minWeight == 0)
 | 
			
		||||
        {
 | 
			
		||||
            minWeight = weight;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void Codebook<T>::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<typename T>
 | 
			
		||||
void Codebook<T>::minimumDistance()
 | 
			
		||||
{
 | 
			
		||||
    for (std::vector<int> distanceVector: distance)
 | 
			
		||||
    {
 | 
			
		||||
        for (int aDistance: distanceVector)
 | 
			
		||||
        {
 | 
			
		||||
            if ((aDistance < minDistance
 | 
			
		||||
                and aDistance != 0)
 | 
			
		||||
                or minDistance == 0)
 | 
			
		||||
            {
 | 
			
		||||
                minDistance = aDistance;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void Codebook<T>::doIncrementalCalculations()
 | 
			
		||||
{
 | 
			
		||||
    minimumIncrementalWeight();
 | 
			
		||||
    calcIncrementalDistance();
 | 
			
		||||
    minimumDistance();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void Codebook<T>::minimumIncrementalWeight()
 | 
			
		||||
{
 | 
			
		||||
    int weight = codebook[codebook.size()-1].getWeight();
 | 
			
		||||
    if (weight < minWeight or minWeight == 0)
 | 
			
		||||
    {
 | 
			
		||||
        minWeight = weight;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void Codebook<T>::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<typename T>
 | 
			
		||||
void Codebook<T>::minimumIncrementalDistance()
 | 
			
		||||
{
 | 
			
		||||
    for (int aDistance: distance[distance.size()-1])
 | 
			
		||||
    {
 | 
			
		||||
        if (aDistance < minDistance or minDistance == 0)
 | 
			
		||||
        {
 | 
			
		||||
            minDistance = aDistance;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										15
									
								
								driver.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								driver.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
			
		||||
// License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										207
									
								
								general_functions.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										207
									
								
								general_functions.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,207 @@
 | 
			
		||||
// License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html
 | 
			
		||||
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <locale>
 | 
			
		||||
#include <random>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
 | 
			
		||||
#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<string> &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<mt19937::result_type> 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<string> &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<string> &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';
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										82
									
								
								general_functions.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								general_functions.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,82 @@
 | 
			
		||||
// License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html
 | 
			
		||||
 | 
			
		||||
#ifndef _GENERAL_FUNCTIONS_H_
 | 
			
		||||
#define _GENERAL_FUNCTIONS_H_
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
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<std::string> &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<std::string> &str_vector,
 | 
			
		||||
    char delimeter = ',');
 | 
			
		||||
 | 
			
		||||
void pick_random_string(
 | 
			
		||||
    std::string &str, const std::vector<std::string> &str_vector);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										28
									
								
								makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								makefile
									
									
									
									
									
										Normal file
									
								
							@ -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
 | 
			
		||||
							
								
								
									
										27
									
								
								readme.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								readme.txt
									
									
									
									
									
										Normal file
									
								
							@ -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.
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user