Add solution for 2016 Day 21

This commit is contained in:
Thraix committed 2026-09-03 22:09:48 +02:00
1 parent 78cb890ed7
commit c62c9dc3de
4 files changed
+569 -8

No files matched your search

+354
View File
@@ -0,0 +1,354 @@
#pragma once
#include <ostream>
#include <string>
#include <vector>
template <typename T>
struct CyclicVector
{
std::vector<T> vector;
size_t offset{0};
CyclicVector(const std::initializer_list<T>& vector)
: vector{vector}
{
}
CyclicVector(const std::vector<T>& vector)
: vector{vector}
{
}
template <typename U = T, typename = std::enable_if_t<std::is_same_v<U, char>>>
CyclicVector(const std::string& str)
: vector{str.begin(), str.end()}
{
}
template <std::size_t N, typename U = T, typename = std::enable_if_t<std::is_same_v<U, char>>>
CyclicVector(const char (&str)[N])
{
vector.resize(N - 1); // don't include \0 character
for (size_t i = 0; i < N - 1; i++)
{
vector[i] = str[i];
}
}
void Rotate(int i)
{
if (i < 0)
RotateLeft(-i);
else
RotateRight(i);
}
void RotateRight(int i)
{
offset = (offset + vector.size() - (i % vector.size())) % vector.size();
}
void RotateLeft(size_t i)
{
offset = (offset + i) % vector.size();
}
T& operator[](size_t i)
{
return vector[(i + offset) % vector.size()];
}
const T& operator[](size_t i) const
{
return vector[(i + offset) % vector.size()];
}
size_t size() const
{
return vector.size();
}
bool empty() const
{
return vector.empty();
}
size_t Find(const T& t) const
{
return std::find(begin(), end(), t).GetPos();
}
struct iterator;
struct const_iterator;
iterator begin()
{
return iterator{*this, 0};
}
iterator end()
{
return iterator{*this, vector.size()};
}
const_iterator begin() const
{
return const_iterator{*this, 0};
}
const_iterator end() const
{
return const_iterator{*this, vector.size()};
}
const_iterator cbegin() const
{
return const_iterator{*this, 0};
}
const_iterator cend() const
{
return const_iterator{*this, vector.size()};
}
friend std::ostream& operator<<(std::ostream& os, const CyclicVector& vector)
{
os << "[";
if (!vector.empty())
os << vector[0];
for (auto it = vector.cbegin() + 1; it != vector.cend(); it++)
{
os << ", " << *it;
}
os << "]";
return os;
}
class iterator
{
private:
CyclicVector<T>& data;
size_t pos;
public:
using iterator_category = std::random_access_iterator_tag;
using value_type = T;
using difference_type = int;
using pointer = T*;
using reference = T&;
iterator(CyclicVector<T>& data, size_t pos)
: data{data},
pos{pos}
{
}
size_t GetPos() const
{
return pos;
}
reference operator*() const
{
return data[pos];
}
pointer operator->() const
{
return &data[pos];
}
iterator& operator++()
{
++pos;
return *this;
}
iterator operator++(int)
{
iterator ret = *this;
++(*this);
return ret;
}
iterator& operator--()
{
--pos;
return *this;
}
iterator operator--(int)
{
iterator ret = *this;
--(*this);
return ret;
}
iterator& operator+=(size_t advance)
{
if (std::numeric_limits<size_t>::max() - pos < advance)
{
pos = data.size();
}
else
{
pos += advance;
if (pos >= data.size())
pos = data.size();
}
return *this;
}
iterator& operator-=(size_t advance)
{
if (advance > pos)
{
pos = data.size();
}
else
{
pos -= advance;
}
return *this;
}
iterator operator+(size_t advance) const
{
iterator ret = *this;
ret += advance;
return ret;
}
iterator operator-(size_t advance) const
{
iterator ret = *this;
ret -= advance;
return ret;
}
bool operator==(const iterator& other) const
{
return pos == other.pos;
}
bool operator!=(const iterator& other) const
{
return !(*this == other);
}
};
class const_iterator
{
private:
const CyclicVector<T>& data;
size_t pos;
public:
using iterator_category = std::random_access_iterator_tag;
using value_type = T;
using difference_type = int;
using pointer = const T*;
using reference = const T&;
const_iterator(const CyclicVector<T>& data, size_t pos)
: data{data},
pos{pos}
{
}
size_t GetPos() const
{
return pos;
}
reference operator*() const
{
return data[pos];
}
pointer operator->() const
{
return &data[pos];
}
const_iterator& operator++()
{
++pos;
return *this;
}
const_iterator operator++(int)
{
const_iterator ret = *this;
++(*this);
return ret;
}
const_iterator& operator--()
{
--pos;
return *this;
}
const_iterator operator--(int)
{
const_iterator ret = *this;
--(*this);
return ret;
}
const_iterator& operator+=(size_t advance)
{
if (std::numeric_limits<size_t>::max() - pos < advance)
{
pos = data.size();
}
else
{
pos += advance;
if (pos >= data.size())
pos = data.size();
}
return *this;
}
const_iterator& operator-=(size_t advance)
{
if (advance > pos)
{
pos = data.size();
}
else
{
pos -= advance;
}
return *this;
}
const_iterator operator+(size_t advance) const
{
const_iterator ret = *this;
ret += advance;
return ret;
}
const_iterator operator-(size_t advance) const
{
const_iterator ret = *this;
ret -= advance;
return ret;
}
bool operator==(const const_iterator& other) const
{
return pos == other.pos;
}
bool operator!=(const const_iterator& other) const
{
return !(*this == other);
}
};
};