diff --git a/src/days/day09.zig b/src/days/day09.zig index 0a0044b..b51820c 100644 --- a/src/days/day09.zig +++ b/src/days/day09.zig @@ -3,24 +3,26 @@ const std = @import("std"); pub const title = "Day 09: Movie Theater"; pub fn run(allocator: std.mem.Allocator) !void { - const input = @embedFile("./input/day09.txt"); - //const input = - // \\7,1 - // \\11,1 - // \\11,7 - // \\9,7 - // \\9,5 - // \\2,5 - // \\2,3 - // \\7,3 - // ; + //const input = @embedFile("./input/day09.txt"); + const input = + \\7,1 + \\11,1 + \\11,7 + \\9,7 + \\9,5 + \\2,5 + \\2,3 + \\7,3 + ; var lines = std.mem.tokenizeScalar(u8, input, '\n'); var tiles: std.ArrayList(Tile) = .empty; defer tiles.deinit(allocator); + var index: usize = 0; while (lines.next()) |line| { + defer index += 1; var coordinates = std.mem.tokenizeScalar(u8, line, ','); const x = blk: { const s = coordinates.next() orelse continue; @@ -30,20 +32,53 @@ pub fn run(allocator: std.mem.Allocator) !void { const s = coordinates.next() orelse continue; break :blk try std.fmt.parseUnsigned(u64, s, 10); }; - try tiles.append(allocator, .{ .pos = .{ x, y } }); + try tiles.append(allocator, .{ .index = index, .pos = .{ x, y } }); + } + + const width = 14; + const height = 9; + for (0..height) |y| { + var buffer: [width]u8 = [_]u8{'.'} ** width; + for (0..width) |x| { + for (tiles.items) |tile| { + if (@reduce(.And, tile.pos == @Vector(2, u64){ x, y })) { + buffer[x] = 'X'; + } + } + } + std.debug.print("{s}\n", .{buffer}); } var largest_area: usize = 0; var largest_rectangle: Rectangle = undefined; for (tiles.items, 0..) |first_tile, i| { + if (i == 0) continue; for (tiles.items[i + 1..]) |second_tile| { const rectangle = first_tile.rectangle(second_tile); + const w = rectangle.width(); + const h = rectangle.height(); + std.debug.print("rectangle {d}-{d}\n", .{rectangle.a.index, rectangle.b.index}); + std.debug.print("width = {d}, height = {d}\n", .{w, h}); + + if (w != 1 and h != 1) { + var verts_outside: bool = false; + for (tiles.items[first_tile.index + 1..second_tile.index]) |between| { + const cond = rectangle.c > between.pos; + if (@reduce(.Or, cond)) { + std.debug.print("vert c ({any}) of rect {d}-{d} is outside the shape\n", .{rectangle.c, rectangle.a.index, rectangle.b.index}); + verts_outside = true; + break; + } + } + } + const area = rectangle.area(); if (area > largest_area) { largest_area = area; largest_rectangle = rectangle; } } + break; } std.debug.print("rectangle = {f}\n", .{largest_rectangle}); @@ -58,6 +93,7 @@ pub fn run(allocator: std.mem.Allocator) !void { } const Tile = struct { + index: usize, pos: @Vector(2, u64), const Self = @This(); @@ -67,20 +103,52 @@ const Tile = struct { } pub fn rectangle(self: Self, other_corner: Self) Rectangle { - return .{ .a = self, .b = other_corner }; + const a = self; + const b = other_corner; + return .{ + .a = a, + .b = b, + .c = .{ b.pos[0], a.pos[1] }, + .d = .{ a.pos[0], b.pos[1] }, + }; } }; +/// 0,0 1,0 +/// a ---- c +/// | | +/// | | +/// d ---- b +/// 0,1 1,1 const Rectangle = struct { a: Tile, b: Tile, + c: @Vector(2, u64), + d: @Vector(2, u64), + const Self = @This(); pub fn format(self: Self, w: *std.io.Writer) std.io.Writer.Error!void { try w.print("{f} to {f}", .{self.a, self.b}); } + pub fn width(self: Self) u64 { + const cond = self.a.pos > self.b.pos; + const high = @select(u64, cond, self.a.pos, self.b.pos); + const low = @select(u64, !cond, self.a.pos, self.b.pos); + const diff = high - low; + return diff[0] + 1; + } + + pub fn height(self: Self) u64 { + const cond = self.a.pos > self.b.pos; + const high = @select(u64, cond, self.a.pos, self.b.pos); + const low = @select(u64, !cond, self.a.pos, self.b.pos); + const diff = high - low; + return diff[1] + 1; + } + pub fn area(self: Self) u64 { const cond = self.a.pos > self.b.pos; const high = @select(u64, cond, self.a.pos, self.b.pos);