Compare commits

...

4 Commits

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

@ -12,7 +12,7 @@ file(GLOB_RECURSE SRC_FILES src/**.cpp)
add_executable(AdventOfCode2023 ${SRC_FILES}) add_executable(AdventOfCode2023 ${SRC_FILES})
include(FetchContent) 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) FetchContent_MakeAvailable(cpr)
target_link_libraries(AdventOfCode2023 cpr::cpr) target_link_libraries(AdventOfCode2023 cpr::cpr)

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

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

@ -1,9 +1,105 @@
#include "Day12.h" #include "Day12.h"
Result Day12::Task1() { 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() { 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" #include "../../Day.h"
class Day12 : public Day { 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: protected:
Result Task1() override; Result Task1() override;

@ -31,4 +31,9 @@ bool isDigit(char c, uint8_t &result);
bool isDigit(char c); bool isDigit(char c);
vector<uint64> parseUInts(const string &data); vector<uint64> parseUInts(const string &data);
vector<int64> parseInts(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