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