Day 8 Question 2

This commit is contained in:
2025-12-10 03:31:32 +02:00
parent d10d3ce2fd
commit 67f590a7b0
3 changed files with 1168 additions and 0 deletions

1000
Day8/Question2/input Normal file

File diff suppressed because it is too large Load Diff

20
Day8/Question2/inputTest Normal file
View File

@@ -0,0 +1,20 @@
162,817,812
57,618,57
906,360,560
592,479,940
352,342,300
466,668,158
542,29,236
431,825,988
739,650,466
52,470,668
216,146,977
819,987,18
117,168,530
805,96,715
346,949,466
970,615,88
941,993,340
862,61,35
984,92,344
425,690,689

148
Day8/Question2/main.cpp Normal file
View File

@@ -0,0 +1,148 @@
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <string>
#include <utility>
#include <vector>
// Just for clean code sake, This is doable without structs or classes
typedef double Distance;
struct Junction;
struct Cluster {
std::vector<Junction *> members{};
};
struct Junction {
int64_t x, y, z;
Cluster *parentCluster = nullptr;
};
Distance distanceBetween(Junction first, Junction second) {
return std::sqrt(std::pow(second.x - first.x, 2) +
std::pow(second.y - first.y, 2) +
std::pow(second.z - first.z, 2));
}
int main() {
std::fstream input("input");
std::string currentLine = "";
std::vector<Junction> junctionList{};
std::list<Cluster> clusterList{};
std::multimap<Distance, std::pair<Junction *, Junction *>>
junctionDistanceMap{};
std::pair<Junction *, Junction *> *lastPair;
uint64_t junctionListSize = 0;
// I do think we could process text and do the necessary calculations for the
// solution, but once again, code should be preferably legiable
while (std::getline(input, currentLine, '\n')) {
uint16_t positionOfFirstComma, positionOfSecondComma;
positionOfFirstComma = currentLine.find(',');
positionOfSecondComma = currentLine.find(',', positionOfFirstComma + 1);
int64_t x, y, z;
x = std::stoll(currentLine.substr(0, positionOfFirstComma));
y = std::stoll(
currentLine.substr(positionOfFirstComma + 1,
positionOfSecondComma - positionOfFirstComma));
z = std::stoll(currentLine.substr(positionOfSecondComma + 1));
junctionList.push_back({x, y, z});
}
// This is O(n²), ouch. It can be estimated with T_n, So idk maybe O(T_n)
uint64_t count = 0;
junctionListSize = junctionList.size();
for (Junction &junction : junctionList) {
for (uint64_t index = ++count; index < junctionListSize; index++) {
junctionDistanceMap.insert(
{distanceBetween(junction, junctionList[index]),
{&junction, &junctionList[index]}});
}
}
// Ordered by smallest to largest key
count = junctionDistanceMap.size();
for (auto &Key : junctionDistanceMap) {
// Just need to know when we connect every junction
Junction *previousJunction = nullptr;
bool isFullyConnected = true;
for (Junction &junction : junctionList) {
if (previousJunction == nullptr) {
previousJunction = &junction;
continue;
}
if (previousJunction->parentCluster == nullptr ||
previousJunction->parentCluster != junction.parentCluster) {
isFullyConnected = false;
break;
}
}
if (count == 0 || isFullyConnected) {
break;
}
count--;
lastPair = &Key.second;
Junction *first = Key.second.first, *second = Key.second.second;
Cluster *firstCluster = first->parentCluster,
*secondCluster = second->parentCluster;
// 4 real possibilities
bool firstHasACluster = firstCluster != nullptr,
secondHasACluster = secondCluster != nullptr;
// Both have clusters, merge clusters
if (firstHasACluster && secondHasACluster) {
// Since both are already connected
if (firstCluster == secondCluster) {
continue;
}
// This bad boy merges the clusters and updates the pointers
firstCluster->members.insert(firstCluster->members.end(),
secondCluster->members.begin(),
secondCluster->members.end());
for (Junction *clusterJunction : secondCluster->members) {
clusterJunction->parentCluster = firstCluster;
}
// Temp fix
secondCluster->members.clear();
second->parentCluster = firstCluster;
continue;
}
// Both don't have clusters, pair up
if (!firstHasACluster && !secondHasACluster) {
clusterList.push_back({{first, second}});
// Directly writing, can't use the variable here
first->parentCluster = &clusterList.back();
second->parentCluster = &clusterList.back();
continue;
}
// Only first doesn't have it, append to second
if (!firstHasACluster) {
first->parentCluster = secondCluster;
secondCluster->members.push_back(first);
continue;
}
// Only second doesn't have it, append to first
if (!secondHasACluster) {
second->parentCluster = firstCluster;
firstCluster->members.push_back(second);
continue;
}
}
std::cout << lastPair->first->x * lastPair->second->x << "\n";
}