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