diff options
| author | Thomas Schmucker <ts@its1.de> | 2023-12-17 22:46:30 +0100 |
|---|---|---|
| committer | Thomas Schmucker <ts@its1.de> | 2023-12-17 22:46:30 +0100 |
| commit | d6a96063a7ff7910a88c52ae1e9a3ea444d1bbc4 (patch) | |
| tree | 7063257fdc742d3c90717dd5720e452e24dc63ad | |
| parent | f7304a97b553a44f3cc9d58ab17da2c6132726e6 (diff) | |
| download | advent-of-code-d6a96063a7ff7910a88c52ae1e9a3ea444d1bbc4.tar.gz advent-of-code-d6a96063a7ff7910a88c52ae1e9a3ea444d1bbc4.tar.bz2 advent-of-code-d6a96063a7ff7910a88c52ae1e9a3ea444d1bbc4.zip | |
Lösungen für Tag 17
| -rw-r--r-- | makefile | 3 | ||||
| -rw-r--r-- | src/day17.cpp | 112 |
2 files changed, 114 insertions, 1 deletions
| @@ -15,7 +15,8 @@ all: bin/day01 \ | |||
| 15 | bin/day13 \ | 15 | bin/day13 \ |
| 16 | bin/day14 \ | 16 | bin/day14 \ |
| 17 | bin/day15 \ | 17 | bin/day15 \ |
| 18 | bin/day16 | 18 | bin/day16 \ |
| 19 | bin/day17 | ||
| 19 | 20 | ||
| 20 | bin: | 21 | bin: |
| 21 | mkdir $@ | 22 | mkdir $@ |
diff --git a/src/day17.cpp b/src/day17.cpp new file mode 100644 index 0000000..4098bba --- /dev/null +++ b/src/day17.cpp | |||
| @@ -0,0 +1,112 @@ | |||
| 1 | #include <array> | ||
| 2 | #include <fstream> | ||
| 3 | #include <functional> | ||
| 4 | #include <iostream> | ||
| 5 | #include <queue> | ||
| 6 | #include <set> | ||
| 7 | #include <string> | ||
| 8 | #include <vector> | ||
| 9 | using namespace std; | ||
| 10 | |||
| 11 | using puzzle_t = vector<vector<int>>; | ||
| 12 | |||
| 13 | puzzle_t | ||
| 14 | read_file(string_view filename) | ||
| 15 | { | ||
| 16 | fstream input{ filename }; | ||
| 17 | puzzle_t data; | ||
| 18 | |||
| 19 | for ( string line; getline(input, line); ) { | ||
| 20 | puzzle_t::value_type numbers; | ||
| 21 | for ( auto chr: line ) { | ||
| 22 | numbers.emplace_back(chr - '0'); | ||
| 23 | } | ||
| 24 | data.emplace_back(numbers); | ||
| 25 | } | ||
| 26 | |||
| 27 | return data; | ||
| 28 | } | ||
| 29 | |||
| 30 | int | ||
| 31 | solve(const puzzle_t& puzzle, size_t min_steps, size_t max_steps) | ||
| 32 | { | ||
| 33 | using pos_t = tuple<size_t, size_t>; | ||
| 34 | using dir_t = tuple<size_t, size_t>; | ||
| 35 | using entry = tuple<int, pos_t, dir_t>; | ||
| 36 | |||
| 37 | static const array<pos_t, 4> directions = { | ||
| 38 | make_tuple(0, 1), | ||
| 39 | make_tuple(0, -1), | ||
| 40 | make_tuple(1, 0), | ||
| 41 | make_tuple(-1, 0) | ||
| 42 | }; | ||
| 43 | |||
| 44 | priority_queue<entry, vector<entry>, greater<>> queue; | ||
| 45 | |||
| 46 | set<tuple<pos_t, dir_t>> seen; | ||
| 47 | |||
| 48 | const pos_t target = { puzzle.size() - 1, puzzle[0].size() - 1 }; | ||
| 49 | |||
| 50 | queue.emplace(0, pos_t(0, 0), dir_t(0, 0)); | ||
| 51 | |||
| 52 | while ( !queue.empty() ) { | ||
| 53 | const auto [heat, pos, dir] = queue.top(); | ||
| 54 | queue.pop(); | ||
| 55 | |||
| 56 | if ( pos == target ) { | ||
| 57 | return heat; | ||
| 58 | } | ||
| 59 | |||
| 60 | const auto key = make_tuple(pos, dir); | ||
| 61 | if ( seen.contains(key) ) { | ||
| 62 | continue; | ||
| 63 | } | ||
| 64 | seen.emplace(key); | ||
| 65 | |||
| 66 | const dir_t inv_dir = { -get<0>(dir), -get<1>(dir) }; | ||
| 67 | |||
| 68 | for ( const auto& next_dir: directions ) { | ||
| 69 | if ( next_dir == dir || next_dir == inv_dir ) { | ||
| 70 | continue; | ||
| 71 | } | ||
| 72 | |||
| 73 | auto heat_so_far = heat; | ||
| 74 | |||
| 75 | for ( size_t steps = 1; steps <= max_steps; ++steps ) { | ||
| 76 | const pos_t next_pos = { get<0>(pos) + get<0>(next_dir) * steps, | ||
| 77 | get<1>(pos) + get<1>(next_dir) * steps }; | ||
| 78 | |||
| 79 | if ( get<0>(next_pos) >= puzzle.size() || get<1>(next_pos) >= puzzle[0].size() ) { | ||
| 80 | continue; | ||
| 81 | } | ||
| 82 | |||
| 83 | heat_so_far += puzzle[get<0>(next_pos)][get<1>(next_pos)]; | ||
| 84 | |||
| 85 | if ( steps >= min_steps ) { | ||
| 86 | queue.emplace(heat_so_far, next_pos, next_dir); | ||
| 87 | } | ||
| 88 | } | ||
| 89 | } | ||
| 90 | } | ||
| 91 | return -1; | ||
| 92 | } | ||
| 93 | |||
| 94 | void | ||
| 95 | part1(const puzzle_t& puzzle) | ||
| 96 | { | ||
| 97 | cout << solve(puzzle, 1, 3) << endl; | ||
| 98 | } | ||
| 99 | |||
| 100 | void | ||
| 101 | part2(const puzzle_t& puzzle) | ||
| 102 | { | ||
| 103 | cout << solve(puzzle, 4, 10) << endl; | ||
| 104 | } | ||
| 105 | |||
| 106 | int | ||
| 107 | main() | ||
| 108 | { | ||
| 109 | const auto puzzle = read_file("data/day17.txt"); | ||
| 110 | part1(puzzle); | ||
| 111 | part2(puzzle); | ||
| 112 | } | ||
