diff --git a/src/days/15/Day15.cpp b/src/days/15/Day15.cpp index e9246ba..450e4d8 100644 --- a/src/days/15/Day15.cpp +++ b/src/days/15/Day15.cpp @@ -1,19 +1,73 @@ #include "Day15.h" Result Day15::Task1() { - Set sensors; - Set beacons; + int64 lowX = INT64_MAX, highX = INT64_MIN; + map sensorToBeaconDist; + Set sensors, beacons; + parseSystem(sensorToBeaconDist, sensors, beacons, lowX, highX); + + int64 count = 0; + int64 y = 2000000; + for (int64 x = lowX; x <= highX; x++){ + if (beacons.contains({x, y})) + continue; + for (const auto& pair : sensorToBeaconDist){ + if (ManDist({x, y}, pair.first) <= pair.second){ + count++; + break; + } + } + } - parseSystem(sensors, beacons); - return Day::Task1(); + return to_string(count); } Result Day15::Task2() { - return Day::Task2(); + int64 lowX = INT64_MAX, highX = INT64_MIN; + map sensorToBeaconDist; + Set sensors, beacons; + parseSystem(sensorToBeaconDist, sensors, beacons, lowX, highX); + + const int64 low = 0; + const int64 high = 4000000; + + for (const auto& pair : sensorToBeaconDist){ + const Point sensor = pair.first; + const auto dist = int64(pair.second); + + // Check all points touching the diamond, but not inside + for (int64 x = -dist - 1; x <= dist + 1; x++){ + int64 yUp = dist + 1 - std::abs(x); + int64 yDown = -yUp; + int64 testX = x + sensor.first; + if (testX < low || testX > high) + continue; + int64 yArr[2] {yUp, yDown}; + for (int64 &y : yArr){ + int64 testY = y + sensor.second; + Point possibleSolution = {testX, testY}; + if (testY < low || testY > high) + continue; + bool overlapped = false; + for (const auto& testPair : sensorToBeaconDist){ + if (ManDist(possibleSolution, testPair.first) <= testPair.second){ + overlapped = true; + break; + } + } + if (!overlapped){ + int64 result = testX * 4000000 + testY; + return to_string(result); + } + } + } + } + + return "Something went wrong"; } -void Day15::parseSystem(Set &sensors, Set &beacons) { +void Day15::parseSystem(map &sensorToBeaconDist, Set &sensors, Set &beacons, int64& lowX, int64& highX) { for (const string &line : input){ size_t xPos = line.find('x') + 2; size_t yPos = line.find('y') + 2; @@ -25,7 +79,17 @@ void Day15::parseSystem(Set &sensors, Set &beacons) { int64 bx = stoi(line.substr(xPos, line.find(',', xPos) - xPos)); int64 by = stoi(line.substr(yPos)); + uint64 dist = ManDist({sx, sy}, {bx, by}); + int64 outerLeft = sx - int64(dist); + int64 outerRight = sx + int64(dist); + if (outerLeft < lowX) lowX = outerLeft; + if (outerRight > highX) highX = outerRight; + sensorToBeaconDist[{sx, sy}] = dist; sensors.insert({sx, sy}); beacons.insert({bx, by}); } } + +uint64 Day15::ManDist(Day15::Point p1, Day15::Point p2) { + return std::abs(p2.first - p1.first) + std::abs(p2.second - p1.second); +} diff --git a/src/days/15/Day15.h b/src/days/15/Day15.h index bc39836..e0910df 100644 --- a/src/days/15/Day15.h +++ b/src/days/15/Day15.h @@ -4,13 +4,14 @@ class Day15 : public Day { typedef pair Point; + static uint64 ManDist(Point p1, Point p2); struct hashFunction { size_t operator()(const Point &p) const { return p.first ^ p.second; } }; typedef unordered_set Set; - void parseSystem(Set&, Set&); + void parseSystem(map&, Set&, Set&, int64&, int64&); protected: Result Task1() override;