Skip to content

Commit cd40a1a

Browse files
committed
day 18.
This one was easy, but I kinda phoned it in. At least I learned about iota_view.
1 parent bef84f6 commit cd40a1a

File tree

4 files changed

+130
-2
lines changed

4 files changed

+130
-2
lines changed

18/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#CXXSTD = c++23
2+
include ../Makefile.inc

18/eg.txt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
5,4
2+
4,2
3+
4,5
4+
3,0
5+
2,1
6+
6,3
7+
2,4
8+
1,5
9+
0,6
10+
3,3
11+
2,6
12+
5,1
13+
1,2
14+
5,5
15+
2,5
16+
6,5
17+
1,4
18+
0,4
19+
6,4
20+
1,1
21+
6,1
22+
1,0
23+
0,5
24+
1,6
25+
2,0

18/solve.cc

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#include "aoc.h"
2+
3+
namespace {
4+
enum Direction { NORTH, EAST, SOUTH, WEST };
5+
6+
using Scalar = unsigned;
7+
using Int = unsigned short;
8+
constexpr Int MAX = std::numeric_limits<Int>::max();
9+
10+
struct Point {
11+
Scalar row{}, col{};
12+
Point operator+ (const Point &rhs) const noexcept { return { Scalar(row + rhs.row), Scalar(col + rhs.col) }; }
13+
auto operator <=> (const Point &rhs) const = default;
14+
};
15+
16+
struct Cell {
17+
unsigned short wall:1{};
18+
unsigned short epoch:15{};
19+
Int cost;
20+
};
21+
22+
constexpr Point velocity(Direction d) noexcept {
23+
switch (d) {
24+
case NORTH: return {Scalar(-1), 0};
25+
case SOUTH: return {1, 0};
26+
case EAST: return {0, 1};
27+
case WEST: return {0, Scalar(-1)};
28+
default: __builtin_unreachable();
29+
}
30+
}
31+
32+
struct Node {
33+
unsigned long cost { MAX };
34+
Point pos{};
35+
auto operator <=> (const Node &rhs) const = default;
36+
};
37+
38+
static constexpr Scalar ROWS = 71;
39+
static constexpr Scalar COLS = 71;
40+
41+
struct MemorySpace {
42+
std::vector<Cell> map;
43+
unsigned age{};
44+
Point s{0,0}, e{ROWS-1, COLS-1};
45+
46+
Cell & at(Point p) { return map[p.row * COLS + p.col]; }
47+
std::vector<Point> walls;
48+
const Cell & at(Point p) const { return map[p.row * COLS + p.col]; }
49+
50+
Int dijkstra(unsigned maxage) {
51+
for (auto &cell : map)
52+
cell.cost = MAX;
53+
std::set<Node> Q;
54+
Q.insert({.cost=0, .pos = {0,0}});
55+
while (Q.begin()->pos != e) {
56+
auto head = Q.begin();
57+
auto item = *head;
58+
Q.erase(head);
59+
auto try_add = [&](Point p, Int c) {
60+
if (p.row >= ROWS || p.col >= COLS)
61+
return;
62+
auto &cell = at(p);
63+
if ((cell.wall && cell.epoch < maxage) || cell.cost < c )
64+
return;
65+
cell.cost = c;
66+
Q.insert({.cost=c, .pos=p });
67+
};
68+
try_add(item.pos + velocity(NORTH), item.cost + 1);
69+
try_add(item.pos + velocity(SOUTH), item.cost + 1);
70+
try_add(item.pos + velocity(EAST), item.cost + 1);
71+
try_add(item.pos + velocity(WEST), item.cost + 1);
72+
if (Q.empty())
73+
return MAX;
74+
}
75+
return Q.begin()->cost;
76+
}
77+
78+
MemorySpace(std::istream &is) noexcept : map ( ROWS * COLS ) {
79+
for (std::string line; getline(is, line); ) {
80+
std::string_view v = line;
81+
Scalar col = aoc::parsetoken<int>(v, ",");
82+
Scalar row = aoc::parsetoken<int>(v, "\n");
83+
walls.emplace_back(row, col);
84+
auto &cell = at({row, col});
85+
cell.wall = true;
86+
cell.epoch = age++;
87+
}
88+
}
89+
};
90+
aoc::Case case1{"part1", [](std::istream &is, std::ostream &os) { os << MemorySpace(is).dijkstra(1024); } };
91+
92+
struct Part2 : MemorySpace {
93+
Part2( std::istream &is ) : MemorySpace(is) {}
94+
void part2(std::ostream &os) {
95+
auto res = std::ranges::partition_point( std::ranges::iota_view(unsigned(0), age) , [this] ( unsigned value ) { auto v = dijkstra(value); return v != MAX; });
96+
os << walls[*res - 1].col << "," << walls[*res - 1].row << "\n";
97+
}
98+
};
99+
aoc::Case case2{"part2", [](std::istream &is, std::ostream &os) { Part2(is).part2(os); } };
100+
}

Makefile.inc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
OPT ?= -O0 -pipe
2-
CXXFLAGS += -g --std=c++2a -Wall -Wextra $(OPT) -I../include
3-
ASFLAGS += -g --std=c++2a -Wall -Wextra $(OPT) -I../include
2+
CXXSTD ?= c++2a
3+
CXXFLAGS += -g --std=$(CXXSTD) -Wall -Wextra $(OPT) -I../include
4+
ASFLAGS += -g --std=$(CXXSTD) -Wall -Wextra $(OPT) -I../include
45

56
.PHONY: all clean
67
VPATH = ../lib

0 commit comments

Comments
 (0)