~cdv/aoc-2018-cc

fef146d81e280342fed32f246aec8cbffd1e12cb — Christopher Vittal 1 year, 3 months ago 5c2978f master
Solve day 9
2 files changed, 67 insertions(+), 1 deletions(-)

A data/day09
M day09.cc
A data/day09 => data/day09 +1 -0
@@ 0,0 1,1 @@
424 players; last marble is worth 71144 points

M day09.cc => day09.cc +66 -1
@@ 1,7 1,72 @@
#include "advent.hh"

#include <algorithm>
#include <list>
#include <vector>

template <typename T>
class CircleIter {
  std::list<T> &m;
  typename std::list<T>::iterator curr;

  void next() {
    if (++curr == m.end())
      curr = m.begin();
  }
  void prev() {
    if (curr == m.begin())
      curr = m.end();
    --curr;
  }

 public:
  explicit CircleIter(std::list<T> &_m): m{_m}, curr{m.begin()} {}
  T operator *() {
    return *curr;
  }
  void next(int n) {
    for (auto i = 0; i < n; ++i)
      next();
  }
  void prev(int n) {
    for (auto i = 0; i < n; ++i)
      prev();
  }
  void erase_current() {
    curr = m.erase(curr);
  }
  void insert(T val) {
    curr = m.insert(curr, val);
  }
};

template <>
template <bool p2>
void Day<9>::solve(std::istream &is, std::ostream &os) {}
void Day<9>::solve(std::istream &is, std::ostream &os) {
  std::string input;
  int players, marbles;
  std::getline(is, input);
  std::sscanf(input.c_str(), "%d players; last marble is worth %d points", &players, &marbles);
  if constexpr(p2) {
    marbles *= 100;
  }

  std::list<int> m;
  m.push_back(0);

  std::vector<uint64_t> p (players);
  CircleIter<int> it{m};
  for (int i = 1; i < marbles; ++i) {
    if (i % 23 == 0) {
      it.prev(7);
      p[i % players] += i + *it;
      it.erase_current();
    } else {
      it.next(2);
      it.insert(i);
    }
  }
  os << *std::max_element(p.begin(), p.end());
}
template void Day<9>::solve<true>(std::istream& is, std::ostream& os);
template void Day<9>::solve<false>(std::istream& is, std::ostream& os);