const std = @import("std"); const path = "data/day13/input.txt"; const RetType = u7; const PointType = u11; const Point = [2]PointType; const Axis = enum(u1) { x, y }; const FoldInstruction = struct { axis: Axis, value: PointType, }; const Dots = std.AutoArrayHashMap(Point, void); const Folds = std.ArrayList(FoldInstruction); const Paper = struct { dots: Dots, folds: Folds, pub fn Fold(self: *@This(), a: std.mem.Allocator, axis: Axis, value: PointType) !void { var to_remove = std.ArrayList(Point).init(a); defer to_remove.deinit(); switch (axis) { .x => { for (self.dots.keys()) |item| { if (item[0] > value) { try to_remove.append(item); try self.dots.put(Point{ value - (item[0] - value), item[1] }, {}); } } }, .y => { for (self.dots.keys()) |item| { if (item[1] > value) { try to_remove.append(item); try self.dots.put(Point{ item[0], value - (item[1] - value) }, {}); } } }, } for (to_remove.items) |item| { _ = self.dots.swapRemove(item); } } }; fn parseInput(a: std.mem.Allocator) anyerror!Paper { const input = @embedFile(path); var lines = std.mem.split(u8, input, "\n"); var ret = Paper{ .dots = Dots.init(a), .folds = Folds.init(a), }; // read in coordinates while (lines.next()) |line| { if (line.len == 0) break; var coord = std.mem.tokenize(u8, line, ","); const x = try std.fmt.parseUnsigned(PointType, coord.next().?, 10); const y = try std.fmt.parseUnsigned(PointType, coord.next().?, 10); // std.debug.print("{s} {d} {d}\n", .{ line, x, y }); try ret.dots.put(Point{ x, y }, {}); } // parse fold instructions while (lines.next()) |foldline| { if (foldline.len == 0) break; var fold = std.mem.tokenize(u8, foldline, " "); _ = fold.next(); _ = fold.next(); var f = std.mem.tokenize(u8, fold.next().?, "="); const axis: Axis = if (std.mem.eql(u8, f.next().?, "x")) .x else .y; const value = try std.fmt.parseUnsigned(PointType, f.next().?, 10); // std.debug.print("{s} {d}\n", .{axis, value}); try ret.folds.append(FoldInstruction{ .axis = axis, .value = value }); } return ret; } pub fn second(allocator: ?std.mem.Allocator) anyerror!RetType { var p = try parseInput(allocator.?); defer { p.dots.deinit(); p.folds.deinit(); } for (p.folds.items) |fold| { try p.Fold(allocator.?, fold.axis, fold.value); } // var row: PointType = 0; // while (row < 7) : (row += 1) { // std.debug.print("\n", .{}); // var col: PointType = 0; // while (col < 50) : (col += 1) { // if (p.dots.contains(Point{ col, row })) { // std.debug.print("#", .{}); // } else { // std.debug.print(" ", .{}); // } // } // } return @intCast(RetType, p.dots.count()); } pub fn main() anyerror!void { var buf: [75_000]u8 = undefined; var fba = std.heap.FixedBufferAllocator.init(&buf); var timer = try std.time.Timer.start(); const ret = try second(fba.allocator()); const t = timer.lap() / 1000; try std.testing.expectEqual(@as(RetType, 103), ret); std.debug.print("Day 13b result: {d} \t\ttime: {d}us\n", .{ ret, t }); } test "day13b" { try std.testing.expectEqual(@as(RetType, 103), try second(std.testing.allocator)); }