From d9d870306c29428bf123c1caa8a82a9a259b58e6 Mon Sep 17 00:00:00 2001 From: Julien Dessaux Date: Tue, 13 Dec 2022 17:41:44 +0100 Subject: 2022-13 in zig --- 2022/13-distress-signal/first.zig | 155 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 2022/13-distress-signal/first.zig (limited to '2022/13-distress-signal/first.zig') diff --git a/2022/13-distress-signal/first.zig b/2022/13-distress-signal/first.zig new file mode 100644 index 0000000..3559e61 --- /dev/null +++ b/2022/13-distress-signal/first.zig @@ -0,0 +1,155 @@ +const std = @import("std"); + +const example = @embedFile("example"); +const input = @embedFile("input"); + +var allocator: std.mem.Allocator = undefined; + +pub fn main() anyerror!void { + var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); + defer arena.deinit(); + allocator = arena.allocator(); + + try std.testing.expectEqual(try solve(example), 13); + const result = try solve(input); + try std.io.getStdOut().writer().print("{}\n", .{result}); +} + +const ListErrors = error{ + OutOfMemory, +}; + +const List = struct { + data: std.ArrayList(Elt), + fn init(reader: anytype) !*List { + var l = try allocator.create(List); + l.data = std.ArrayList(Elt).init(allocator); + while (true) { + const c = reader.readByte() catch break; + switch (c) { + '[' => { + var e = try l.data.addOne(); + e.* = Elt{ .list = try List.init(reader) }; + }, + ']' => { + return l; + }, + ',' => { // comma after a list ending, ignore + }, + else => { // a digit + var e = try l.data.addOne(); + e.* = Elt{ .int = c - '0' }; + while (true) { + const d = reader.readByte() catch unreachable; + if (d == ']') { + return l; + } else if (d == ',') { + break; + } + e.int = e.int * 10 + d; + } + }, + } + } + return l; + } + fn initSingleton(n: u8) !*List { + var l = try allocator.create(List); + l.data = std.ArrayList(Elt).init(allocator); + var e = try l.data.addOne(); + e.* = Elt{ .int = n }; + return l; + } + fn isLowerThan(l: *List, o: *List) ListErrors!?bool { + var i: usize = 0; + while (true) : (i += 1) { + if (o.len() <= i) { + if (l.len() <= i) { + return null; + } + return false; + } + if (l.len() <= i) { + return true; + } + const t = try l.data.items[i].isLowerThan(&(o.data.items[i])); + if (t != null) { + return t; + } + } + } + inline fn len(l: *List) usize { + return l.data.items.len; + } + fn print(l: *List) void { + for (l.data.items) |e| { + switch (e) { + Elt.int => |i| std.debug.print("{d} ", .{i}), + Elt.list => |o| { + std.debug.print("[", .{}); + o.print(); + std.debug.print("]", .{}); + }, + } + } + } +}; + +const EltType = enum { + int, + list, +}; + +const Elt = union(EltType) { + int: u8, + list: *List, + fn isLowerThan(e: *Elt, f: *Elt) !?bool { + switch (e.*) { + Elt.int => |i| switch (f.*) { + Elt.int => |j| { + if (i == j) { + return null; + } + return i < j; + }, + Elt.list => |o| { + var l = try List.initSingleton(i); + return l.isLowerThan(o); + }, + }, + Elt.list => |l| switch (f.*) { + Elt.int => |j| { + f.* = Elt{ .list = try List.initSingleton(j) }; + return e.isLowerThan(f); + }, + Elt.list => |o| { + return l.isLowerThan(o); + }, + }, + } + } +}; + +fn solve(puzzle: []const u8) !u64 { + var it = std.mem.tokenize(u8, puzzle, "\n"); + var i: usize = 1; + var tot: usize = 0; + while (it.next()) |line| { + var firstLine = std.io.fixedBufferStream(line); + var first = try List.init(firstLine.reader()); + var secondLine = std.io.fixedBufferStream(it.next() orelse unreachable); + var second = try List.init(secondLine.reader()); + const t = try first.isLowerThan(second); + //first.print(); + //std.debug.print("\n", .{}); + //second.print(); + //std.debug.print("\n{d}: {?}\n", .{ i, t }); + if (t) |s| { + if (s) { + tot += i; + } + } + i += 1; + } + return tot; +} -- cgit v1.2.3