From cdd24f8b8a75d74c1502014d626b929b72f0a5b7 Mon Sep 17 00:00:00 2001 From: avokadoen Date: Mon, 7 Dec 2020 19:18:33 +0100 Subject: [PATCH 1/4] day 3 zig --- days/day-02/solutions/day02.zig | 6 +- days/day-03/solutions/day03.zig | 101 ++++++++++++++++++++++++++++++++ days/day-03/test.sh | 1 + 3 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 days/day-03/solutions/day03.zig diff --git a/days/day-02/solutions/day02.zig b/days/day-02/solutions/day02.zig index 5032f35d..0fb6bc69 100644 --- a/days/day-02/solutions/day02.zig +++ b/days/day-02/solutions/day02.zig @@ -65,14 +65,14 @@ const RequirementPassword = struct { return occurence >= self.min; } - pub inline fn newValid(self: RequirementPassword) bool { + pub inline fn newValid(self: RequirementPassword) bool { var min_occurence: usize = @boolToInt(self.password[self.min - 1] == self.char); var max_occurence: usize = @boolToInt(self.password[self.max - 1] == self.char); return @as(usize, min_occurence) + @as(usize, max_occurence) == 1; } }; -fn bytesToRPPArrayList(allocator: *Allocator, bytes: []u8) !ArrayList(RequirementPassword) { +fn bytesToParsedArrayList(allocator: *Allocator, bytes: []u8) !ArrayList(RequirementPassword) { var list = try ArrayList(RequirementPassword).initCapacity(allocator, 2000); var it = mem.split(bytes, "\n"); @@ -110,7 +110,7 @@ pub fn main() anyerror!void { const length = try in.readAll(&buf); - var parsed_input = try bytesToRPPArrayList(allocator, buf[0..length]); + var parsed_input = try bytesToParsedArrayList(allocator, buf[0..length]); var old_valid: u32 = 0; var new_valid: u32 = 0; diff --git a/days/day-03/solutions/day03.zig b/days/day-03/solutions/day03.zig new file mode 100644 index 00000000..7f416f32 --- /dev/null +++ b/days/day-03/solutions/day03.zig @@ -0,0 +1,101 @@ +const std = @import("std"); +const mem = std.mem; +const io = std.io; +const ArrayList = std.ArrayList; +const Allocator = std.mem.Allocator; + +const max_file_size = 20_000; + +const Tile = enum { + open, + closed +}; + +const ParseError = error { + UnrecognizedChar +}; + +// Zig will support support function definition expressions in 0.8 +// see: https://github.com/ziglang/zig/issues/1717 +inline fn parse(internal_map: *ArrayList(Tile), bytes: ArrayList(u8), pos: usize, exit_on_whitespace: bool) anyerror!usize { + var i: usize = pos; + + parser: while (i < bytes.items.len) : (i += 1) { + var tile: Tile = Tile.closed; + + switch(bytes.items[i]) { + '.' => tile = Tile.open, + '#' => tile = Tile.closed, + '\n', '\r' => if (exit_on_whitespace) break else continue :parser, + else => return ParseError.UnrecognizedChar + } + + try internal_map.append(tile); + } + + return i; +} + +const Map = struct { + internal_map: ArrayList(Tile), + map_width: usize, + map_height: usize, + + pub inline fn fromBytesList(bytes: ArrayList(u8), pre_alloc: usize) anyerror!Map { + var internal_map = try ArrayList(Tile).initCapacity(bytes.allocator, pre_alloc); + var map_width: usize = 0; + + map_width = try parse(&internal_map, bytes, 0, true); + _ = try parse(&internal_map, bytes, map_width, false); + + return Map { + .internal_map = internal_map, + .map_width = map_width, + .map_height = @divFloor(internal_map.items.len, map_width) + }; + } + + pub fn inspectPath(self: Map, right: usize, down: usize) u32 { + var x_pos: usize = 0; + var y_pos: usize = 0; + + var closed: u32 = 0; + while (y_pos < self.map_height) { + var wat = self.get(x_pos, y_pos); + closed += @boolToInt(self.get(x_pos, y_pos) == Tile.closed); + x_pos += right; + y_pos += down; + } + + return closed; + } + + pub fn get(self: Map, x: usize, y: usize) Tile { + var real_x = x % self.map_width; + var real_y = y * self.map_width; + + return self.internal_map.items[real_x + real_y]; + } +}; + +pub fn main() anyerror!void { + var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); + defer arena.deinit(); + + const allocator = &arena.allocator; + + const in = std.io.getStdIn().reader(); + const stdout = std.io.getStdOut().writer(); + + // Lets not do io using the stack this time ... + comptime const pre_alloc = max_file_size * 0.8; + var bytes = try ArrayList(u8).initCapacity(allocator, pre_alloc); + try in.readAllArrayList(&bytes, max_file_size); + + var map = try Map.fromBytesList(bytes, pre_alloc); + + var path_3_1 = map.inspectPath(3, 1); + try stdout.print("{}\n", .{path_3_1}); + + try stdout.print("{}\n", .{map.inspectPath(1, 1) * path_3_1 * map.inspectPath(5, 1) * map.inspectPath(7, 1) * map.inspectPath(1, 2)}); +} \ No newline at end of file diff --git a/days/day-03/test.sh b/days/day-03/test.sh index e22dff49..0cf06015 100755 --- a/days/day-03/test.sh +++ b/days/day-03/test.sh @@ -6,6 +6,7 @@ D=$(dirname $(realpath $0)) echo "" echo "--- Day 3: Counting trees ---" $D/../../languages/c.sh $D/input.txt $D/output.txt $D/solutions/day03.c +$D/../../languages/zig.sh $D/input.txt $D/output.txt $D/solutions/day03.zig $D/../../languages/go.sh $D/input.txt $D/output.txt $D/solutions/day03.stektpotet.go $D/../../languages/go.sh $D/input.txt $D/output.txt $D/solutions/day03.tholok97.go $D/../../languages/sml.sh $D/input.txt $D/output.txt $D/solutions/day03.sml From ca0d1bd4e6cc12a01f747166fa27f25aba113773 Mon Sep 17 00:00:00 2001 From: avokadoen Date: Tue, 8 Dec 2020 00:14:13 +0100 Subject: [PATCH 2/4] Refactored day03 zig to avoid copy and use stack --- days/day-03/solutions/day03.zig | 89 +++++++++++---------------------- 1 file changed, 30 insertions(+), 59 deletions(-) diff --git a/days/day-03/solutions/day03.zig b/days/day-03/solutions/day03.zig index 7f416f32..e727683b 100644 --- a/days/day-03/solutions/day03.zig +++ b/days/day-03/solutions/day03.zig @@ -4,79 +4,52 @@ const io = std.io; const ArrayList = std.ArrayList; const Allocator = std.mem.Allocator; -const max_file_size = 20_000; - -const Tile = enum { - open, - closed -}; - -const ParseError = error { - UnrecognizedChar -}; - -// Zig will support support function definition expressions in 0.8 -// see: https://github.com/ziglang/zig/issues/1717 -inline fn parse(internal_map: *ArrayList(Tile), bytes: ArrayList(u8), pos: usize, exit_on_whitespace: bool) anyerror!usize { - var i: usize = pos; - - parser: while (i < bytes.items.len) : (i += 1) { - var tile: Tile = Tile.closed; - - switch(bytes.items[i]) { - '.' => tile = Tile.open, - '#' => tile = Tile.closed, - '\n', '\r' => if (exit_on_whitespace) break else continue :parser, - else => return ParseError.UnrecognizedChar - } - - try internal_map.append(tile); - } - - return i; -} +const MAX_FILE_SIZE = 20_000; const Map = struct { - internal_map: ArrayList(Tile), - map_width: usize, + bytes: []u8, + line_width: usize, map_height: usize, - pub inline fn fromBytesList(bytes: ArrayList(u8), pre_alloc: usize) anyerror!Map { - var internal_map = try ArrayList(Tile).initCapacity(bytes.allocator, pre_alloc); - var map_width: usize = 0; + pub inline fn init(bytes: []u8) Map { + var line_width: usize = 0; + while (line_width < bytes.len) : (line_width += 1) { + switch(bytes[line_width]) { + '\n', '\r' => break, + else => continue + } + } - map_width = try parse(&internal_map, bytes, 0, true); - _ = try parse(&internal_map, bytes, map_width, false); + line_width += 1; return Map { - .internal_map = internal_map, - .map_width = map_width, - .map_height = @divFloor(internal_map.items.len, map_width) + .bytes = bytes, + .line_width = line_width, // TODO: account for arbitrary line ending format + .map_height = @divFloor(bytes.len, line_width) }; - } + } - pub fn inspectPath(self: Map, right: usize, down: usize) u32 { + pub inline fn inspectPath(self: Map, rigth: usize, down: usize) usize { var x_pos: usize = 0; var y_pos: usize = 0; - var closed: u32 = 0; + while (y_pos < self.map_height) { - var wat = self.get(x_pos, y_pos); - closed += @boolToInt(self.get(x_pos, y_pos) == Tile.closed); - x_pos += right; + var n_skipped = @divFloor(x_pos, self.line_width - 1); + var real_x = (x_pos + n_skipped) % self.line_width; + var real_y = y_pos * self.line_width; + + closed += @boolToInt(self.bytes[real_x + real_y] == '#'); + + x_pos += rigth; y_pos += down; - } + } return closed; } +}; - pub fn get(self: Map, x: usize, y: usize) Tile { - var real_x = x % self.map_width; - var real_y = y * self.map_width; - return self.internal_map.items[real_x + real_y]; - } -}; pub fn main() anyerror!void { var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); @@ -87,12 +60,10 @@ pub fn main() anyerror!void { const in = std.io.getStdIn().reader(); const stdout = std.io.getStdOut().writer(); - // Lets not do io using the stack this time ... - comptime const pre_alloc = max_file_size * 0.8; - var bytes = try ArrayList(u8).initCapacity(allocator, pre_alloc); - try in.readAllArrayList(&bytes, max_file_size); + var buf: [MAX_FILE_SIZE]u8 = undefined; + const length = try in.readAll(&buf); - var map = try Map.fromBytesList(bytes, pre_alloc); + var map = Map.init(buf[0..length]); var path_3_1 = map.inspectPath(3, 1); try stdout.print("{}\n", .{path_3_1}); From 2fbbf325d92f8c110c269c0601319a4f8edfb10a Mon Sep 17 00:00:00 2001 From: avokadoen Date: Tue, 8 Dec 2020 00:16:21 +0100 Subject: [PATCH 3/4] added zig day 3 to readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c062bc6f..11879b45 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,9 @@ Welcome to this community project, where we collaboratively solve the 2020 editi | deno.ts | **7** | 1 | 1 | 1 | 1 | 1 | 1 | 1 | | | |||||||||||||||| | c | **6** | 1 | 1 | 1 | 1 | 1 | 1 | | | | |||||||||||||||| | node.js | **4** | 1 | | | 1 | | 1 | 1 | | | |||||||||||||||| +| zig | **3** | 1 | 1 | 1 | | | | | | | |||||||||||||||| | c++ | **2** | 1 | 1 | | | | | | | | |||||||||||||||| | ruby | **2** | 1 | | | 1 | | | | | | |||||||||||||||| -| zig | **2** | 1 | 1 | | | | | | | | |||||||||||||||| | rust | **1** | 1 | | | | | | | | | |||||||||||||||| | bash | **0** | | | | | | | | | | |||||||||||||||| | java | **0** | | | | | | | | | | |||||||||||||||| From 659648c2c518dad497025ff8decae3dd23277cb5 Mon Sep 17 00:00:00 2001 From: avokadoen Date: Tue, 8 Dec 2020 00:29:32 +0100 Subject: [PATCH 4/4] Minor refactor of day03.zig --- days/day-03/solutions/day03.zig | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/days/day-03/solutions/day03.zig b/days/day-03/solutions/day03.zig index e727683b..b534ee45 100644 --- a/days/day-03/solutions/day03.zig +++ b/days/day-03/solutions/day03.zig @@ -2,7 +2,6 @@ const std = @import("std"); const mem = std.mem; const io = std.io; const ArrayList = std.ArrayList; -const Allocator = std.mem.Allocator; const MAX_FILE_SIZE = 20_000; @@ -52,11 +51,6 @@ const Map = struct { pub fn main() anyerror!void { - var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena.deinit(); - - const allocator = &arena.allocator; - const in = std.io.getStdIn().reader(); const stdout = std.io.getStdOut().writer(); @@ -69,4 +63,4 @@ pub fn main() anyerror!void { try stdout.print("{}\n", .{path_3_1}); try stdout.print("{}\n", .{map.inspectPath(1, 1) * path_3_1 * map.inspectPath(5, 1) * map.inspectPath(7, 1) * map.inspectPath(1, 2)}); -} \ No newline at end of file +}