Skip to content

Commit ca0d1bd

Browse files
author
avokadoen
committed
Refactored day03 zig to avoid copy and use stack
1 parent cdd24f8 commit ca0d1bd

File tree

1 file changed

+30
-59
lines changed

1 file changed

+30
-59
lines changed

days/day-03/solutions/day03.zig

Lines changed: 30 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -4,79 +4,52 @@ const io = std.io;
44
const ArrayList = std.ArrayList;
55
const Allocator = std.mem.Allocator;
66

7-
const max_file_size = 20_000;
8-
9-
const Tile = enum {
10-
open,
11-
closed
12-
};
13-
14-
const ParseError = error {
15-
UnrecognizedChar
16-
};
17-
18-
// Zig will support support function definition expressions in 0.8
19-
// see: https://github.com/ziglang/zig/issues/1717
20-
inline fn parse(internal_map: *ArrayList(Tile), bytes: ArrayList(u8), pos: usize, exit_on_whitespace: bool) anyerror!usize {
21-
var i: usize = pos;
22-
23-
parser: while (i < bytes.items.len) : (i += 1) {
24-
var tile: Tile = Tile.closed;
25-
26-
switch(bytes.items[i]) {
27-
'.' => tile = Tile.open,
28-
'#' => tile = Tile.closed,
29-
'\n', '\r' => if (exit_on_whitespace) break else continue :parser,
30-
else => return ParseError.UnrecognizedChar
31-
}
32-
33-
try internal_map.append(tile);
34-
}
35-
36-
return i;
37-
}
7+
const MAX_FILE_SIZE = 20_000;
388

399
const Map = struct {
40-
internal_map: ArrayList(Tile),
41-
map_width: usize,
10+
bytes: []u8,
11+
line_width: usize,
4212
map_height: usize,
4313

44-
pub inline fn fromBytesList(bytes: ArrayList(u8), pre_alloc: usize) anyerror!Map {
45-
var internal_map = try ArrayList(Tile).initCapacity(bytes.allocator, pre_alloc);
46-
var map_width: usize = 0;
14+
pub inline fn init(bytes: []u8) Map {
15+
var line_width: usize = 0;
16+
while (line_width < bytes.len) : (line_width += 1) {
17+
switch(bytes[line_width]) {
18+
'\n', '\r' => break,
19+
else => continue
20+
}
21+
}
4722

48-
map_width = try parse(&internal_map, bytes, 0, true);
49-
_ = try parse(&internal_map, bytes, map_width, false);
23+
line_width += 1;
5024

5125
return Map {
52-
.internal_map = internal_map,
53-
.map_width = map_width,
54-
.map_height = @divFloor(internal_map.items.len, map_width)
26+
.bytes = bytes,
27+
.line_width = line_width, // TODO: account for arbitrary line ending format
28+
.map_height = @divFloor(bytes.len, line_width)
5529
};
56-
}
30+
}
5731

58-
pub fn inspectPath(self: Map, right: usize, down: usize) u32 {
32+
pub inline fn inspectPath(self: Map, rigth: usize, down: usize) usize {
5933
var x_pos: usize = 0;
6034
var y_pos: usize = 0;
61-
6235
var closed: u32 = 0;
36+
6337
while (y_pos < self.map_height) {
64-
var wat = self.get(x_pos, y_pos);
65-
closed += @boolToInt(self.get(x_pos, y_pos) == Tile.closed);
66-
x_pos += right;
38+
var n_skipped = @divFloor(x_pos, self.line_width - 1);
39+
var real_x = (x_pos + n_skipped) % self.line_width;
40+
var real_y = y_pos * self.line_width;
41+
42+
closed += @boolToInt(self.bytes[real_x + real_y] == '#');
43+
44+
x_pos += rigth;
6745
y_pos += down;
68-
}
46+
}
6947

7048
return closed;
7149
}
50+
};
7251

73-
pub fn get(self: Map, x: usize, y: usize) Tile {
74-
var real_x = x % self.map_width;
75-
var real_y = y * self.map_width;
7652

77-
return self.internal_map.items[real_x + real_y];
78-
}
79-
};
8053

8154
pub fn main() anyerror!void {
8255
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
@@ -87,12 +60,10 @@ pub fn main() anyerror!void {
8760
const in = std.io.getStdIn().reader();
8861
const stdout = std.io.getStdOut().writer();
8962

90-
// Lets not do io using the stack this time ...
91-
comptime const pre_alloc = max_file_size * 0.8;
92-
var bytes = try ArrayList(u8).initCapacity(allocator, pre_alloc);
93-
try in.readAllArrayList(&bytes, max_file_size);
63+
var buf: [MAX_FILE_SIZE]u8 = undefined;
64+
const length = try in.readAll(&buf);
9465

95-
var map = try Map.fromBytesList(bytes, pre_alloc);
66+
var map = Map.init(buf[0..length]);
9667

9768
var path_3_1 = map.inspectPath(3, 1);
9869
try stdout.print("{}\n", .{path_3_1});

0 commit comments

Comments
 (0)