Created
January 4, 2021 19:14
-
-
Save kjelloh/e46a2b48c740a2abf1f33f0b827e6bae to your computer and use it in GitHub Desktop.
Advent of Code 2020 day 17 part 1 and 2 :)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// main.cpp | |
// AdventOfCode201217_1 | |
// | |
// Created by Kjell-Olov Högdal on 2021-01-04. | |
// | |
#include <iostream> | |
#include <sstream> | |
#include <string> | |
#include <vector> | |
#include <array> | |
#include <unordered_set> | |
#include <numeric> | |
#include <algorithm> | |
#include <cmath> | |
using Count = std::size_t; | |
// const Count dimension_count{3}; // Part 1 3D space :) | |
const Count dimension_count{4}; // Part 2 4D space :) | |
char const* pExample = R"(.#. | |
..# | |
###)"; | |
char const* pData = R"(.#.####. | |
.#...##. | |
..###.## | |
#..#.#.# | |
#..#.... | |
#.####.. | |
##.##..# | |
#.#.#..#)"; | |
using Coordinate = int; | |
using Vector = std::array<Coordinate,dimension_count>; | |
std::string to_string(Vector const& v) { | |
std::string init; | |
bool is_first {true}; | |
auto result = std::accumulate(v.begin(), v.end(), init,[&is_first](auto& acc,auto const& coord){ | |
if (is_first) {is_first = false;} else {acc += ",";} | |
acc += std::to_string(coord); | |
return acc; | |
}); | |
return result; | |
} | |
Vector operator+(Vector const& v1,Vector const& v2) { | |
Vector result{}; | |
for (Coordinate i = 0;i<dimension_count;++i) { | |
result[i] = (v1[i]+v2[i]); | |
} | |
// std::cout << "\n{" << to_string(v1) << "} + {" << to_string(v2) << " = {" << to_string(result) << "}"; | |
return result; | |
} | |
bool operator==(Vector const& v1,Vector const& v2) { | |
std::vector<bool> bool_v; | |
std::transform(v1.begin(), v1.end(), v2.begin(), std::back_inserter(bool_v), [](auto coord1, auto coord2) { | |
return (coord1 == coord2); | |
}); | |
return std::all_of(bool_v.begin(), bool_v.end(), [](auto b) {return b;}); | |
} | |
using Vectors = std::vector<Vector>; | |
struct VectorHash { | |
std::size_t operator()(Vector const& v) const { | |
return std::hash<std::string>{}(to_string(v)); | |
} | |
}; | |
using Active = std::unordered_set<Vector,VectorHash>; | |
using Lines = std::vector<std::string>; | |
void print_active(Active const& active) { | |
Vectors vs {}; | |
std::transform(active.begin(), active.end(), std::back_inserter(vs), [](auto const& v) {return v;}); | |
std::sort(vs.begin(), vs.end(), [](auto const& v1,auto const& v2) { | |
return (v1[2] < v2[2]); // sort on z | |
}); | |
Vector last_v {vs.back()}; | |
for (auto const& v : vs) { | |
for (int i = 0;i<dimension_count;++i) { | |
if (i > 1) { | |
if (last_v[i] != v[i]) std::cout << "\ndim " << i << " = " << v[i]; | |
} | |
} | |
std::cout << "\n\t{" << to_string(v) << "}"; | |
last_v = v; | |
} | |
} | |
class Grid { | |
public: | |
explicit Grid(std::istream& in) : m_active{} { | |
std::string line; | |
Vector v {}; | |
while (std::getline(in, line)) { | |
v[0] = 0; | |
for (auto c : line) { | |
if (c == '#') m_active.insert(v); | |
++v[0]; // x coordinate | |
} | |
++v[1]; // y coordinate | |
} | |
std::cout << "\ninit"; | |
// print_active(m_active); | |
} | |
Count operator++() { | |
static Count count {0}; | |
++count; | |
std::cout << "\noperator++ iteration " << count; | |
Active next_active {}; | |
for (auto v : m_active) { | |
if (is_next_active(v)) { | |
next_active.insert(v); | |
} | |
// Take care of activating inactive cubes (those NOT in m_active) | |
for (auto delta : m_adjacent_space) { | |
Vector vn {v+delta}; | |
auto iter = m_active.find(vn); | |
if (iter == m_active.end()) { | |
// Bring inactive to life | |
if (is_next_active(vn)) { | |
next_active.insert(vn); | |
} | |
} | |
} | |
} | |
m_active = std::move(next_active); | |
// std::cout << "\niteration " << count; | |
// print_active(m_active); | |
return count; | |
} | |
Count active_count() {return m_active.size();} | |
private: | |
Vectors create_adjacent_space() { | |
Vectors result {}; | |
// Generate all vectors with coordinates -1,0,1 for all dimensions | |
// as these are the distances to adjacent cubes | |
// Use base-3 numeration | |
const Count base{3}; | |
const auto N {std::pow(base,dimension_count)}; | |
for (Count j=0;j<N;++j) { | |
Vector delta {}; | |
Count k = j; | |
for (Count i = 0; i < dimension_count;++i) { | |
auto d = (k % base)-1; // Offset to -1,0,1 | |
k = k / base; | |
delta[i] = static_cast<Coordinate>(d); | |
} | |
if ((delta == Vector{})) { | |
// std::cout << "\nskip zero delta "; | |
} | |
else { | |
// std::cout << "\n\tdelta " << "{" << to_string(delta) << "}"; | |
result.push_back(delta); | |
} | |
} | |
return result; | |
} | |
const Vectors m_adjacent_space {create_adjacent_space()}; | |
Count active_neighbours_count(Vector const& v) { | |
Count result {0}; | |
for (auto delta : m_adjacent_space) { | |
Vector vn = v + delta; | |
if (m_active.find(vn) != m_active.end()) { | |
++result; | |
} | |
} | |
// std::cout << "\nactive_neighbours_count of {" << to_string(v) << "} is " << result; | |
return result; | |
} | |
bool is_next_active(Vector const& v) { | |
bool result {false}; | |
auto anc = active_neighbours_count(v); | |
if (m_active.find(v) != m_active.end()) { | |
// v is active | |
result = (anc == 2) or (anc == 3); | |
} | |
else { | |
// v is inactive | |
result = (anc == 3); | |
} | |
/* | |
std::cout << "\nis_next_active {" << to_string(v) << "}"; | |
if (result) std::cout << " TRUE"; | |
else std::cout << " false"; | |
*/ | |
return result; | |
} | |
Active m_active; | |
}; | |
int main(int argc, const char * argv[]) { | |
// Refactored from https://github.com/craig-chasseur/aoc2020/blob/main/puzzles/day_17/part1.cc | |
// Many thanks to Craig Chasseur. | |
std::basic_istringstream<char> in {pData}; | |
Grid grid {in}; | |
for (int i = 0; i < 6; ++i) { | |
++grid; | |
} | |
std::cout << "\n\nResult = " << grid.active_count(); | |
std::cout << "\n\nBye :)"; | |
std::cout << "\n"; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment