Obsidian Glow Theme
A polished obsidian-dark theme with vibrant blue highlights.
Huffman
node.hh
#pragma once
#include <memory>
#include <optional>
struct Node
{
Node() = default;
Node(float weight_, std::optional<char> symbol_);
Node(float weight_, std::unique_ptr<Node> left_, std::unique_ptr<Node> right_);
float weight;
std::optional<char> symbol;
std::unique_ptr<Node> left;
std::unique_ptr<Node> right;
};
node.cc
#include "node.hh"
Node::Node(float weight_, std::optional<char> symbol_)
: weight(weight_), symbol(symbol_), left(nullptr), right(nullptr)
{}
Node::Node(float weight_, std::unique_ptr<Node> left_, std::unique_ptr<Node> right_)
: weight(weight_), symbol(std::nullopt), left(std::move(left_)), right(std::move(right_))
{}
priority_queue.hh
#pragma once
#include <algorithm>
#include <numeric>
#include <stdexcept>
#include <utility>
#include <vector>
#include "node.hh"
class PriorityQueue
{
public:
explicit PriorityQueue() = default;
size_t size() const;
void push(std::unique_ptr<Node> node);
std::unique_ptr<Node> pop();
private:
std::vector<std::unique_ptr<Node>> m_heap;
};
priority_queue.cc
#include "priority_queue.hh"
#include <algorithm>
#include <memory>
#include <ranges>
#include <vector>
size_t PriorityQueue::size() const { return m_heap.size(); }
void PriorityQueue::push(std::unique_ptr<Node> node)
{
m_heap.push_back(std::move(node));
}
std::unique_ptr<Node> PriorityQueue::pop()
{
if (m_heap.empty())
throw std::runtime_error("error no node to pop");
auto it = std::ranges::min_element(m_heap, [](https://github.com/arthurnrj/const auto& a, const auto& b) {
return a->weight < b->weight;
});
auto node = std::move(*it);
m_heap.erase(it);
return node;
}
huffman.hh
#pragma once
#include <memory>
#include <string>
#include <unordered_map>
#include "node.hh"
#include "priority_queue.hh"
std::unique_ptr<Node> buildHuffmanTree(const std::string& message);
std::unordered_map<char, std::string> buildCodeTable(const std::unique_ptr<Node>& node);
huffman.cc
#include "huffman.hh"
#include <map>
std::unique_ptr<Node> buildHuffmanTree(const std::string& message)
{
if (message.empty())
return nullptr;
auto freq = std::map<char, int>{};
for (char c : message)
freq[c]++;
auto pq = PriorityQueue{};
for (auto& [ch, count] : freq)
pq.push(std::make_unique<Node>(static_cast<float>(count), ch));
while (pq.size() > 1)
{
auto left = pq.pop();
auto right = pq.pop();
auto weight = left->weight + right->weight;
pq.push(std::make_unique<Node>(weight, std::move(left), std::move(right)));
}
return pq.pop();
}
static void buildCodeTableHelper(const std::unique_ptr<Node>& node,
const std::string& prefix,
std::unordered_map<char, std::string>& table)
{
if (!node)
return;
if (node->symbol.has_value())
{
table[node->symbol.value()] = prefix.empty() ? "0" : prefix;
return;
}
buildCodeTableHelper(node->left, prefix + "0", table);
buildCodeTableHelper(node->right, prefix + "1", table);
}
std::unordered_map<char, std::string> buildCodeTable(const std::unique_ptr<Node>& node)
{
auto table = std::unordered_map<char, std::string>{};
buildCodeTableHelper(node, "", table);
return table;
}
encode_decode.hh
#pragma once
#include <string>
#include <unordered_map>
std::string huffmanEncode(const std::string& message,
std::unordered_map<char, std::string> table);
std::string huffmanDecode(const std::string& compressed_message,
std::unordered_map<char, std::string> table);
encode_decode.cc
#include "encode_decode.hh"
std::string huffmanEncode(const std::string& message,
std::unordered_map<char, std::string> table)
{
auto encoded = std::string{};
for (unsigned char c : message)
encoded += table[c];
return encoded;
}
std::string huffmanDecode(const std::string& compressed_message,
std::unordered_map<char, std::string> table)
{
auto rev_table = std::unordered_map<std::string, char>{};
for (auto i = table.begin(); i != table.end(); ++i)
rev_table[i->second] = i->first;
std::string message = "";
std::string cur = "";
for (const char c : compressed_message)
{
cur += c;
if (rev_table.contains(cur))
{
message += rev_table.at(cur);
cur = "";
}
}
return message;
}
Int Container
int_container.hh
#pragma once
#include <iostream>
#include <memory>
#include <optional>
class MyIntContainer
{
public:
MyIntContainer(size_t size);
void print() const;
size_t get_len() const;
bool add(int elem);
std::optional<int> pop();
std::optional<int> get(size_t position) const;
std::optional<size_t> find(int elem) const;
void sort();
bool is_sorted() const;
private:
size_t current_size_;
size_t max_size_;
std::unique_ptr<int[]> elems_;
};
int_container.cc
#include "int_container.hh"
MyIntContainer::MyIntContainer(size_t size)
{
current_size_ = 0;
max_size_ = size;
elems_ = std::make_unique<int[]>(size);
}
void MyIntContainer::print() const
{
for (size_t i = 0; i < current_size_; i++)
{
std::cout << elems_[i];
if (i < current_size_ - 1)
std::cout << " | ";
}
std::cout << '\n';
}
size_t MyIntContainer::get_len() const { return current_size_; }
bool MyIntContainer::add(int elem)
{
if (current_size_ >= max_size_)
return false;
elems_[current_size_] = elem;
current_size_++;
return true;
}
std::optional<int> MyIntContainer::pop()
{
if (current_size_ == 0)
return std::nullopt;
current_size_--;
return elems_[current_size_];
}
std::optional<int> MyIntContainer::get(size_t position) const
{
if (position >= current_size_)
return std::nullopt;
return elems_[position];
}
std::optional<size_t> MyIntContainer::find(int elem) const
{
for (size_t i = 0; i < current_size_; ++i)
{
if (elems_[i] == elem)
return i;
}
return std::nullopt;
}
void MyIntContainer::sort()
{
if (current_size_ <= 1)
return;
for (size_t i = 0; i < current_size_ - 1; i++)
for (size_t j = 0; j < current_size_ - i - 1; j++)
if (elems_[j] > elems_[j + 1])
{
int temp = elems_[j];
elems_[j] = elems_[j + 1];
elems_[j + 1] = temp;
}
}
bool MyIntContainer::is_sorted() const
{
if (current_size_ <= 1)
return true;
for (size_t i = 0; i < current_size_ - 1; i++)
if (elems_[i] > elems_[i + 1])
return false;
return true;
}
Is Prime
is_prime.hh
#pragma once
#include "is_prime.hxx"
is_prime.hxx
#pragma once
constexpr bool is_prime(unsigned n)
{
if (n < 2)
return false;
for (unsigned i = 2; i * i <= n; i++)
if (n % i == 0)
return false;
return true;
}
Lookup Table
lookup_table.hh
#pragma once
#include <optional>
#include <unordered_map>
class LookupTable
{
public:
std::optional<long> get(int x);
void set(int x, long value);
private:
std::unordered_map<int, long> table_;
};
lookup_table.cc
#include "lookup_table.hh"
std::optional<long> LookupTable::get(int x)
{
auto it = table_.find(x);
if (it != table_.end())
return it->second;
return std::nullopt;
}
void LookupTable::set(int x, long value) { table_[x] = value; }
fibo.hh
#pragma once
#include "lookup_table.hh"
class Fibo
{
private:
LookupTable lookup_table_;
public:
long operator()(int x);
};
fibo.cc
#include "fibo.hh"
long Fibo::operator()(int x)
{
if (x <= 1)
return x;
std::optional<long> opt_lookup_table = lookup_table_.get(x);
if (opt_lookup_table)
return *opt_lookup_table;
auto res = (*this)(x - 1) + (*this)(x - 2);
lookup_table_.set(x, res);
return res;
}
Merge Sort
merge_sort.hh
#pragma once
#include <algorithm>
#include <vector>
#define while forbidden_use_of_while
#define for forbidden_use_of_for
#define goto forbidden_use_of_goto
#define sort forbidden_use_of_sort
#define partial_sort forbidden_use_of_sort
#define stable_sort forbidden_use_of_sort
#define sort_heap forbidden_use_of_sort
using iterator_type = std::vector<int>::iterator;
void merge_sort(iterator_type begin, iterator_type end);
merge_sort.cc
#include "merge_sort.hh"
#include <algorithm>
void merge_sort(iterator_type begin, iterator_type end)
{
auto stop = end - begin;
if (stop <= 1)
return;
auto mid = begin + (end - begin) / 2;
merge_sort(begin, mid);
merge_sort(mid, end);
std::inplace_merge(begin, mid, end);
}
My NFTs
nft.hh
#pragma once
#include <memory>
#include <string>
using NFT = std::unique_ptr<std::string>;
NFT create_empty_nft();
NFT create_nft(const std::string& name);
#include "nft.hxx"
nft.hxx
#pragma once
#include <memory>
#include "nft.hh"
inline NFT create_empty_nft() { return nullptr; }
inline NFT create_nft(const std::string& name)
{
return std::make_unique<std::string>(name);
}
person.hh
#pragma once
#include <ostream>
#include <vector>
#include "nft.hh"
class Person
{
public:
Person(const std::string& name, uint money);
std::vector<std::string> enumerate_nfts() const;
void add_nft(NFT nft);
NFT remove_nft(const std::string& name);
void add_money(uint money);
bool remove_money(uint money);
uint get_money() const;
const std::string& get_name() const;
private:
std::string name_;
uint money_;
std::vector<NFT> nfts_;
};
std::ostream& operator<<(std::ostream& os, const Person& p);
person.cc
#include "person.hh"
#include <algorithm>
#include <utility>
Person::Person(const std::string& name, uint money) : name_(name), money_(money) {}
std::vector<std::string> Person::enumerate_nfts() const
{
std::vector<std::string> names;
for (const auto& nft : nfts_)
names.push_back(*nft);
return names;
}
void Person::add_nft(NFT nft) { nfts_.push_back(std::move(nft)); }
NFT Person::remove_nft(const std::string& name)
{
for (auto i = nfts_.begin(); i != nfts_.end(); i++)
{
if (**i == name)
{
NFT nft = std::move(*i);
nfts_.erase(i);
return nft;
}
}
return create_empty_nft();
}
void Person::add_money(uint money) { money_ += money; }
bool Person::remove_money(uint money)
{
if (money_ < money)
return false;
money_ -= money;
return true;
}
uint Person::get_money() const { return money_; }
const std::string& Person::get_name() const { return name_; }
std::ostream& operator<<(std::ostream& os, const Person& p)
{
os << "Name: " << p.get_name() << "\n"
<< "Money: " << p.get_money() << "\n"
<< "NFTs:";
for (const auto& name : p.enumerate_nfts())
os << ' ' << name;
os << "\n";
return os;
}
auction.hh
#pragma once
#include "nft.hh"
#include "person.hh"
class Auction
{
public:
Auction(Person& organizer, NFT nft, uint initial_bid);
~Auction();
Auction(const Auction&&) = delete;
Auction(const Auction&) = delete;
Auction& operator=(const Auction&&) = delete;
Auction& operator=(const Auction&) = delete;
bool bid(Person& person, uint money);
const std::string& get_nft_name() const;
uint get_highest_bid() const;
private:
Person& organizer_;
NFT nft_;
Person* highest_bidder_;
uint highest_bid_;
};
auction.cc
#include "auction.hh"
#include <utility>
Auction::Auction(Person& organizer, NFT nft, uint initial_bid)
: organizer_(organizer), nft_(std::move(nft)),
highest_bidder_(nullptr), highest_bid_(initial_bid)
{
if (!nft_)
throw "empty NFT";
}
Auction::~Auction()
{
if (highest_bidder_)
{
highest_bidder_->add_nft(std::move(nft_));
organizer_.add_money(highest_bid_);
}
else
organizer_.add_nft(std::move(nft_));
}
bool Auction::bid(Person& person, uint money)
{
if (money <= highest_bid_)
return false;
if (!person.remove_money(money))
return false;
if (highest_bidder_)
highest_bidder_->add_money(highest_bid_);
highest_bidder_ = &person;
highest_bid_ = money;
return true;
}
const std::string& Auction::get_nft_name() const { return *nft_; }
uint Auction::get_highest_bid() const { return highest_bid_; }
Parse CSV
parse_csv.hh
#pragma once
#include <string>
#include <vector>
std::vector<std::vector<std::string>> parse_csv(const std::string& file_name);
parse_csv.cc
#include "parse_csv.hh"
#include <fstream>
#include <sstream>
std::vector<std::vector<std::string>> parse_csv(const std::string& file_name)
{
std::ifstream file(file_name);
if (!file.is_open())
throw std::ios_base::failure("Error opening file");
std::vector<std::vector<std::string>> result;
std::string line;
std::size_t expected_cols = 0;
while (std::getline(file, line))
{
std::vector<std::string> row;
std::istringstream ss(line);
std::string field;
while (std::getline(ss, field, ','))
row.push_back(field);
if (!line.empty() && line.back() == ',')
row.push_back("");
if (result.empty())
expected_cols = row.size();
else if (row.size() != expected_cols)
throw std::ios_base::failure("Non consistent number of columns at line "
+ std::to_string(result.size() + 1));
result.push_back(row);
}
return result;
}