Day 8 Question 2
This commit is contained in:
1000
Day8/Question2/input
Normal file
1000
Day8/Question2/input
Normal file
File diff suppressed because it is too large
Load Diff
20
Day8/Question2/inputTest
Normal file
20
Day8/Question2/inputTest
Normal 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
148
Day8/Question2/main.cpp
Normal 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";
|
||||
}
|
||||
Reference in New Issue
Block a user