Compare commits
5 commits
b3f8ab19ff
...
2af1c7e03f
| Author | SHA1 | Date | |
|---|---|---|---|
| 2af1c7e03f | |||
| 0633ee80a9 | |||
| f088a5a21a | |||
| 393f80f314 | |||
| b55a6d61da |
2 changed files with 1265 additions and 2 deletions
|
|
@ -1,7 +1,240 @@
|
||||||
const std = @import("std");
|
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(usize, line[0..p], 10);
|
||||||
|
const height = try std.fmt.parseUnsigned(usize, 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var accumulator: usize = 0;
|
||||||
|
|
||||||
|
for (regions.items) |region| {
|
||||||
|
std.debug.print("{f}\n", .{region});
|
||||||
|
var area_needed: usize = 0;
|
||||||
|
for (region.required_presents, 0..) |amount, i| {
|
||||||
|
area_needed += amount * presents.items[i].area();
|
||||||
|
}
|
||||||
|
if (area_needed < region.area()) {
|
||||||
|
std.debug.print("{f}\nfits\n", .{region});
|
||||||
|
accumulator += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var buffer: [8]u8 = undefined;
|
||||||
|
var stdout_writer = std.fs.File.stdout().writer(&buffer);
|
||||||
|
const stdout = &stdout_writer.interface;
|
||||||
|
|
||||||
|
try stdout.print("{d}\n", .{accumulator});
|
||||||
|
|
||||||
|
try stdout.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn area(self: Self) usize {
|
||||||
|
return self.shape.count();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Region = struct {
|
||||||
|
width: usize,
|
||||||
|
height: usize,
|
||||||
|
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(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn createEmpty(self: Self, allocator: std.mem.Allocator) !EmptyRegion {
|
||||||
|
return try .init(allocator, self.width, self.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn area(self: Self) usize {
|
||||||
|
return self.width * self.height;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const EmptyRegion = struct {
|
||||||
|
grid: [][]bool,
|
||||||
|
filled_spaces: usize,
|
||||||
|
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
pub fn init(allocator: std.mem.Allocator, width: u8, height: u8) !Self {
|
||||||
|
const h = try allocator.alloc([]bool, height);
|
||||||
|
for (0..height) |i| {
|
||||||
|
const w = try allocator.alloc(u8, width);
|
||||||
|
@memset(w, false);
|
||||||
|
h[i] = w;
|
||||||
|
}
|
||||||
|
return .{
|
||||||
|
.grid = h,
|
||||||
|
.filled_spaces = 0,
|
||||||
|
.allocator = allocator,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: Self) void {
|
||||||
|
for (self.grid) |row| {
|
||||||
|
self.allocator.free(row);
|
||||||
|
}
|
||||||
|
self.allocator.free(self.grid);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fits(self: Self, present: Present) bool {
|
||||||
|
std.debug.assert(self.grid.len > 0);
|
||||||
|
const size = self.grid.len * self.grid[0].len;
|
||||||
|
if ((size - self.filled_spaces) < present.shape.count()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Implementation
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
||||||
1030
src/days/input/day12.txt
Executable file
1030
src/days/input/day12.txt
Executable file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue