diff --git a/native/solutions/2015/02/common.zig b/native/solutions/2015/02/common.zig new file mode 100644 index 0000000..469f1db --- /dev/null +++ b/native/solutions/2015/02/common.zig @@ -0,0 +1,64 @@ +const std = @import("std"); + +const Allocator = std.mem.Allocator; + +const BytesList = std.ArrayList(u8); + +pub fn Parser(comptime reduce: *const fn ([3]u32) u32) type { + return struct { + total: u32, + + data: [3]u32, + index: usize, + + buffer: BytesList, + + const Self = @This(); + + pub fn init(allocator: Allocator) Self { + return .{ + .total = 0, + + .data = .{ 0, 0, 0 }, + .index = 0, + + .buffer = BytesList.init(allocator), + }; + } + + pub fn write(self: *Self, byte: u8) !void { + return switch (byte) { + '0'...'9' => try self.buffer.append(byte), + 'x' => try self.flushDimension(), + '\n' => try self.flushTotal(), + else => error.InvalidInput, + }; + } + + fn flushDimension(self: *Self) !void { + if (self.buffer.items.len > 0) { + self.data[self.index] = try std.fmt.parseInt(u32, self.buffer.items, 10); + } + + self.index += 1; + + self.buffer.clearAndFree(); + } + + pub fn flushTotal(self: *Self) !void { + try self.flushDimension(); + + self.total += reduce(self.data); + + self.data[0] = 0; + self.data[1] = 0; + self.data[2] = 0; + + self.index = 0; + } + + pub fn deinit(self: *Self) void { + self.buffer.deinit(); + } + }; +} diff --git a/native/solutions/2015/02/part_1.zig b/native/solutions/2015/02/part_1.zig index 11cfcef..ca79fb8 100644 --- a/native/solutions/2015/02/part_1.zig +++ b/native/solutions/2015/02/part_1.zig @@ -1,85 +1,36 @@ const panic = @import("panic"); const std = @import("std"); +const common = @import("./common.zig"); + const Allocator = std.mem.Allocator; const AnyReader = std.io.AnyReader; -const BytesList = std.ArrayList(u8); - -const Parser = struct { - total: i32, - - data: [3]i32, - index: usize, +fn reduce(data: [3]u32) u32 { + const sqs = [3]u32{ + data[0] * data[1], + data[1] * data[2], + data[2] * data[0], + }; - buffer: BytesList, + const minSq = blk: { + var min = sqs[0]; - fn init(allocator: Allocator) Parser { - return .{ - .total = 0, - - .data = .{ 0, 0, 0 }, - .index = 0, - - .buffer = BytesList.init(allocator), - }; - } - - fn write(self: *Parser, byte: u8) !void { - return switch (byte) { - '0'...'9' => try self.buffer.append(byte), - 'x' => try self.flushDimension(), - '\n' => try self.flushTotal(), - else => error.InvalidInput, - }; - } - - fn flushDimension(self: *Parser) !void { - if (self.buffer.items.len > 0) { - self.data[self.index] = try std.fmt.parseInt(i32, self.buffer.items, 10); + if (sqs[1] < min) { + min = sqs[1]; } - self.index += 1; - - self.buffer.clearAndFree(); - } - - fn flushTotal(self: *Parser) !void { - try self.flushDimension(); - - const sqs = [3]i32{ - self.data[0] * self.data[1], - self.data[1] * self.data[2], - self.data[2] * self.data[0], - }; - - const minSq = blk: { - var min = sqs[0]; - - if (sqs[1] < min) { - min = sqs[1]; - } - - if (sqs[2] < min) { - min = sqs[2]; - } - - break :blk min; - }; - - self.total += 2 * sqs[0] + 2 * sqs[1] + 2 * sqs[2] + minSq; + if (sqs[2] < min) { + min = sqs[2]; + } - self.data[0] = 0; - self.data[1] = 0; - self.data[2] = 0; + break :blk min; + }; - self.index = 0; - } + return 2 * sqs[0] + 2 * sqs[1] + 2 * sqs[2] + minSq; +} - fn deinit(self: *Parser) void { - self.buffer.deinit(); - } -}; +const Parser = common.Parser(reduce); pub fn solve(allocator: Allocator, reader: AnyReader) ![]const u8 { var parser = Parser.init(allocator); diff --git a/native/solutions/2015/02/part_2.zig b/native/solutions/2015/02/part_2.zig index 0bf9fc8..36a8786 100644 --- a/native/solutions/2015/02/part_2.zig +++ b/native/solutions/2015/02/part_2.zig @@ -1,86 +1,35 @@ const panic = @import("panic"); const std = @import("std"); +const common = @import("./common.zig"); + const Allocator = std.mem.Allocator; const AnyReader = std.io.AnyReader; -const BytesList = std.ArrayList(u8); - -const Parser = struct { - total: i32, - - data: [3]i32, - index: usize, - - buffer: BytesList, - - fn init(allocator: Allocator) Parser { - return .{ - .total = 0, - - .data = .{ 0, 0, 0 }, - .index = 0, +fn reduce(data: [3]u32) u32 { + var ribbon: u32 = data[0] + data[1] + data[2]; - .buffer = BytesList.init(allocator), - }; - } - - fn write(self: *Parser, byte: u8) !void { - return switch (byte) { - '0'...'9' => try self.buffer.append(byte), - 'x' => try self.flushDimension(), - '\n' => try self.flushTotal(), - else => error.InvalidInput, - }; - } + const maxDs = blk: { + var max = data[0]; - fn flushDimension(self: *Parser) !void { - if (self.buffer.items.len > 0) { - self.data[self.index] = try std.fmt.parseInt(i32, self.buffer.items, 10); + if (data[1] > max) { + max = data[1]; } - self.index += 1; - - self.buffer.clearAndFree(); - } - - fn flushTotal(self: *Parser) !void { - try self.flushDimension(); - - var ribbon: i32 = self.data[0] + self.data[1] + self.data[2]; - - const maxDs = blk: { - var max = self.data[0]; - - if (self.data[1] > max) { - max = self.data[1]; - } - - if (self.data[2] > max) { - max = self.data[2]; - } - - break :blk max; - }; - - ribbon -= maxDs; - ribbon *= 2; - - ribbon += self.data[0] * self.data[1] * self.data[2]; + if (data[2] > max) { + max = data[2]; + } - self.total += ribbon; + break :blk max; + }; - self.data[0] = 0; - self.data[1] = 0; - self.data[2] = 0; + ribbon -= maxDs; + ribbon *= 2; - self.index = 0; - } + return ribbon + data[0] * data[1] * data[2]; +} - fn deinit(self: *Parser) void { - self.buffer.deinit(); - } -}; +const Parser = common.Parser(reduce); pub fn solve(allocator: Allocator, reader: AnyReader) ![]const u8 { var parser = Parser.init(allocator);