Compare commits

..

No commits in common. "main" and "Template-insert" have entirely different histories.

17 changed files with 46 additions and 2198 deletions

2
.gitignore vendored
View File

@ -2,5 +2,3 @@
*.d *.d
*.o *.o
PmergeMe PmergeMe
RPN
ex00/btc

View File

@ -52,8 +52,6 @@
"iomanip": "cpp", "iomanip": "cpp",
"sstream": "cpp", "sstream": "cpp",
"*.tpp": "cpp", "*.tpp": "cpp",
"chrono": "cpp", "chrono": "cpp"
"list": "cpp",
"ratio": "cpp"
} }
} }

View File

@ -6,7 +6,7 @@
# By: whaffman <whaffman@student.codam.nl> +#+ # # By: whaffman <whaffman@student.codam.nl> +#+ #
# +#+ # # +#+ #
# Created: 2025/03/21 15:00:16 by whaffman #+# #+# # # Created: 2025/03/21 15:00:16 by whaffman #+# #+# #
# Updated: 2025/09/08 16:11:34 by whaffman ######## odam.nl # # Updated: 2025/09/02 11:40:20 by whaffman ######## odam.nl #
# # # #
# **************************************************************************** # # **************************************************************************** #
@ -32,7 +32,6 @@ $(NAME): $(OBJ)
clean: clean:
rm -f $(OBJ) rm -f $(OBJ)
rm -f $(OBJ:.o=.d)
fclean: clean fclean: clean
rm -f $(NAME) rm -f $(NAME)

View File

@ -1,2 +0,0 @@
NAME := btc
include ../common.mk

File diff suppressed because it is too large Load Diff

View File

@ -1,62 +0,0 @@
#pragma once
#include <map>
#include <string>
#include <stdexcept>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <ctime>
#include <exception>
class BitcoinExchange
{
public:
BitcoinExchange() = delete;
BitcoinExchange(const std::string &data_file);
BitcoinExchange(const BitcoinExchange &other);
~BitcoinExchange();
BitcoinExchange &operator=(const BitcoinExchange &other);
void printData() const;
void loadInputFile(const std::string &filename);
class FileNotFoundException : public std::exception
{
public:
virtual const char *what() const noexcept;
};
class LineFormatException : public std::exception
{
public:
virtual const char *what() const noexcept;
};
class ValueNegativeException : public std::exception
{
public:
virtual const char *what() const noexcept;
};
class ValueTooLargeException : public std::exception
{
public:
virtual const char *what() const noexcept;
};
class DateInvalidException : public std::exception
{
public:
virtual const char *what() const noexcept;
};
private:
std::map<long, float>
_data;
long getTimestamp(const std::string &date) const;
void loadDataFile(const std::string &filename);
float getRate(long timestamp) const;
float getValue(long timestamp, float amount) const;
};

View File

@ -1,16 +0,0 @@
date | value
2011-01-03 | 3
2011-01-03 | 2
2011-01-03 | 1
2011-01-03 | 1.2
2011-01-09 | 1
2016-04-12 | 3
2025-12-12 |2
2012-01-11 | -1
2001-42-42 | 2
2000-01-11 | 1
2012-01-11 | 2147483648
2012-01-11 | 1
2001-123-1 | 3

View File

