Skip to content

Commit b0e4654

Browse files
committed
Day 12 part 2, remove debug
1 parent f3cabe5 commit b0e4654

File tree

2 files changed

+126
-20
lines changed

2 files changed

+126
-20
lines changed

day12/part1.zig

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -57,21 +57,6 @@ pub fn main() !void {
5757
}
5858
}
5959
}
60-
{
61-
var it = cave_id.iterator();
62-
while (it.next()) |e| {
63-
std.debug.print("{s} {d}\n", .{ e.key_ptr.*, e.value_ptr.* });
64-
}
65-
std.debug.print("\n", .{});
66-
}
67-
68-
{
69-
var it = is_small_cave.iterator(.{});
70-
while (it.next()) |sc| {
71-
std.debug.print("{d},", .{sc});
72-
}
73-
std.debug.print("\n\n", .{});
74-
}
7560

7661
var paths: u64 = 0;
7762
var been_to = try std.DynamicBitSet.initEmpty(ids, allocator);
@@ -95,11 +80,6 @@ pub fn main() !void {
9580
const n = ns.items[v.n_idx];
9681
if (n == 1) {
9782
// found "end" node, new path
98-
for (stack.items) |e| {
99-
std.debug.print("{d},", .{e.id});
100-
}
101-
std.debug.print("\n", .{});
102-
10383
paths += 1;
10484
continue;
10585
}

day12/part2.zig

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
const std = @import("std");
2+
3+
pub fn main() !void {
4+
var file = try std.fs.cwd().openFile("input", .{});
5+
defer file.close();
6+
7+
var buf_reader = std.io.bufferedReader(file.reader());
8+
var in_stream = buf_reader.reader();
9+
10+
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
11+
defer arena.deinit();
12+
13+
const allocator = &arena.allocator;
14+
15+
var cave_id = std.StringHashMap(u32).init(allocator);
16+
defer {
17+
// TODO how to free string keys of map?
18+
// while (it.next()) |k| {
19+
// allocator.free(slice);
20+
// }
21+
22+
cave_id.deinit();
23+
}
24+
25+
var neighbors = std.ArrayList(std.ArrayList(u32)).init(allocator);
26+
defer {
27+
for (neighbors.items) |ns| {
28+
ns.deinit();
29+
}
30+
neighbors.deinit();
31+
}
32+
33+
var ids: u32 = 0;
34+
35+
_ = try getOrSetId(&cave_id, &neighbors, &ids, allocator, "start");
36+
_ = try getOrSetId(&cave_id, &neighbors, &ids, allocator, "end");
37+
38+
var read_buf: [1024]u8 = undefined;
39+
while (try in_stream.readUntilDelimiterOrEof(&read_buf, '\n')) |line| {
40+
var split = std.mem.split(line, "-");
41+
const from = split.next().?;
42+
const to = split.next().?;
43+
const from_id = try getOrSetId(&cave_id, &neighbors, &ids, allocator, from);
44+
const to_id = try getOrSetId(&cave_id, &neighbors, &ids, allocator, to);
45+
46+
try neighbors.items[from_id].append(to_id);
47+
try neighbors.items[to_id].append(from_id);
48+
}
49+
50+
var is_small_cave = try std.DynamicBitSet.initEmpty(ids, allocator);
51+
defer is_small_cave.deinit();
52+
{
53+
var it = cave_id.iterator();
54+
while (it.next()) |e| {
55+
if (std.ascii.isLower(e.key_ptr.*[0])) {
56+
is_small_cave.set(e.value_ptr.*);
57+
}
58+
}
59+
}
60+
61+
var paths: u64 = 0;
62+
var been_to = try std.DynamicBitSet.initEmpty(ids, allocator);
63+
defer been_to.deinit();
64+
65+
var stack = std.ArrayList(NextCave).init(allocator);
66+
defer stack.deinit();
67+
68+
try stack.append(NextCave{ .id = 0, .n_idx = 0 });
69+
been_to.set(0);
70+
71+
var double_visited: ?u32 = null;
72+
73+
while (stack.items.len != 0) {
74+
const v = stack.pop();
75+
const ns = neighbors.items[v.id];
76+
if (v.n_idx >= ns.items.len) {
77+
if (double_visited == v.id) {
78+
double_visited = null;
79+
} else {
80+
been_to.unset(v.id);
81+
}
82+
continue;
83+
}
84+
85+
try stack.append(NextCave{ .id = v.id, .n_idx = v.n_idx + 1 });
86+
const n = ns.items[v.n_idx];
87+
if (n == 1) {
88+
// found "end" node, new path
89+
paths += 1;
90+
continue;
91+
}
92+
if (!been_to.isSet(n)) {
93+
try stack.append(NextCave{ .id = n, .n_idx = 0 });
94+
if (is_small_cave.isSet(n)) {
95+
been_to.set(n);
96+
}
97+
} else if (double_visited == null and n != 0 and n != 1) {
98+
try stack.append(NextCave{ .id = n, .n_idx = 0 });
99+
double_visited = n;
100+
}
101+
}
102+
103+
const stdout = std.io.getStdOut().writer();
104+
try stdout.print("{d}\n", .{paths});
105+
}
106+
107+
const NextCave = struct {
108+
id: u32,
109+
n_idx: u32,
110+
};
111+
112+
fn getOrSetId(cave_id: *std.StringHashMap(u32), neighbors: *std.ArrayList(std.ArrayList(u32)), ids: *u32, allocator: *std.mem.Allocator, name_str: []const u8) !u32 {
113+
const name: []const u8 = try allocator.dupe(u8, name_str);
114+
if (cave_id.get(name)) |id| {
115+
return id;
116+
}
117+
118+
const id: u32 = ids.*;
119+
const new_ids: u32 = id + 1;
120+
ids.* = new_ids;
121+
122+
try cave_id.put(name, id);
123+
124+
try neighbors.append(std.ArrayList(u32).init(allocator));
125+
return id;
126+
}

0 commit comments

Comments
 (0)