WIP: implement part 1

This commit is contained in:
ktkk 2025-12-12 11:02:47 +00:00
parent 524b451399
commit b55a6d61da
2 changed files with 1198 additions and 2 deletions

View file

@ -1,7 +1,173 @@
const std = @import("std");
pub const title = "Day 12";
pub const title = "Day 12: Christmas Tree Farm";
pub fn run(_: std.mem.Allocator) !void {
pub fn run(allocator: std.mem.Allocator) !void {
//const input = @embedFile("./input/day12.txt");
const input =
\\0:
\\###
\\##.
\\##.
\\
\\1:
\\###
\\##.
\\.##
\\
\\2:
\\.##
\\###
\\##.
\\
\\3:
\\##.
\\###
\\##.
\\
\\4:
\\###
\\#..
\\###
\\
\\5:
\\###
\\.#.
\\###
\\
\\4x4: 0 0 0 0 2 0
\\12x5: 1 0 1 0 2 2
\\12x5: 1 0 1 0 3 2
;
var lines = std.mem.tokenizeScalar(u8, input, '\n');
var presents: std.ArrayList(Present) = .empty;
defer presents.deinit(allocator);
var regions: std.ArrayList(Region) = .empty;
defer {
for (regions.items) |region| {
region.deinit(allocator);
}
regions.deinit(allocator);
}
while (lines.next()) |line| {
var semicolon_pos: usize = 0;
var x_pos: ?usize = null;
for (line, 0..) |c, i| {
switch (c) {
'x' => x_pos = i,
':' => {
semicolon_pos = i;
break;
},
else => {},
}
}
if (semicolon_pos != 0) {
if (x_pos) |p| {
// region
const width = try std.fmt.parseUnsigned(u8, line[0..p], 10);
const height = try std.fmt.parseUnsigned(u8, line[p + 1..semicolon_pos], 10);
var required_presents: std.ArrayList(u8) = .empty;
defer required_presents.deinit(allocator);
if (presents.items.len > 0) {
try required_presents.ensureTotalCapacity(allocator, presents.items.len);
}
var presents_iter = std.mem.tokenizeScalar(u8, line[semicolon_pos + 2..], ' ');
while (presents_iter.next()) |present| {
const amount = try std.fmt.parseUnsigned(u8, present, 10);
try required_presents.append(allocator, amount);
}
const required_presents_slice = try required_presents.toOwnedSlice(allocator);
errdefer allocator.free(required_presents_slice);
const region: Region = .{
.width = width,
.height = height,
.required_presents = required_presents_slice,
};
try regions.append(allocator, region);
} else {
// present
var present: Present = .{
.shape = .initEmpty(),
};
for (0..Present.Width) |y| {
const l = lines.next() orelse unreachable;
for (0..Present.Width) |x| {
if (l[x] == '#') {
present.set(x, y);
}
}
}
try presents.append(allocator, present);
}
}
}
for (presents.items, 0..) |present, i| {
std.debug.print("{d}:\n{f}\n\n", .{i, present});
}
for (regions.items) |region| {
std.debug.print("{f}\n", .{region});
}
}
const Present = struct {
shape: std.bit_set.IntegerBitSet(Width * Width),
const Width = 3;
const Self = @This();
pub fn format(self: Self, w: *std.Io.Writer) std.Io.Writer.Error!void {
for (0..Width) |y| {
for (0..Width) |x| {
try w.writeByte(if (self.isSet(x, y)) '#' else '.');
}
if (y < Width - 1) {
try w.writeByte('\n');
}
}
}
pub fn set(self: *Self, x: usize, y: usize) void {
const index = (y * Width) + x;
self.shape.set(index);
}
pub fn isSet(self: Self, x: usize, y: usize) bool {
const index = (y * Width) + x;
return self.shape.isSet(index);
}
};
const Region = struct {
width: u8,
height: u8,
required_presents: []u8,
const Self = @This();
pub fn deinit(self: Self, allocator: std.mem.Allocator) void {
allocator.free(self.required_presents);
}
pub fn format(self: Self, w: *std.Io.Writer) std.Io.Writer.Error!void {
try w.print("{d}x{d}: ", .{self.width, self.height});
for (self.required_presents, 0..) |present, i| {
try w.print("{d}", .{present});
if (i < self.required_presents.len - 1) {
try w.writeByte(' ');
}
}
}
};