aboutsummaryrefslogtreecommitdiff
path: root/2024
diff options
context:
space:
mode:
Diffstat (limited to '2024')
-rw-r--r--2024/20/Makefile11
-rw-r--r--2024/20/day20a.cpp108
-rw-r--r--2024/20/day20b.cpp114
3 files changed, 233 insertions, 0 deletions
diff --git a/2024/20/Makefile b/2024/20/Makefile
new file mode 100644
index 0000000..0fd3d80
--- /dev/null
+++ b/2024/20/Makefile
@@ -0,0 +1,11 @@
1CC=g++ -std=c++20 -g -Wall
2
3a:
4 ${CC} -o a.out day20a.cpp
5 ./a.out
6
7b:
8 ${CC} -o b.out day20b.cpp
9 ./b.out
10
11.PHONY: a b
diff --git a/2024/20/day20a.cpp b/2024/20/day20a.cpp
new file mode 100644
index 0000000..8837de7
--- /dev/null
+++ b/2024/20/day20a.cpp
@@ -0,0 +1,108 @@
1#include <algorithm>
2#include <cstdint>
3#include <iostream>
4#include <map>
5#include <queue>
6#include <ranges>
7#include <set>
8#include <sstream>
9#include <string>
10#include <string_view>
11#include <vector>
12using namespace std;
13
14class Map {
15public:
16 int N, M, L;
17 int *cell;
18
19 Map(const vector<string>& lines)
20 : N{(int)lines.size()}, M{(int)lines[0].size()}, cell{new int[M*N]}
21 {
22 for (int i = 0; i < N; i++) {
23 for (int j = 0; j < N; j++) {
24 cell[M*i+j] = lines[i][j] == '#' ? -1 : 0;
25 if (lines[i][j] == 'S') {
26 is = i;
27 js = j;
28 }
29 if (lines[i][j] == 'E') {
30 ie = i;
31 je = j;
32 }
33 }
34 }
35 findpath();
36 }
37
38 ~Map() {
39 delete[] cell;
40 }
41
42 int& operator()(int i, int j) {
43 if (i < 0 || i >= N || j < 0 || j >= M)
44 return out_of_bound;
45 return cell[M*i+j];
46 }
47
48 const int& operator()(int i, int j) const {
49 if (i < 0 || i >= N || j < 0 || j >= M)
50 return out_of_bound;
51 return cell[M*i+j];
52 }
53
54 int cheat(int i, int j) {
55 if ((*this)(i, j) != -1)
56 return -1;
57 if ((*this)(i+1, j) >= 0 && (*this)(i-1, j) >= 0)
58 return abs((*this)(i+1, j) - (*this)(i-1, j)) - 2;
59 if ((*this)(i, j+1) >= 0 && (*this)(i, j-1) >= 0)
60 return abs((*this)(i, j+1) - (*this)(i, j-1)) - 2;
61 return -1;
62 }
63private:
64 int is, js, ie, je;
65 int out_of_bound = -1;
66 vector<pair<int, int>> directions {{0,1}, {0,-1}, {1,0}, {-1,0}};
67
68 void findpath() {
69 int i, j, k;
70 for (i = is, j = js, k = 1; i != ie || j != je; step(i, j, k))
71 (*this)(i, j) = k;
72 (*this)(ie, je) = k;
73 L = k-1;
74 }
75
76 void step(int& i, int& j, int& k) {
77 k++;
78 for (auto p : directions) {
79 if ((*this)(i+p.first, j+p.second) == 0) {
80 i = i+p.first;
81 j = j+p.second;
82 return;
83 }
84 }
85 cout << "Error! at " << i << ", " << j << endl;
86 }
87};
88
89int main() {
90 string line;
91 vector<string> lines;
92 while (getline(cin, line))
93 lines.push_back(line);
94 Map m(lines);
95
96 int count = 0;
97 for (int i = 0; i < m.N; i++) {
98 for (int j = 0; j < m.M; j++) {
99 int c = m.cheat(i, j);
100 if (c >= 100)
101 count++;
102 }
103 }
104
105 cout << count << endl;
106
107 return 0;
108}
diff --git a/2024/20/day20b.cpp b/2024/20/day20b.cpp
new file mode 100644
index 0000000..dc55cc0
--- /dev/null
+++ b/2024/20/day20b.cpp
@@ -0,0 +1,114 @@
1#include <algorithm>
2#include <cstdint>
3#include <iostream>
4#include <map>
5#include <queue>
6#include <ranges>
7#include <set>
8#include <sstream>
9#include <string>
10#include <string_view>
11#include <vector>
12using namespace std;
13
14class Map {
15public:
16 int N, M, L;
17 int *cell;
18
19 Map(const vector<string>& lines)
20 : N{(int)lines.size()}, M{(int)lines[0].size()}, cell{new int[M*N]}
21 {
22 for (int i = 0; i < N; i++) {
23 for (int j = 0; j < N; j++) {
24 cell[M*i+j] = lines[i][j] == '#' ? -1 : 0;
25 if (lines[i][j] == 'S') {
26 is = i;
27 js = j;
28 }
29 if (lines[i][j] == 'E') {
30 ie = i;
31 je = j;
32 }
33 }
34 }
35 findpath();
36 }
37
38 ~Map() {
39 delete[] cell;
40 }
41
42 int& operator()(int i, int j) {
43 if (i < 0 || i >= N || j < 0 || j >= M)
44 return out_of_bound;
45 return cell[M*i+j];
46 }
47
48 const int& operator()(int i, int j) const {
49 if (i < 0 || i >= N || j < 0 || j >= M)
50 return out_of_bound;
51 return cell[M*i+j];
52 }
53
54 int cheats(int x, int y, int k, int p) {
55 // Cheats <= p starting at x, y saving at least k picoseconds
56
57 int count = 0;
58 for (int i = 0; i < N; i++)
59 for (int j = 0; j < M; j++)
60 if ((*this)(i, j) != -1)
61 count += saved(i, j, x, y, p) >= k;
62
63 return count;
64 }
65private:
66 int is, js, ie, je;
67 int out_of_bound = -1;
68 vector<pair<int, int>> directions {{0,1}, {0,-1}, {1,0}, {-1,0}};
69
70 void findpath() {
71 int i, j, k;
72 for (i = is, j = js, k = 1; i != ie || j != je; step(i, j, k))
73 (*this)(i, j) = k;
74 (*this)(ie, je) = k;
75 L = k-1;
76 }
77
78 void step(int& i, int& j, int& k) {
79 k++;
80 for (auto p : directions) {
81 if ((*this)(i+p.first, j+p.second) == 0) {
82 i = i+p.first;
83 j = j+p.second;
84 return;
85 }
86 }
87 cout << "Error! at " << i << ", " << j << endl;
88 }
89
90 int saved(int i, int j, int x, int y, int p) {
91 if (int d = abs(i-x) + abs(j-y); d > p)
92 return 0;
93 else
94 return abs((*this)(i, j) - (*this)(x, y)) - d;
95 }
96};
97
98int main() {
99 string line;
100 vector<string> lines;
101 while (getline(cin, line))
102 lines.push_back(line);
103 Map m(lines);
104
105 int count = 0;
106 for (int i = 0; i < m.N; i++)
107 for (int j = 0; j < m.M; j++)
108 if (m(i, j) != -1)
109 count += m.cheats(i, j, 100, 20);
110
111 cout << count / 2 << endl;
112
113 return 0;
114}

Generated with cgit - Back to sebastiano.tronto.net