542KFIY2VRSIP2HN5CDBSBA6G7CAZCU5WTB6THZP5IWZKU34OZBAC
fn bigImage(self: @This()) [8 * SIZE][8 * SIZE]bool {
var ret: [8 * SIZE][8 * SIZE]bool = undefined;
for (self.order.items) |oidx, i| {
const start_row = i / SIZE * 8;
const start_col = i % SIZE * 8;
// std.debug.print("idx: {d} srow: {d} scol: {d}\n", .{oidx, start_row, start_col});
for (self.tiles[oidx].data) |line, row| {
if (row == 0 or row == 9) continue;
for (line[1..9]) |item, col| {
ret[start_row + row - 1][start_col + col] = item;
}
}
}
return ret;
}
fn bigRotate(big: [8 * SIZE][8 * SIZE]bool) [8 * SIZE][8 * SIZE]bool {
var rotated: [8 * SIZE][8 * SIZE]bool = undefined;
for (big) |line, row| {
for (line) |item, col| {
rotated[big.len - 1 - col][row] = item;
}
}
return rotated;
}
fn bigFlip(big: [8 * SIZE][8 * SIZE]bool, axis: u1) [8 * SIZE][8 * SIZE]bool {
var flipped: [8 * SIZE][8 * SIZE]bool = undefined;
switch (axis) {
0 => return big,
1 => {
// horizontal flip
for (big) |slice, row| {
flipped[big.len - 1 - row] = slice;
}
},
}
return flipped;
}
_ = allocator;
return 0;
var image = Image{
.tiles = undefined,
.visited = std.AutoHashMap(u16, void).init(allocator.?),
.order = std.ArrayList(usize).init(allocator.?),
};
image.tiles = try parseInput(allocator.?, @embedFile(PATH));
defer {
allocator.?.free(image.tiles);
image.visited.deinit();
image.order.deinit();
}
image.size = @intCast(u8, std.math.sqrt(image.tiles.len / 8));
if (!image.solve()) unreachable;
var big = image.bigImage();
var monsters: usize = 0;
var habitat: usize = 0;
for ([_]u1{ 0, 1 }) |flip| {
big = bigFlip(big, flip);
for ([_]u2{ 0, 1, 2, 3 }) |rotate| {
big = bigRotate(big);
// Monster search...
for (big) |line, row| {
ears: for (line) |item, col| {
if (flip == 0 and rotate == 0 and item == true) habitat += 1;
// ear is on .{-1, 18}
if (col < 18) continue;
// after ear we move one right
if (col >= big.len - 1) continue;
// after ear we move two down
if (row >= big.len - 2) continue;
if (item == true) {
const tailRow = row + 1;
const tailCol = col - 18;
for (monster_offsets) |diff| {
if (big[tailRow + diff[0]][tailCol + diff[1]] != true) continue :ears;
}
monsters += 1;
}
}
}
if (monsters > 0) return habitat - monsters * 15;
}
}
unreachable;
// O
// X ## ## ###
// # # # # # #
//
// check for ears (marked with O first), then move .{1, -18} to tail (marked with X)
// and try these positions...
// zig fmt: off
const monster_offsets = [_][2]u8{
.{ 0, 0 }, .{ 0, 5 }, .{ 0, 6 }, .{ 0, 11 }, .{ 0, 12 }, .{ 0, 17 }, .{ 0, 18 }, .{ 0, 19 },
.{ 1, 1 }, .{ 1, 4 }, .{ 1, 7 }, .{ 1, 10 }, .{ 1, 13 }, .{ 1, 16 } };
// zig fmt: on