Compare commits

...

4 Commits

  1. 2
      CMakeLists.txt
  2. 65
      src/days/11/Day11.cpp
  3. 2
      src/days/11/Day11.h
  4. 100
      src/days/12/Day12.cpp
  5. 5
      src/days/12/Day12.h
  6. 5
      src/util.h

@ -12,7 +12,7 @@ file(GLOB_RECURSE SRC_FILES src/**.cpp)
add_executable(AdventOfCode2023 ${SRC_FILES})
include(FetchContent)
FetchContent_Declare(cpr GIT_REPOSITORY https://github.com/libcpr/cpr.git GIT_TAG 100cf2050be7619430a615cd0d580b33c62fde6b)
FetchContent_Declare(cpr GIT_REPOSITORY https://github.com/libcpr/cpr.git GIT_TAG 3b15fa8)
FetchContent_MakeAvailable(cpr)
target_link_libraries(AdventOfCode2023 cpr::cpr)

@ -29,38 +29,15 @@ Result Day11::Task1() {
}
}
vector<Coord> galaxies;
for (size_t y = 0; y < universe.size(); y++){
auto row = universe[y];
for (size_t x = 0; x < row.size(); x++)
if (universe[y][x])
galaxies.emplace_back(x, y);
}
uint64 sum = 0;
for (size_t i = 0; i < galaxies.size(); i++){
for (size_t j = i + 1; j < galaxies.size(); j++){
auto &[x1, y1] = galaxies[i];
auto &[x2, y2] = galaxies[j];
auto galaxies = getGalaxies(universe);
sum += std::abs(long(x2 - x1)) + std::abs(long(y2 - y1));
}
}
return to_string(sum);
return to_string(getDistanceSum(galaxies));
}
Result Day11::Task2() {
Universe universe = parseUniverse();
vector<Coord> galaxies;
for (size_t y = 0; y < universe.size(); y++){
auto row = universe[y];
for (size_t x = 0; x < row.size(); x++)
if (universe[y][x])
galaxies.emplace_back(x, y);
}
auto galaxies = getGalaxies(universe);
const size_t gapSize = 1000000;
@ -94,6 +71,23 @@ Result Day11::Task2() {
gx += gapSize - 1;
}
return to_string(getDistanceSum(galaxies));
}
Day11::Universe Day11::parseUniverse() const {
Universe universe;
for (const string &line : input){
vector<bool> row(line.size(), false);
for (size_t index : findAll(line, "#"))
row[index] = true;
universe.push_back(row);
}
return universe;
}
uint64 Day11::getDistanceSum(const vector<Coord> &galaxies) {
uint64 sum = 0;
for (size_t i = 0; i < galaxies.size(); i++){
@ -105,18 +99,15 @@ Result Day11::Task2() {
}
}
return to_string(sum);
return sum;
}
Day11::Universe Day11::parseUniverse() const {
Universe universe;
for (const string &line : input){
vector<bool> row(line.size(), false);
for (size_t index : findAll(line, "#"))
row[index] = true;
universe.push_back(row);
vector<Day11::Coord> Day11::getGalaxies(const Day11::Universe &universe) {
vector<Coord> galaxies;
for (size_t y = 0; y < universe.size(); y++){
for (size_t x = 0; x < universe[y].size(); x++)
if (universe[y][x])
galaxies.emplace_back(x, y);
}
return universe;
return galaxies;
}

@ -6,6 +6,8 @@ class Day11 : public Day {
typedef pair<size_t, size_t> Coord;
typedef vector<vector<bool>> Universe;
Universe parseUniverse() const;
static vector<Coord> getGalaxies(const Universe &universe) ;
static uint64 getDistanceSum(const vector<Coord> &galaxies) ;
protected:
Result Task1() override;

@ -1,9 +1,105 @@
#include "Day12.h"
Result Day12::Task1() {
return Day::Task1();
uint64 sum = 0;
for (const auto& [conditions, groups] : parseRecords()){
uint64 localSum = 0;
auto arrangements = allArrangements({conditions, groups});
for (const auto& arrangement : arrangements){
if (matches(conditions, arrangement))
localSum++;
}
size_t count = arrangements.size();
sum += localSum;
}
return to_string(sum);
}
Result Day12::Task2() {
return Day::Task2();
uint64 sum = 0;
size_t index = 0;
for (auto& [conditions, groups] : parseRecords()){
auto condCopy = conditions;
auto groupsCopy = groups;
for (size_t i = 0; i < 4; i++){
conditions += "?" + condCopy;
groups.insert(groups.end(), groupsCopy.begin(), groupsCopy.end());
}
for (const auto& arrangement : allArrangements({conditions, groups})){
if (matches(conditions, arrangement))
sum++;
}
cout << index++ << endl;
}
return to_string(sum);
}
vector<Day12::Record> Day12::parseRecords() const {
vector<Record> records;
for (const string &line : input){
auto both = split(line, ' ');
records.emplace_back(both[0], parseUInts(both[1]));
}
return records;
}
vector<Day12::Arrangement> Day12::allArrangements(const Day12::Record &record) {
auto &[conditions, groups] = record;
vector<Arrangement> arrangements;
if (groups.size() == 1){
size_t group = groups[0];
for (size_t i = 0; i < conditions.size() - group + 1; i++){
Arrangement a(conditions.size(), false);
for (size_t j = 0; j < group; j++)
a[i + j] = true;
arrangements.push_back(a);
}
return arrangements;
}
vector<size_t> remainingGroups(groups.size() - 1);
std::copy(++groups.begin(), groups.end(), remainingGroups.begin());
size_t neededSpace = sum(remainingGroups) + remainingGroups.size() - 1;
size_t startLimit = conditions.size() - neededSpace - 1;
for (size_t i = groups[0] - 1; i < startLimit; i++){
Arrangement base(i + 2, true);
base.back() = false;
for (size_t j = 0; j < i - groups[0] + 1; j++)
base[j] = false;
auto addedRight = allArrangements({conditions.substr(i + 2), remainingGroups});
for (auto &a : addedRight){
Arrangement combined(base);
std::copy(a.begin(), a.end(), std::back_inserter(combined));
arrangements.push_back(combined);
}
}
return arrangements;
}
bool Day12::matches(const string &conditions, const Day12::Arrangement &arrangement) {
for (size_t i = 0; i < arrangement.size(); i++){
char cond = conditions[i];
bool broken = arrangement[i];
if (cond == '.' && broken || cond == '#' && !broken)
return false;
}
return true;
}

@ -3,6 +3,11 @@
#include "../../Day.h"
class Day12 : public Day {
typedef pair<string, vector<uint64>> Record;
typedef vector<bool> Arrangement;
vector<Record> parseRecords() const;
static vector<Arrangement> allArrangements(const Record &record);
static bool matches(const string& conditions, const Arrangement& arrangement);
protected:
Result Task1() override;

@ -32,3 +32,8 @@ bool isDigit(char c);
vector<uint64> parseUInts(const string &data);
vector<int64> parseInts(const string &data);
template<typename T>
T sum(const vector<T>& values){
return std::reduce(values.begin(), values.end(), T(), [](T a, T b){return a + b;});
}
Loading…
Cancel
Save