@ -1,171 +0,0 @@
#include "BitcoinExchange.hpp"
#include <fstream>
#include <iostream>
#include <string>
#include <stdexcept>
BitcoinExchange::BitcoinExchange(const std::string &data_file)
{
loadDataFile(data_file);
}
BitcoinExchange::BitcoinExchange(const BitcoinExchange &other) : _data(other._data)
{
}
BitcoinExchange::~BitcoinExchange()
{
}
BitcoinExchange &BitcoinExchange::operator=(const BitcoinExchange &other)
{
if (this != &other)
{
_data = other._data;
}
return *this;
}
void BitcoinExchange::printData() const
{
for (std::map<long, float>::const_iterator it = _data.begin(); it != _data.end(); ++it)
{
std::cout << it->first << " => " << it->second << std::endl;
}
}
void trimInPlace(std::string &str)
{
// Trim from right
str.erase(str.find_last_not_of(" \t\n\r") + 1);
// Trim from left
str.erase(0, str.find_first_not_of(" \t\n\r"));
}
std::pair<std::string, std::string> split(const std::string &str, char delimiter)
{
size_t pos = str.find(delimiter);
if (pos == std::string::npos)
{
throw BitcoinExchange::LineFormatException();
}
std::string first = str.substr(0, pos);
std::string second = str.substr(pos + 1);
trimInPlace(first);
trimInPlace(second);
if (first.empty() || second.empty())
{
throw BitcoinExchange::LineFormatException();
}
if (second.find_first_not_of("-0123456789.") != std::string::npos)
{
throw BitcoinExchange::LineFormatException();
}
return {first, second};
}
void BitcoinExchange::loadDataFile(const std::string &filename)
{
std::ifstream rate_file(filename);
if (!rate_file)
throw FileNotFoundException();
std::string line;
std::getline(rate_file, line);
while (std::getline(rate_file, line))
{
try
{
std::pair<std::string, std::string> parts = split(line, ',');
long timestamp = getTimestamp(parts.first);
float value = std::stof(parts.second);
_data[timestamp] = value;
}
catch (std::exception &e)
{
std::cerr << e.what() << std::endl;
}
}
}
void BitcoinExchange::loadInputFile(const std::string &filename)
{
std::ifstream input_file(filename);
if (!input_file)
throw FileNotFoundException();
std::string line;
std::getline(input_file, line);
while (std::getline(input_file, line))
{
if (line.empty())
continue;
try
{
std::pair<std::string, std::string> parts = split(line, '|');
long timestamp = getTimestamp(parts.first);
float value = std::stof(parts.second);
if (value < 0)
throw ValueNegativeException();
if (value > 1000)
throw ValueTooLargeException();
std::cout << parts.first << " => " << getValue(timestamp, value) << std::endl;
}
catch (std::exception &e)
{
std::cerr << e.what() << std::endl;
}
}
}
float BitcoinExchange::getRate(long timestamp) const
{
auto it = _data.upper_bound(timestamp);
if (it != _data.begin())
--it;
return it->second;
}
float BitcoinExchange::getValue(long timestamp, float amount) const
{
return getRate(timestamp) * amount;
}
long BitcoinExchange::getTimestamp(const std::string &date) const
{
std::stringstream ss(date);
std::tm tm = {};
ss >> std::get_time(&tm, "%Y-%m-%d");
if (ss.fail())
throw std::invalid_argument("Error: Invalid date format: " + std::string(date));
return static_cast<long>(std::mktime(&tm));
}
const char *BitcoinExchange::FileNotFoundException::what() const noexcept
{
return "Error: File not found";
}
const char *BitcoinExchange::LineFormatException::what() const noexcept
{
return "Error: Line format is incorrect";
}
const char *BitcoinExchange::ValueNegativeException::what() const noexcept
{
return "Error: Value is negative";
}
const char *BitcoinExchange::ValueTooLargeException::what() const noexcept
{
return "Error: Value is too large";
}
const char *BitcoinExchange::DateInvalidException::what() const noexcept
{
return "Error: Date is invalid";
}

View File

@ -1,31 +0,0 @@
#include "BitcoinExchange.hpp"
#include <fstream>
#include <iostream>
#include <string>
int main (int argc, char **argv)
{
if (argc != 2)
{
std::cerr << "Usage: " << argv[0] << " <data_file>" << std::endl;
return 1;
}
try
{
BitcoinExchange btcExchange("data.csv");
btcExchange.loadInputFile(argv[1]);
}
catch (const BitcoinExchange::FileNotFoundException &e)
{
std::cerr << e.what() << std::endl;
return 1;
}
catch (const std::exception &e)
{
std::cerr << "An error occurred: " << e.what() << std::endl;
return 1;
}
return 0;
}

View File

@ -1,2 +0,0 @@
NAME := RPN
include ../common.mk

View File

@ -1,48 +0,0 @@
#pragma once
#include <string>
#include <stack>
class RPN
{
public:
RPN();
RPN(std::string expression);
RPN(const RPN &other);
~RPN();
RPN &operator=(const RPN &other);
void setExpression(std::string expression);
int evaluate();
class NoExpressionException : public std::exception
{
public:
const char *what() const noexcept override;
};
class InvalidExpressionException : public std::exception
{
public:
const char *what() const noexcept override;
};
class DivisionByZeroException : public std::exception
{
public:
const char *what() const noexcept override;
};
class InvalidCharacterException : public std::exception
{
public:
const char *what() const noexcept override;
};
private:
std::string _expression;
bool isWellformed() const;
bool isOperator(char c) const;
int applyOperator(int a, int b, char op) const;
void printStack(std::stack<int> stack) const;
};

View File

@ -1,172 +0,0 @@
#include "RPN.hpp"
#include <algorithm>
#include <stdexcept>
#include <stack>
#include <iostream>
RPN::RPN() : _expression("")
{
}
RPN::RPN(std::string expression) : _expression(expression)
{
}
RPN::RPN(const RPN &other) : _expression(other._expression)
{
}
RPN::~RPN()
{
}
RPN &RPN::operator=(const RPN &other)
{
if (this != &other)
{
_expression = other._expression;
}
return *this;
}
void RPN::setExpression(std::string expression)
{
_expression = expression;
}
int RPN::evaluate()
{
if (_expression.empty())
throw RPN::NoExpressionException();
if (!isWellformed())
throw RPN::InvalidExpressionException();
std::stack<int> stack;
for (char c : _expression)
{
if (std::isspace(c))
continue;
if (std::isdigit(c))
stack.push(c - '0');
else if (isOperator(c))
{
if (stack.size() < 2)
throw RPN::InvalidExpressionException();
int b = stack.top();
stack.pop();
int a = stack.top();
stack.pop();
int result = applyOperator(a, b, c);
stack.push(result);
}
else
{
throw RPN::InvalidCharacterException();
}
// std::cout << "Stack after processing '" << c << "': ";
// printStack(stack);
}
if (stack.size() != 1)
throw RPN::InvalidExpressionException();
return stack.top();
}
bool RPN::isWellformed() const
{
bool needs_space = false;
for (char c : _expression)
{
if (std::isspace(c))
{
if (needs_space)
needs_space = false;
continue;
}
if (std::isdigit(c) || isOperator(c))
{
if (needs_space)
return false;
needs_space = true;
}
else
{
return false;
}
}
return true;
}
bool RPN::isOperator(char c) const
{
if (std::string("+-*/").find(c) != std::string::npos)
return true;
return false;
}
int RPN::applyOperator(int a, int b, char op) const
{
switch (op)
{
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
if (b == 0)
throw RPN::DivisionByZeroException();
return a / b;
default:
throw RPN::InvalidExpressionException();
return 0;
}
}
void RPN::printStack(std::stack<int> stack) const
{
if (stack.empty())
{
std::cout << "[]\n";
return;
}
std::stack<int> temp;
while (!stack.empty())
{
temp.push(stack.top());
stack.pop();
}
std::cout << "[";
while (!temp.empty())
{
std::cout << temp.top();
temp.pop();
if (!temp.empty())
std::cout << ", ";
}
std::cout << "]\n";
}
const char *RPN::NoExpressionException::NoExpressionException::what() const noexcept
{
return "No expression provided.";
}
const char *RPN::InvalidExpressionException::InvalidExpressionException::what() const noexcept
{
return "Invalid RPN expression.";
}
const char *RPN::DivisionByZeroException::DivisionByZeroException::what() const noexcept
{
return "Division by zero.";
}
const char *RPN::InvalidCharacterException::InvalidCharacterException::what() const noexcept
{
return "Invalid character in expression.";
}

View File

