WIP: implement part 2

This commit is contained in:
ktkk 2025-12-09 16:32:37 +00:00
parent 1d6cdccaf8
commit 605b5ee85a

View file

@ -3,24 +3,26 @@ const std = @import("std");
pub const title = "Day 09: Movie Theater"; pub const title = "Day 09: Movie Theater";
pub fn run(allocator: std.mem.Allocator) !void { pub fn run(allocator: std.mem.Allocator) !void {
const input = @embedFile("./input/day09.txt"); //const input = @embedFile("./input/day09.txt");
//const input = const input =
// \\7,1 \\7,1
// \\11,1 \\11,1
// \\11,7 \\11,7
// \\9,7 \\9,7
// \\9,5 \\9,5
// \\2,5 \\2,5
// \\2,3 \\2,3
// \\7,3 \\7,3
// ; ;
var lines = std.mem.tokenizeScalar(u8, input, '\n'); var lines = std.mem.tokenizeScalar(u8, input, '\n');
var tiles: std.ArrayList(Tile) = .empty; var tiles: std.ArrayList(Tile) = .empty;
defer tiles.deinit(allocator); defer tiles.deinit(allocator);
var index: usize = 0;
while (lines.next()) |line| { while (lines.next()) |line| {
defer index += 1;
var coordinates = std.mem.tokenizeScalar(u8, line, ','); var coordinates = std.mem.tokenizeScalar(u8, line, ',');
const x = blk: { const x = blk: {
const s = coordinates.next() orelse continue; const s = coordinates.next() orelse continue;
@ -30,20 +32,53 @@ pub fn run(allocator: std.mem.Allocator) !void {
const s = coordinates.next() orelse continue; const s = coordinates.next() orelse continue;
break :blk try std.fmt.parseUnsigned(u64, s, 10); 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_area: usize = 0;
var largest_rectangle: Rectangle = undefined; var largest_rectangle: Rectangle = undefined;
for (tiles.items, 0..) |first_tile, i| { for (tiles.items, 0..) |first_tile, i| {
if (i == 0) continue;
for (tiles.items[i + 1..]) |second_tile| { for (tiles.items[i + 1..]) |second_tile| {
const rectangle = first_tile.rectangle(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(); const area = rectangle.area();
if (area > largest_area) { if (area > largest_area) {
largest_area = area; largest_area = area;
largest_rectangle = rectangle; largest_rectangle = rectangle;
} }
} }
break;
} }
std.debug.print("rectangle = {f}\n", .{largest_rectangle}); std.debug.print("rectangle = {f}\n", .{largest_rectangle});
@ -58,6 +93,7 @@ pub fn run(allocator: std.mem.Allocator) !void {
} }
const Tile = struct { const Tile = struct {
index: usize,
pos: @Vector(2, u64), pos: @Vector(2, u64),
const Self = @This(); const Self = @This();
@ -67,20 +103,52 @@ const Tile = struct {
} }
pub fn rectangle(self: Self, other_corner: Self) Rectangle { 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 { const Rectangle = struct {
a: Tile, a: Tile,
b: Tile, b: Tile,
c: @Vector(2, u64),
d: @Vector(2, u64),
const Self = @This(); const Self = @This();
pub fn format(self: Self, w: *std.io.Writer) std.io.Writer.Error!void { pub fn format(self: Self, w: *std.io.Writer) std.io.Writer.Error!void {
try w.print("{f} to {f}", .{self.a, self.b}); 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 { pub fn area(self: Self) u64 {
const cond = self.a.pos > self.b.pos; const cond = self.a.pos > self.b.pos;
const high = @select(u64, cond, self.a.pos, self.b.pos); const high = @select(u64, cond, self.a.pos, self.b.pos);