Skip to content

Commit 71ec718

Browse files
committed
Solve Day 16 Part 2
1 parent 98125f8 commit 71ec718

File tree

23 files changed

+186
-149
lines changed

23 files changed

+186
-149
lines changed

CMakeLists.txt

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,17 @@ set(CMAKE_VERBOSE_MAKEFILE OFF)
1919
include(CheckIPOSupported)
2020
check_ipo_supported(RESULT ipo_available)
2121

22-
add_library(aocio ${CMAKE_CURRENT_SOURCE_DIR}/aocio/aocio.cpp)
23-
add_library(lrucache ${CMAKE_CURRENT_SOURCE_DIR}/lru-cache/lru-cache.cpp)
22+
add_library(aocio ${CMAKE_CURRENT_SOURCE_DIR}/aoclib/aocio.cpp)
2423

24+
# aocio
2525
set_target_properties(aocio PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
26-
target_include_directories(aocio PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/aocio/")
26+
target_include_directories(aocio PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/aoclib/")
2727
target_compile_options(aocio PRIVATE ${WARNING_FLAGS_CXX} $<$<CONFIG:Debug>:-fsanitize=undefined,address -g3 -Og>)
2828
target_link_options(aocio PRIVATE ${WARNING_FLAGS_CXX} $<$<CONFIG:Debug>:-fsanitize=undefined,address -g3 -Og>)
2929

30-
set_target_properties(lrucache PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
31-
target_include_directories(lrucache PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/lru-cache/")
32-
target_compile_options(lrucache PRIVATE ${WARNING_FLAGS_CXX} $<$<CONFIG:Debug>:-fsanitize=undefined,address -g3 -Og>)
33-
target_link_options(lrucache PRIVATE ${WARNING_FLAGS_CXX} $<$<CONFIG:Debug>:-fsanitize=undefined,address -g3 -Og>)
34-
3530
if(ipo_available AND (NOT CMAKE_BUILD_TYPE MATCHES Debug) AND (NOT CMAKE_BUILD_TYPE MATCHES RelWithDebInfo))
3631
message("-- IPO enabled")
3732
set_property(TARGET aocio PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
38-
set_property(TARGET lrucache PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
3933

4034
endif()
4135

@@ -46,11 +40,10 @@ list(LENGTH TARGETS NUM_TARGETS)
4640
foreach(current_target IN LISTS TARGETS)
4741
add_executable(${current_target} ${current_target}/${current_target}.cpp)
4842
set_target_properties(${current_target} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
49-
target_include_directories(${current_target} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/aocio/")
43+
target_include_directories(${current_target} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/aoclib/")
5044
target_compile_options(${current_target} PRIVATE ${WARNING_FLAGS_CXX} $<$<CONFIG:Debug>:-fsanitize=undefined,address -g3 -Og>)
5145
target_link_options(${current_target} PRIVATE ${WARNING_FLAGS_CXX} $<$<CONFIG:Debug>:-fsanitize=undefined,address -g3 -Og>)
52-
target_link_libraries(${current_target} lrucache aocio)
53-
46+
target_link_libraries(${current_target} aocio)
5447

5548
target_compile_definitions(${current_target} PRIVATE AOC_INPUT_PATH="${CMAKE_CURRENT_SOURCE_DIR}/${current_target}/input.txt")
5649
target_compile_definitions(${current_target} PRIVATE AOC_INPUT_DIR="${CMAKE_CURRENT_SOURCE_DIR}/${current_target}/")

aocio/aocio.cpp renamed to aoclib/aocio.cpp

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
#include <iostream>
2-
#include <sstream>
3-
#include <fstream>
4-
#include <vector>
5-
#include <cassert>
6-
#include <string>
7-
81
#include "aocio.hpp"
92

103
bool aocio::file_getlines(std::string_view fname, std::vector<std::string>& lines)
@@ -27,7 +20,7 @@ void aocio::line_tokenise(const std::string& line, const std::string& delims, co
2720
{
2821
for (char d : preserved_delims) {
2922
if (delims.find(d) == std::string::npos) {
30-
throw "Preserved delim not in delims";
23+
throw std::invalid_argument("Preserved delim not in delims");
3124
}
3225
}
3326
std::string::size_type start_pos = 0;
@@ -50,22 +43,22 @@ void aocio::line_tokenise(const std::string& line, const std::string& delims, co
5043
}
5144
}
5245

53-
int aocio::parse_num(const std::string &str)
46+
std::optional<int> aocio::parse_num(const std::string &str)
5447
{
5548
size_t num_read = 0;
5649
int n = std::stoi(str, &num_read);
5750
if (num_read == 0) {
58-
throw "Invalid token: expected number";
51+
return {};
5952
}
6053
return n;
6154
}
6255

63-
int64_t aocio::parse_num_i64(const std::string& str)
56+
std::optional<int64_t> aocio::parse_num_i64(const std::string& str)
6457
{
6558
size_t num_read = 0;
6659
int64_t n = std::stoll(str, &num_read);
6760
if (num_read == 0) {
68-
throw "Invalid token: expected number";
61+
return {};
6962
}
7063
return n;
7164
}

aoclib/aocio.hpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#pragma once
2+
3+
#include <iostream>
4+
#include <sstream>
5+
#include <fstream>
6+
#include <filesystem>
7+
#include <vector>
8+
#include <limits>
9+
#include <cassert>
10+
#include <optional>
11+
12+
#ifndef AOC_INPUT_PATH
13+
#define AOC_INPUT_PATH ""
14+
#endif
15+
16+
#ifndef AOC_INPUT_DIR
17+
#define AOC_INPUT_DIR ""
18+
#endif
19+
20+
namespace aocio
21+
{
22+
bool file_getlines(std::string_view fname, std::vector<std::string>& lines);
23+
void line_tokenise(const std::string& line, const std::string& delims, const std::string& preserved_delims, std::vector<std::string>& tokens);
24+
25+
std::optional<int> parse_num(const std::string &str);
26+
std::optional<int64_t> parse_num_i64(const std::string& str);
27+
28+
inline void print_day()
29+
{
30+
std::string day_name {std::filesystem::path(AOC_INPUT_DIR).parent_path().filename()};
31+
32+
if (day_name.size()) {
33+
day_name[0] = std::toupper(day_name[0]);
34+
}
35+
36+
std::string debug_release;
37+
#ifdef NDEBUG
38+
debug_release = "Release";
39+
#else
40+
debug_release = "Debug";
41+
#endif
42+
43+
std::cout << day_name << " (" << debug_release << ")\n";
44+
}
45+
}

aocio/aocio.hpp renamed to aoclib/grid.hpp

Lines changed: 31 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,14 @@
1-
#pragma once
2-
3-
#include <iostream>
4-
#include <sstream>
5-
#include <fstream>
6-
#include <filesystem>
71
#include <vector>
82
#include <limits>
93
#include <cassert>
104
#include <optional>
11-
12-
#include "aocio.hpp"
13-
14-
#ifndef AOC_INPUT_PATH
15-
#define AOC_INPUT_PATH ""
16-
#endif
17-
18-
#ifndef AOC_INPUT_DIR
19-
#define AOC_INPUT_DIR ""
20-
#endif
21-
22-
namespace aocio
23-
{
24-
bool file_getlines(std::string_view fname, std::vector<std::string>& lines);
25-
void line_tokenise(const std::string& line, const std::string& delims, const std::string& preserved_delims, std::vector<std::string>& tokens);
26-
27-
int parse_num(const std::string &str);
28-
int64_t parse_num_i64(const std::string& str);
29-
30-
inline void print_day()
31-
{
32-
std::string day_name {std::filesystem::path(AOC_INPUT_DIR).parent_path().filename()};
33-
34-
if (day_name.size()) {
35-
day_name[0] = std::toupper(day_name[0]);
36-
}
37-
38-
std::string debug_release;
39-
#ifdef NDEBUG
40-
debug_release = "Release";
41-
#else
42-
debug_release = "Debug";
43-
#endif
44-
45-
std::cout << day_name << " (" << debug_release << ")\n";
46-
}
47-
}
5+
#include "vec.hpp"
486

497
namespace aocutil
508
{
519

52-
template<typename T>
53-
struct Vec2 {
54-
T x, y;
55-
56-
Vec2 operator+(const Vec2& v) const
57-
{
58-
return Vec2{.x = x + v.x, .y = y + v.y};
59-
}
60-
61-
Vec2 operator-(const Vec2& v) const
62-
{
63-
return Vec2{.x = x - v.x, .y = y - v.y};
64-
}
65-
66-
bool operator==(const Vec2& v) const = default;
67-
};
68-
6910
template<typename RowType, typename ElemType>
70-
class Grid;
11+
class Grid; // Forward declaration for the iterators.
7112

7213
// cf. on custom iterators: https://internalpointers.com/post/writing-custom-iterators-modern-cpp (last retrieved 2024-06-19)
7314
template<typename RowType, typename ElemType, bool is_const>
@@ -80,8 +21,6 @@ struct GridColIterator
8021
using reference = typename std::conditional_t<is_const, const ElemType&, ElemType&>;
8122
using parent_ptr_type = typename std::conditional_t<is_const, const Grid<RowType, ElemType>*, Grid<RowType, ElemType>*>;
8223

83-
// GridColIterator() = default;
84-
8524
GridColIterator(int column, int row, parent_ptr_type parent) : col(column), current_row(row), parent(parent)
8625
{
8726
assert(parent);
@@ -160,7 +99,7 @@ struct GridColIterator
16099
{
161100
int new_row = current_row - n;
162101
if (new_row < 0 || new_row >= parent->height()) {
163-
throw std::out_of_range("GridIter: subscript out of range");
102+
throw std::out_of_range("GridColIterator: subscript out of range");
164103
}
165104
return parent->at(col, new_row);
166105
}
@@ -187,13 +126,24 @@ struct GridColIterator
187126
return iter - n;
188127
}
189128

190-
friend bool operator==(const GridColIterator& a, const GridColIterator& b) {assert(a.col == b.col && a.parent == b.parent); return a.current_row == b.current_row; };
191-
friend bool operator!=(const GridColIterator& a, const GridColIterator& b) {assert(a.col == b.col && a.parent == b.parent); return a.current_row != b.current_row;};
129+
friend bool operator==(const GridColIterator& a, const GridColIterator& b)
130+
{
131+
assert(a.col == b.col && a.parent == b.parent);
132+
bool eq = a.current_row == b.current_row;
133+
assert(!(eq && (a.ptr != b.ptr)));
134+
return eq;
135+
};
136+
137+
friend bool operator!=(const GridColIterator& a, const GridColIterator& b)
138+
{
139+
assert(a.col == b.col && a.parent == b.parent);
140+
return a.current_row != b.current_row;
141+
};
192142

193143
private:
194144
int col;
195145
int current_row;
196-
parent_ptr_type parent = nullptr; // ptr itself is const (and parent_ptr_type depending on is_const).
146+
parent_ptr_type parent = nullptr;
197147
pointer ptr;
198148
};
199149

@@ -208,8 +158,6 @@ struct GridIterator
208158
using reference = typename std::conditional_t<is_const, const ElemType&, ElemType&>;
209159
using parent_ptr_type = typename std::conditional_t<is_const, const Grid<RowType, ElemType>*, Grid<RowType, ElemType>*>;
210160

211-
// GridIterator() = default;
212-
213161
GridIterator(int column, int row, parent_ptr_type parent) : current_col(column), current_row(row), parent(parent)
214162
{
215163
assert(parent);
@@ -332,7 +280,7 @@ struct GridIterator
332280
int new_col = new_idx % parent->width();
333281
int new_row = new_idx / parent->width();
334282
if (!parent->pos_on_grid(new_col, new_row)) {
335-
throw std::out_of_range("Grid: subscript out of range.");
283+
throw std::out_of_range("GridIterator: subscript out of range.");
336284
}
337285
return parent->at(new_col, new_row);
338286
}
@@ -363,8 +311,18 @@ struct GridIterator
363311
return iter - n;
364312
}
365313

366-
friend bool operator==(const GridIterator& a, const GridIterator& b) {assert(a.parent == b.parent); return a.ptr == b.ptr;};
367-
friend bool operator!=(const GridIterator& a, const GridIterator& b) {assert(a.parent == b.parent); return a.ptr != b.ptr;};
314+
friend bool operator==(const GridIterator& a, const GridIterator& b)
315+
{
316+
assert(a.parent == b.parent);
317+
return a.ptr == b.ptr && (a.current_col == b.current_col && a.current_row == b.current_row);
318+
};
319+
320+
friend bool operator!=(const GridIterator& a, const GridIterator& b)
321+
{
322+
assert(a.parent == b.parent);
323+
assert(!((a.ptr != b.ptr) && (a.current_col == b.current_col && a.current_row == b.current_row)));
324+
return a.ptr != b.ptr;
325+
};
368326

369327
private:
370328
int current_col = 0;
@@ -567,15 +525,4 @@ class Grid
567525
}
568526
};
569527

570-
}
571-
572-
template<typename T>
573-
struct std::hash<aocutil::Vec2<T>>
574-
{
575-
std::size_t operator()(const aocutil::Vec2<T>& v) const noexcept
576-
{
577-
std::size_t h1 = std::hash<T>{}(v.x);
578-
std::size_t h2 = std::hash<T>{}(v.y);
579-
return h1 ^ (h2 << 1); // cf. https://en.cppreference.com/w/cpp/utility/hash (last retrieved 2024-06-17)
580-
}
581-
};
528+
}

lru-cache/lru-cache.hpp renamed to aoclib/lru-cache.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#include <array>
33
#include <unordered_map>
44

5+
namespace aocutil
6+
{
57
/*
68
General idea: https://stackoverflow.com/questions/2504178/lru-cache-design/54272232#54272232 (last retrieved 2024-06-16)
79
Instead of using std::list, a custom intrusive doubly linked list is used, which means
@@ -205,7 +207,7 @@ class LRUCache
205207
{
206208
os << "size: " << cache.size <<"\n";
207209
size_t idx = cache.head_idx;
208-
size_t prev_idx = LRUCache::IDX_NULL;
210+
[[maybe_unused]] size_t prev_idx = LRUCache::IDX_NULL;
209211
while (idx != LRUCache<Key, Val, N>::IDX_NULL ) {
210212
const auto& v = cache.nodes.at(idx);
211213

@@ -224,4 +226,6 @@ class LRUCache
224226
}
225227
return os;
226228
}
227-
};
229+
};
230+
231+
}

aoclib/vec.hpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#include <memory>
2+
3+
namespace aocutil
4+
{
5+
6+
template<typename T>
7+
struct Vec2 {
8+
T x, y;
9+
10+
Vec2 operator+(const Vec2& v) const
11+
{
12+
return Vec2{.x = x + v.x, .y = y + v.y};
13+
}
14+
15+
Vec2 operator-(const Vec2& v) const
16+
{
17+
return Vec2{.x = x - v.x, .y = y - v.y};
18+
}
19+
20+
bool operator==(const Vec2& v) const = default;
21+
};
22+
23+
}
24+
25+
template<typename T>
26+
struct std::hash<aocutil::Vec2<T>>
27+
{
28+
std::size_t operator()(const aocutil::Vec2<T>& v) const noexcept
29+
{
30+
std::size_t h1 = std::hash<T>{}(v.x);
31+
std::size_t h2 = std::hash<T>{}(v.y);
32+
return h1 ^ (h2 << 1); // cf. https://en.cppreference.com/w/cpp/utility/hash (last retrieved 2024-06-17)
33+
}
34+
};

day-01/day-01.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "../aocio/aocio.hpp"
1+
#include "../aoclib/aocio.hpp"
22

33
/*
44
Problem: https://adventofcode.com/2023/day/1

day-02/day-02.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include <unordered_map>
2-
#include "../aocio/aocio.hpp"
2+
#include "../aoclib/aocio.hpp"
33

44
/*
55
Problem: https://adventofcode.com/2023/day/2

day-03/day-03.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include <algorithm>
2-
#include "../aocio/aocio.hpp"
2+
#include "../aoclib/aocio.hpp"
33

44
/*
55
Problem: https://adventofcode.com/2023/day/3

0 commit comments

Comments
 (0)