@ -1,25 +0,0 @@
#include "RPN.hpp"
#include <iostream>
int main(int argc, char **argv)
{
if (argc != 2)
{
std::cerr << "Usage: " << argv[0] << " <RPN expression>" << std::endl;
return 1;
}
try
{
RPN rpn(argv[1]);
int result = rpn.evaluate();
std::cout << result << std::endl;
}
catch (const std::exception &e)
{
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
return 0;
}

View File

@ -18,7 +18,6 @@ public:
void sort(); void sort();
std::string getString() const; std::string getString() const;
int getComparisons() const;
private: private:
Container _data; Container _data;

View File

@ -13,13 +13,11 @@
#include <vector> #include <vector>
#include <chrono> #include <chrono>
template<typename T> template<typename T>
std::string getTypeName() std::string getTypeName() {
{ if (std::is_same_v<T, std::vector<int>>) return "std::vector<int> ";
if (std::is_same_v<T, std::vector<int>>) if (std::is_same_v<T, std::deque<int>>) return "std::deque<int> ";
return "std::vector<int> ";
if (std::is_same_v<T, std::deque<int>>)
return "std::deque<int> ";
return typeid(T).name(); // fallback to mangled name return typeid(T).name(); // fallback to mangled name
} }
@ -29,8 +27,6 @@ PmergeMe<Container>::PmergeMe(const int argc, const char **argv) : _comparisons(
for (int i = 1; argv[i] != nullptr; ++i) for (int i = 1; argv[i] != nullptr; ++i)
{ {
size_t pos; size_t pos;
try
{
int value = std::stoi(argv[i], &pos); int value = std::stoi(argv[i], &pos);
if (value < 0) if (value < 0)
throw std::invalid_argument("All inputs must be non-negative integers"); throw std::invalid_argument("All inputs must be non-negative integers");
@ -39,15 +35,6 @@ PmergeMe<Container>::PmergeMe(const int argc, const char **argv) : _comparisons(
_data.push_back(value); _data.push_back(value);
} }
catch (const std::out_of_range &e)
{
throw std::out_of_range("Input value out of range");
}
catch (const std::invalid_argument &e)
{
throw std::invalid_argument("Invalid input: not a valid integer");
}
}
if (!areAllUnique()) if (!areAllUnique())
throw std::invalid_argument("All inputs must be unique integers"); throw std::invalid_argument("All inputs must be unique integers");
@ -106,12 +93,6 @@ std::string PmergeMe<Container>::getString() const
return result; return result;
} }
template <typename Container>
int PmergeMe<Container>::getComparisons() const
{
return _comparisons;
}
template <typename Container> template <typename Container>
bool PmergeMe<Container>::less(int a, int b) bool PmergeMe<Container>::less(int a, int b)
{ {
@ -217,3 +198,4 @@ std::ostream &operator<<(std::ostream &os, const PmergeMe<Container> &obj)
return os; return os;
} }

View File

@ -0,0 +1,26 @@
#include "PmergeMe.hpp"
#include <algorithm>
#include <cmath>
#include <cstring>
#include <deque>
#include <iomanip>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
#include <chrono>
std::ostream &operator<<(std::ostream &os, const std::vector<int> &obj)
{
for (std::vector<int>::const_iterator it = obj.begin(); it != obj.end(); ++it)
{
if (it != obj.begin())
os << " ";
os << *it;
}
return os;
}

View File

@ -10,14 +10,12 @@ int main(const int argc, const char **argv)
try try
{ {
PmergeMe<std::vector<int> > sorter_vector(argc, argv); PmergeMe<std::vector<int> > sorter(argc, argv);
std::cout << "Before: " << sorter_vector << std::endl; std::cout << "Before: " << sorter << std::endl;
sorter_vector.sort(); sorter.sort();
PmergeMe<std::deque<int> > sorter_deque(argc, argv); PmergeMe<std::deque<int> > sorter_deque(argc, argv);
sorter_deque.sort(); sorter_deque.sort();
std::cout << "After: " << sorter_deque << std::endl; std::cout << "After: " << sorter_deque << std::endl;
std::cout << "Total comparisons (vector): " << sorter_vector.getComparisons() << std::endl;
std::cout << "Total comparisons (deque): " << sorter_deque.getComparisons() << std::endl;
} }
catch (const std::invalid_argument &e) catch (const std::invalid_argument &e)
@ -25,16 +23,6 @@ int main(const int argc, const char **argv)
std::cerr << "Error: " << e.what() << std::endl; std::cerr << "Error: " << e.what() << std::endl;
return 1; return 1;
} }
catch (const std::out_of_range &e)
{
std::cerr << "Error: "<< e.what() << std::endl;
return 1;
}
catch (const std::exception &e)
{
std::cerr << "Unexpected error: " << e.what() << std::endl;
return 1;
}
return 0; return 0;
} }