diff --git a/src/days/day09.zig b/src/days/day09.zig index 5b8cfab..c167255 100644 --- a/src/days/day09.zig +++ b/src/days/day09.zig @@ -1,7 +1,242 @@ const std = @import("std"); -pub const title = "Day 09"; +pub const title = "Day 09: Movie Theater"; -pub fn run(_: std.mem.Allocator) !void { +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 + // ; + + var lines = std.mem.tokenizeScalar(u8, input, '\n'); + + var tiles: std.ArrayList(Tile) = .empty; + defer tiles.deinit(allocator); + + std.debug.print("parsing tiles...\n", .{}); + 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; + break :blk try std.fmt.parseUnsigned(u64, s, 10); + }; + const y = blk: { + const s = coordinates.next() orelse continue; + break :blk try std.fmt.parseUnsigned(u64, s, 10); + }; + try tiles.append(allocator, .{ .index = index, .pos = .{ x, y } }); + } + + std.debug.print("calculating edges...\n", .{}); + var edges: std.ArrayList(Edge) = .empty; + defer edges.deinit(allocator); + for (tiles.items, 0..) |tile, i| { + const a = tile; + const b = if (i == tiles.items.len - 1) tiles.items[0] else tiles.items[i + 1]; + try edges.append(allocator, Edge.fromTiles(a, b)); + } + + std.debug.print("finding largest rectangle...\n", .{}); + var largest_area: usize = 0; + var largest_rectangle: Rectangle = undefined; + for (tiles.items, 0..) |first_tile, i| { + inner: for (tiles.items[i + 1..]) |second_tile| { + const rectangle = first_tile.rectangle(second_tile); + + std.debug.print("checking rectangle {f}...\n", .{rectangle}); + + const has_inside = rectangle.width() >= 3 and rectangle.height() >= 3; + if (has_inside) { + const one: @Vector(2, u64) = @splat(1); + const top_left = rectangle.topLeft() + one; + const bottom_right = rectangle.bottomRight() - one; + edge_loop: for (edges.items) |edge| { + if (edge.direction == .horizontal) { + if (edge.a.pos[1] < top_left[1] or edge.a.pos[1] > bottom_right[1]) { + continue :edge_loop; + } + + const start, const end = if (edge.a.pos[0] < edge.b.pos[0] + 1) .{ edge.a.pos[0], edge.b.pos[0] } else .{ edge.b.pos[0], edge.a.pos[0] + 1 }; + for (start..end) |ex| { + const edge_tile: @Vector(2, u64) = .{ ex, edge.a.pos[1] }; + if (top_left[0] <= edge_tile[0] and edge_tile[0] <= bottom_right[0]) { + std.debug.print("rectangle {f} hits edge {f}\n", .{rectangle, edge}); + continue :inner; + } + } + } else { + if (edge.a.pos[0] < top_left[0] or edge.a.pos[0] > bottom_right[0]) { + continue :edge_loop; + } + + const start, const end = if (edge.a.pos[1] < edge.b.pos[1] + 1) .{ edge.a.pos[1], edge.b.pos[1] } else .{ edge.b.pos[1], edge.a.pos[1] + 1 }; + for (start..end) |ey| { + const edge_tile: @Vector(2, u64) = .{ edge.a.pos[0], ey }; + if (top_left[1] <= edge_tile[1] and edge_tile[1] <= bottom_right[1]) { + std.debug.print("rectangle {f} hits edge {f}\n", .{rectangle, edge}); + continue :inner; + } + } + } + } + } + + const area = rectangle.area(); + if (area > largest_area) { + largest_area = area; + largest_rectangle = rectangle; + } + } + } + + std.debug.print("rectangle = {f}\n", .{largest_rectangle}); + std.debug.print("top_left = {any}, bottom_right = {any}\n", .{largest_rectangle.topLeft(), largest_rectangle.bottomRight()}); + + var buffer: [64]u8 = undefined; + var stdout_writer = std.fs.File.stdout().writer(&buffer); + const stdout = &stdout_writer.interface; + + try stdout.print("{d}\n", .{largest_area}); + + try stdout.flush(); } +const Tile = struct { + index: usize, + pos: @Vector(2, u64), + + const Self = @This(); + + pub fn format(self: Self, w: *std.io.Writer) std.io.Writer.Error!void { + try w.print("{d},{d}", .{self.pos[0], self.pos[1]}); + } + + pub fn rectangle(self: Self, other_corner: Self) Rectangle { + return Rectangle.fromTiles(self, other_corner); + } +}; + +const Edge = struct { + a: Tile, + b: Tile, + + direction: Direction, + + const Self = @This(); + + const Direction = enum { + horizontal, + vertical, + }; + + pub fn fromTiles(a: Tile, b: Tile) Self { + const direction: Direction = if (a.pos[0] == b.pos[0]) + .vertical + else if (a.pos[1] == b.pos[1]) + .horizontal + else + unreachable; + + return .{ + .a = a, + .b = b, + .direction = direction, + }; + } + + pub fn format(self: Self, w: *std.io.Writer) std.io.Writer.Error!void { + try w.print("{f} - {f}", .{self.a, self.b}); + } +}; + +/// 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 fromTiles(a: Tile, b: Tile) Self { + const cx = if (a.pos[0] <= b.pos[0]) b.pos[0] else a.pos[0]; + const cy = if (a.pos[1] >= b.pos[1]) a.pos[1] else b.pos[1]; + const dx = if (a.pos[0] <= b.pos[0]) a.pos[0] else b.pos[0]; + const dy = if (a.pos[1] >= b.pos[1]) b.pos[1] else a.pos[1]; + return .{ + .a = a, + .b = b, + .c = .{ cx, cy }, + .d = .{ dx, dy }, + }; + } + + pub fn format(self: Self, w: *std.io.Writer) std.io.Writer.Error!void { + try w.print("{d} to {d} ({f} - {d},{d} - {f} - {d},{d})", .{self.a.index, self.b.index, self.a, self.c[0], self.c[1], self.b, self.d[0], self.d[1]}); + } + + pub fn topLeft(self: Self) @Vector(2, u64) { + const verts = [_]@Vector(2, u64){ self.c, self.b.pos, self.d }; + var top_left: @Vector(2, u64) = self.a.pos; + for (verts) |vert| { + const cond = vert <= top_left; + if (@reduce(.And, cond)) { + top_left = vert; + } + } + return top_left; + } + + pub fn bottomRight(self: Self) @Vector(2, u64) { + const verts = [_]@Vector(2, u64){ self.d, self.a.pos, self.c }; + var bottom_right: @Vector(2, u64) = self.b.pos; + for (verts) |vert| { + const cond = vert >= bottom_right; + if (@reduce(.And, cond)) { + bottom_right = vert; + } + } + return bottom_right; + } + + 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); + const low = @select(u64, !cond, self.a.pos, self.b.pos); + const diff = high - low; + const one: @Vector(2, u64) = @splat(1); + return @reduce(.Mul, diff + one); + } +}; + diff --git a/src/days/input/day09.txt b/src/days/input/day09.txt new file mode 100755 index 0000000..44cac4b --- /dev/null +++ b/src/days/input/day09.txt @@ -0,0 +1,496 @@ +98241,50245 +98241,51464 +98122,51464 +98122,52660 +97649,52660 +97649,53867 +97585,53867 +97585,55104 +97774,55104 +97774,56255 +97196,56255 +97196,57546 +97636,57546 +97636,58780 +97591,58780 +97591,59958 +97238,59958 +97238,61063 +96596,61063 +96596,62184 +96091,62184 +96091,63423 +96024,63423 +96024,64739 +96152,64739 +96152,65592 +94869,65592 +94869,66846 +94784,66846 +94784,67925 +94219,67925 +94219,69237 +94206,69237 +94206,70195 +93369,70195 +93369,71228 +92725,71228 +92725,72421 +92396,72421 +92396,73353 +91573,73353 +91573,74531 +91190,74531 +91190,75402 +90295,75402 +90295,76446 +89686,76446 +89686,77385 +88921,77385 +88921,78413 +88284,78413 +88284,79671 +87931,79671 +87931,80568 +87102,80568 +87102,81220 +85994,81220 +85994,82478 +85581,82478 +85581,83480 +84863,83480 +84863,83949 +83605,83949 +83605,84603 +82559,84603 +82559,85593 +81829,85593 +81829,86686 +81171,86686 +81171,87253 +80061,87253 +80061,87969 +79082,87969 +79082,88669 +78093,88669 +78093,89502 +77196,89502 +77196,90250 +76233,90250 +76233,91130 +75347,91130 +75347,91250 +74000,91250 +74000,92327 +73212,92327 +73212,92894 +72128,92894 +72128,93270 +70952,93270 +70952,93370 +69660,93370 +69660,94478 +68819,94478 +68819,94708 +67595,94708 +67595,95183 +66472,95183 +66472,95207 +65195,95207 +65195,96147 +64221,96147 +64221,96615 +63081,96615 +63081,96461 +61777,96461 +61777,97201 +60700,97201 +60700,97015 +59412,97015 +59412,97740 +58305,97740 +58305,97562 +57038,97562 +57038,97176 +55764,97176 +55764,97302 +54566,97302 +54566,97656 +53385,97656 +53385,98146 +52195,98146 +52195,97889 +50969,97889 +50969,97871 +49756,97871 +49756,97859 +48543,97859 +48543,97449 +47351,97449 +47351,97738 +46119,97738 +46119,97642 +44909,97642 +44909,97226 +43740,97226 +43740,97219 +42519,97219 +42519,96788 +41367,96788 +41367,97309 +40026,97309 +40026,96882 +38868,96882 +38868,96221 +37780,96221 +37780,95804 +36640,95804 +36640,96136 +35265,96136 +35265,95792 +34086,95792 +34086,94892 +33112,94892 +33112,94733 +31866,94733 +31866,94172 +30777,94172 +30777,93317 +29828,93317 +29828,92857 +28705,92857 +28705,92156 +27705,92156 +27705,91484 +26696,91484 +26696,91543 +25258,91543 +25258,90924 +24200,90924 +24200,90213 +23201,90213 +23201,89043 +22528,89043 +22528,88927 +21108,88927 +21108,88089 +20204,88089 +20204,87315 +19255,87315 +19255,86250 +18557,86250 +18557,85773 +17347,85773 +17347,84679 +16696,84679 +16696,83809 +15843,83809 +15843,82679 +15268,82679 +15268,82055 +14153,82055 +14153,81303 +13157,81303 +13157,80213 +12558,80213 +12558,79102 +12004,79102 +12004,78475 +10804,78475 +10804,76971 +10824,76971 +10824,76102 +9952,76102 +9952,75038 +9369,75038 +9369,74238 +8339,74238 +8339,72905 +8231,72905 +8231,71987 +7378,71987 +7378,70721 +7205,70721 +7205,69997 +5885,69997 +5885,68793 +5582,68793 +5582,67760 +4871,67760 +4871,66522 +4679,66522 +4679,65214 +4737,65214 +4737,64207 +3895,64207 +3895,62932 +3915,62932 +3915,61848 +3259,61848 +3259,60571 +3366,60571 +3366,59436 +2864,59436 +2864,58155 +3122,58155 +3122,57084 +2124,57084 +2124,55838 +2213,55838 +2213,54652 +1807,54652 +1807,53424 +1794,53424 +1794,52197 +1810,52197 +1810,50973 +1890,50973 +1890,50228 +94822,50228 +94822,48525 +1557,48525 +1557,47341 +2383,47341 +2383,46107 +2110,46107 +2110,44867 +1961,44867 +1961,43734 +2727,43734 +2727,42467 +2452,42467 +2452,41283 +2754,41283 +2754,40077 +2933,40077 +2933,38872 +3134,38872 +3134,37713 +3522,37713 +3522,36439 +3506,36439 +3506,35262 +3852,35262 +3852,34252 +4684,34252 +4684,33262 +5505,33262 +5505,32101 +5846,32101 +5846,31022 +6392,31022 +6392,29688 +6381,29688 +6381,28480 +6689,28480 +6689,27621 +7685,27621 +7685,26247 +7715,26247 +7715,25643 +9102,25643 +9102,24398 +9389,24398 +9389,23514 +10255,23514 +10255,22573 +11021,22573 +11021,21166 +11150,21166 +11150,20538 +12337,20538 +12337,19792 +13336,19792 +13336,18451 +13627,18451 +13627,17941 +14878,17941 +14878,16560 +15179,16560 +15179,15977 +16322,15977 +16322,14917 +16989,14917 +16989,14500 +18254,14500 +18254,13050 +18605,13050 +18605,12768 +19956,12768 +19956,11585 +20576,11585 +20576,11164 +21786,11164 +21786,10359 +22708,10359 +22708,9858 +23836,9858 +23836,8777 +24596,8777 +24596,8258 +25713,8258 +25713,7978 +26955,7978 +26955,7540 +28095,7540 +28095,6507 +28940,6507 +28940,6682 +30363,6682 +30363,6251 +31489,6251 +31489,5782 +32598,5782 +32598,4548 +33429,4548 +33429,4750 +34790,4750 +34790,4015 +35829,4015 +35829,4049 +37104,4049 +37104,3690 +38261,3690 +38261,2708 +39279,2708 +39279,3314 +40653,3314 +40653,2568 +41748,2568 +41748,2300 +42941,2300 +42941,2002 +44135,2002 +44135,2479 +45412,2479 +45412,1845 +46579,1845 +46579,2346 +47826,2346 +47826,2049 +49029,2049 +49029,2462 +50242,2462 +50242,2326 +51451,2326 +51451,1711 +52695,1711 +52695,1956 +53904,1956 +53904,1808 +55148,1808 +55148,2309 +56320,2309 +56320,3006 +57444,3006 +57444,3165 +58640,3165 +58640,3456 +59812,3456 +59812,3478 +61045,3478 +61045,3412 +62316,3412 +62316,4049 +63401,4049 +63401,4368 +64572,4368 +64572,4266 +65892,4266 +65892,5403 +66775,5403 +66775,5880 +67884,5880 +67884,6132 +69090,6132 +69090,6792 +70119,6792 +70119,6784 +71472,6784 +71472,7784 +72326,7784 +72326,8026 +73577,8026 +73577,8876 +74490,8876 +74490,8978 +75860,8978 +75860,9930 +76701,9930 +76701,10352 +77896,10352 +77896,11232 +78772,11232 +78772,11817 +79867,11817 +79867,12626 +80792,12626 +80792,14062 +81171,14062 +81171,14424 +82471,14424 +82471,15055 +83557,15055 +83557,16158 +84188,16158 +84188,16772 +85314,16772 +85314,18188 +85573,18188 +85573,18598 +86957,18598 +86957,19899 +87301,19899 +87301,20942 +87937,20942 +87937,21902 +88675,21902 +88675,22692 +89662,22692 +89662,23972 +89932,23972 +89932,24741 +90987,24741 +90987,25832 +91538,25832 +91538,27127 +91708,27127 +91708,28094 +92461,28094 +92461,29086 +93191,29086 +93191,30203 +93671,30203 +93671,31293 +94211,31293 +94211,32525 +94402,32525 +94402,33715 +94665,33715 +94665,34739 +95400,34739 +95400,35775 +96158,35775 +96158,36914 +96627,36914 +96627,38153 +96733,38153 +96733,39465 +96473,39465 +96473,40509 +97404,40509 +97404,41858 +96797,41858 +96797,42955 +97601,42955 +97601,44214 +97352,44214 +97352,45389 +97756,45389 +97756,46601 +97847,46601 +97847,47809 +98021,47809 +98021,49037 +97534,49037 +97534,50245