mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
Implement day 03 part 1.
This commit is contained in:
@@ -5,7 +5,7 @@ project(aoc2019)
|
||||
find_package(GTest REQUIRED)
|
||||
|
||||
file(GLOB DAYS_FILES src/day*.cpp)
|
||||
add_library(AoCSolutions src/implementations.cpp "${DAYS_FILES}")
|
||||
add_library(AoCSolutions src/implementations.cpp "${DAYS_FILES}" src/point.hpp src/utils.cpp src/utils.hpp)
|
||||
target_compile_features(AoCSolutions PUBLIC cxx_std_17)
|
||||
|
||||
add_executable(runner src/runner.cpp)
|
||||
|
||||
@@ -1,10 +1,69 @@
|
||||
#include <cassert>
|
||||
#include <charconv>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <unordered_set>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "days.hpp"
|
||||
#include "point.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
namespace {
|
||||
typedef aoc2019::Point<int, 2> point_t;
|
||||
|
||||
const std::unordered_map<char, point_t> DIRECTION_MAP = {
|
||||
{'U', {0, -1}},
|
||||
{'D', {0, 1}},
|
||||
{'L', {-1, 0}},
|
||||
{'R', {1, 0}},
|
||||
};
|
||||
|
||||
std::unordered_set<point_t> get_points(std::string_view line) {
|
||||
std::unordered_set<point_t> points{};
|
||||
point_t pos = {};
|
||||
|
||||
for (auto entry = aoc2019::strtok(line); !line.empty() || !entry.empty(); entry = aoc2019::strtok(line)) {
|
||||
const auto dir = DIRECTION_MAP.at(entry[0]);
|
||||
std::size_t amount = 0;
|
||||
std::from_chars(entry.data() + 1, entry.data() + entry.size(), amount);
|
||||
assert(amount > 0 && "Must have some valid direction");
|
||||
|
||||
for (std::size_t i = 0; i < amount; ++i) {
|
||||
pos += dir;
|
||||
points.insert(pos);
|
||||
}
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
std::pair<std::unordered_set<point_t>, std::unordered_set<point_t>> read_input(std::istream& input) {
|
||||
std::string buffer;
|
||||
std::getline(input, buffer);
|
||||
auto a = get_points(buffer);
|
||||
std::getline(input, buffer);
|
||||
auto b = get_points(buffer);
|
||||
|
||||
return { std::move(a), std::move(b) };
|
||||
}
|
||||
}
|
||||
|
||||
void aoc2019::day03_part1(std::istream &input, std::ostream &output) {
|
||||
output << "Not implemented\n";
|
||||
auto [a, b] = read_input(input);
|
||||
|
||||
int best = std::numeric_limits<int>::max();
|
||||
|
||||
for (const auto& point : a) {
|
||||
if (b.count(point) && point.l1() < best) {
|
||||
best = point.l1();
|
||||
}
|
||||
}
|
||||
|
||||
output << best << std::endl;
|
||||
}
|
||||
|
||||
void aoc2019::day03_part2(std::istream &input, std::ostream &output) {
|
||||
output << "Not implemented\n";
|
||||
output << "Not implemented\n";
|
||||
}
|
||||
|
||||
62
2019/src/point.hpp
Normal file
62
2019/src/point.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstdlib>
|
||||
#include "utils.hpp"
|
||||
|
||||
namespace aoc2019 {
|
||||
template<class T, std::size_t L>
|
||||
class Point : public std::array<T, L> {
|
||||
public:
|
||||
constexpr Point& operator +=(Point other) {
|
||||
for (std::size_t i = 0; i < L; ++i) {
|
||||
(*this)[i] += other[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Point operator+(Point other) const {
|
||||
auto result = *this;
|
||||
result += other;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
constexpr Point& operator -=(Point other) {
|
||||
for (std::size_t i = 0; i < L; ++i) {
|
||||
(*this)[i] -= other[i];
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Point operator-(Point other) const {
|
||||
auto result = *this;
|
||||
result -= other;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
constexpr T l1() const {
|
||||
T result = 0;
|
||||
for (auto e : *this) {
|
||||
result += std::abs(e);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace std {
|
||||
// Make point usable with unordered collections.
|
||||
template<class T, std::size_t L> struct hash<aoc2019::Point<T, L>> {
|
||||
size_t operator()(const aoc2019::Point<T, L> &o) const {
|
||||
size_t seed = 0;
|
||||
for (auto i : o) {
|
||||
aoc2019::combine_hash(seed, i);
|
||||
}
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
}
|
||||
12
2019/src/utils.cpp
Normal file
12
2019/src/utils.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "utils.hpp"
|
||||
|
||||
std::string_view aoc2019::strtok(std::string_view &str, char token) {
|
||||
auto next_delim = str.find(token);
|
||||
auto next = str.substr(0, next_delim);
|
||||
if (next_delim == std::string_view::npos) {
|
||||
str = {};
|
||||
} else {
|
||||
str = str.substr(next_delim + 1);
|
||||
}
|
||||
return next;
|
||||
}
|
||||
16
2019/src/utils.hpp
Normal file
16
2019/src/utils.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <string_view>
|
||||
|
||||
namespace aoc2019 {
|
||||
|
||||
template<typename T>
|
||||
void combine_hash(std::size_t& seed, const T& o) {
|
||||
// Algorithm taken from boost::combine_hash.
|
||||
std::hash<T> hash{};
|
||||
seed ^= hash(o) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
}
|
||||
|
||||
std::string_view strtok(std::string_view &str, char token = ',');
|
||||
}
|
||||
2
2019/tests/samples/03-1-1.in
Normal file
2
2019/tests/samples/03-1-1.in
Normal file
@@ -0,0 +1,2 @@
|
||||
R75,D30,R83,U83,L12,D49,R71,U7,L72
|
||||
U62,R66,U55,R34,D71,R55,D58,R83
|
||||
1
2019/tests/samples/03-1-1.out
Normal file
1
2019/tests/samples/03-1-1.out
Normal file
@@ -0,0 +1 @@
|
||||
159
|
||||
2
2019/tests/samples/03-1-2.in
Normal file
2
2019/tests/samples/03-1-2.in
Normal file
@@ -0,0 +1,2 @@
|
||||
R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51
|
||||
U98,R91,D20,R16,D67,R40,U7,R15,U6,R7
|
||||
1
2019/tests/samples/03-1-2.out
Normal file
1
2019/tests/samples/03-1-2.out
Normal file
@@ -0,0 +1 @@
|
||||
135
|
||||
Reference in New Issue
Block a user