Add day 8 implementation with input parsing and distance calculations
- Created CMakeLists.txt for day 8 and added it to the main CMakeLists.txt. - Implemented main.cpp for day 8, including functions for parsing input, calculating distances, and processing point combinations. - Added test and puzzle input files for day 8.
This commit is contained in:
parent
6e70ea4a45
commit
9a3e228f00
5 changed files with 1181 additions and 0 deletions
|
|
@ -41,5 +41,6 @@ add_subdirectory(day4)
|
||||||
add_subdirectory(day5)
|
add_subdirectory(day5)
|
||||||
add_subdirectory(day6)
|
add_subdirectory(day6)
|
||||||
add_subdirectory(day7)
|
add_subdirectory(day7)
|
||||||
|
add_subdirectory(day8)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
2
day8/CMakeLists.txt
Normal file
2
day8/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
# Use top-level helper to add the target and copy input files
|
||||||
|
aoc_add_day(day8 "${CMAKE_CURRENT_SOURCE_DIR}" main.cpp)
|
||||||
158
day8/main.cpp
Normal file
158
day8/main.cpp
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <expected>
|
||||||
|
#include <format>
|
||||||
|
#include <fstream>
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <print>
|
||||||
|
#include <ranges>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using Point = std::tuple<int, int, int>;
|
||||||
|
|
||||||
|
static auto getDistance(const Point &a, const Point &b) -> double {
|
||||||
|
return sqrt(pow(std::get<0>(a) - std::get<0>(b), 2) + pow(std::get<1>(a) - std::get<1>(b), 2) +
|
||||||
|
pow(std::get<2>(a) - std::get<2>(b), 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto parseInput(const std::string &filename) -> std::expected<std::vector<Point>, std::string> {
|
||||||
|
std::ifstream inputF{filename};
|
||||||
|
|
||||||
|
if (!inputF) {
|
||||||
|
return std::unexpected{"Some file open error."};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Point> pointVec{};
|
||||||
|
|
||||||
|
std::string puzzleLine;
|
||||||
|
while (std::getline(inputF, puzzleLine)) {
|
||||||
|
if (!puzzleLine.empty()) {
|
||||||
|
auto subParts = std::ranges::to<std::vector<std::string>>(std::views::split(puzzleLine, ','));
|
||||||
|
pointVec.emplace_back(std::stoi(subParts[0]), std::stoi(subParts[1]), std::stoi(subParts[2]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// std::println("pointList: {}", pointVec);
|
||||||
|
return pointVec;
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto getCombinations(const std::vector<Point> &pointVec) -> std::vector<std::pair<Point, Point>> {
|
||||||
|
std::vector<std::pair<Point, Point>> result;
|
||||||
|
|
||||||
|
result.reserve(pointVec.size() * pointVec.size());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < pointVec.size(); ++i) {
|
||||||
|
for (size_t j = i + 1; j < pointVec.size(); ++j) {
|
||||||
|
result.emplace_back(pointVec[i], pointVec[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::move(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto getDistances(const std::vector<Point> &pointVec) -> auto {
|
||||||
|
auto comparisonLamb = [](const std::pair<Point, Point> &pair1, const std::pair<Point, Point> &pair2) -> bool {
|
||||||
|
return getDistance(pair1.first, pair1.second) < getDistance(pair2.first, pair2.second);
|
||||||
|
};
|
||||||
|
std::map<std::pair<Point, Point>, double, decltype(comparisonLamb)> sortedMap(comparisonLamb);
|
||||||
|
|
||||||
|
auto combinations = getCombinations(pointVec);
|
||||||
|
for (const auto &combination : combinations) {
|
||||||
|
|
||||||
|
// std::println("Combinations: {}:{}", combination.first, combination.second);
|
||||||
|
sortedMap[combination] = getDistance(combination.first, combination.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sortedMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto doTheThing(const std::vector<Point> &pointVec, int numberToTake) -> auto {
|
||||||
|
auto distanceMap = getDistances(pointVec);
|
||||||
|
std::map<Point, int> pointToCircuitMap{};
|
||||||
|
std::unordered_map<int, std::vector<Point>> circuitMap;
|
||||||
|
int currentCircuit = 0;
|
||||||
|
for (const auto &[combination, distance] : distanceMap | std::views::take(numberToTake)) {
|
||||||
|
const auto &[left, right] = combination;
|
||||||
|
// std::println("DistanceMap: {}:{} = {}", left, right, distance);
|
||||||
|
|
||||||
|
if (pointToCircuitMap.contains(left) && pointToCircuitMap.contains(right)) {
|
||||||
|
int leftCircuit = pointToCircuitMap[left];
|
||||||
|
int rightCircuit = pointToCircuitMap[right];
|
||||||
|
// std::println("Left circuit: {}. Right circuit: {}", leftCircuit, rightCircuit);
|
||||||
|
if (leftCircuit != rightCircuit) {
|
||||||
|
// std::println("Fuck: {} to {}", left, right);
|
||||||
|
|
||||||
|
for (const auto &rightCircuitPoint : circuitMap[rightCircuit]) {
|
||||||
|
pointToCircuitMap[rightCircuitPoint] = leftCircuit;
|
||||||
|
}
|
||||||
|
circuitMap[leftCircuit].append_range(circuitMap[rightCircuit]);
|
||||||
|
circuitMap.erase(rightCircuit);
|
||||||
|
}
|
||||||
|
} else if (pointToCircuitMap.contains(left)) {
|
||||||
|
int leftCircuit = pointToCircuitMap[left];
|
||||||
|
// std::println("Only left exists: {} to {}", left, right);
|
||||||
|
pointToCircuitMap[right] = pointToCircuitMap[left];
|
||||||
|
|
||||||
|
circuitMap[leftCircuit].push_back(right);
|
||||||
|
} else if (pointToCircuitMap.contains(right)) {
|
||||||
|
int rightCircuit = pointToCircuitMap[right];
|
||||||
|
// std::println("Only right exists: {} to {}", left, right);
|
||||||
|
pointToCircuitMap[left] = pointToCircuitMap[right];
|
||||||
|
|
||||||
|
circuitMap[rightCircuit].push_back(left);
|
||||||
|
} else {
|
||||||
|
currentCircuit++;
|
||||||
|
pointToCircuitMap[left] = currentCircuit;
|
||||||
|
pointToCircuitMap[right] = currentCircuit;
|
||||||
|
|
||||||
|
circuitMap[currentCircuit].push_back(left);
|
||||||
|
circuitMap[currentCircuit].push_back(right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// std::println("pointToCircuitMap: {}", pointToCircuitMap);
|
||||||
|
|
||||||
|
std::println("circuitMap");
|
||||||
|
for (const auto &[circuit, pointsInCircuit] : circuitMap) {
|
||||||
|
|
||||||
|
std::println("{} : {}", circuit, pointsInCircuit);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto sizesOfLists = circuitMap | std::views::transform([](const auto &kvp) -> int { return kvp.second.size(); }) |
|
||||||
|
std::ranges::to<std::vector<int>>();
|
||||||
|
std::ranges::sort(sizesOfLists, std::greater{});
|
||||||
|
auto threeLargest = std::ranges::fold_left(sizesOfLists | std::views::take(3), 1, std::multiplies{});
|
||||||
|
|
||||||
|
// std::println("{}", threeLargest);
|
||||||
|
return threeLargest;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto main() -> int {
|
||||||
|
auto testCase = parseInput("test_input");
|
||||||
|
if (testCase) {
|
||||||
|
|
||||||
|
auto testResult = doTheThing(*testCase, 10);
|
||||||
|
std::println("P1 Testcase result: {}", testResult);
|
||||||
|
|
||||||
|
// auto testResultP2 = treePartTwo(*testCase);
|
||||||
|
// std::println("P2 Testcase result: {}", testResultP2);
|
||||||
|
} else {
|
||||||
|
std::print("{}\n", testCase.error());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto realPuzzle = parseInput("puzzle_input");
|
||||||
|
if (realPuzzle) {
|
||||||
|
auto realResult = doTheThing(*realPuzzle, 1000);
|
||||||
|
std::println("P1 Real result: {}", realResult);
|
||||||
|
|
||||||
|
// auto realResultP2 = treePartTwo(*realPuzzle);
|
||||||
|
// std::println("P1 Real result: {}", realResultP2);
|
||||||
|
} else {
|
||||||
|
std::print("{}\n", realPuzzle.error());
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
1000
day8/puzzle_input
Normal file
1000
day8/puzzle_input
Normal file
File diff suppressed because it is too large
Load diff
20
day8/test_input
Normal file
20
day8/test_input
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
|
||||||
Loading…
Add table
Add a link
Reference in a new issue