|
@@ -3,20 +3,20 @@ const std = @import("std");
|
|
|
const shapeModule = @import("shape.zig");
|
|
const shapeModule = @import("shape.zig");
|
|
|
const inputModule = @import("input.zig");
|
|
const inputModule = @import("input.zig");
|
|
|
const areaModule = @import("area.zig");
|
|
const areaModule = @import("area.zig");
|
|
|
|
|
+const coordModule = @import("coord.zig");
|
|
|
|
|
+const unionFindModule = @import("unionfind.zig");
|
|
|
|
|
|
|
|
const Shape = shapeModule.Shape;
|
|
const Shape = shapeModule.Shape;
|
|
|
const Area = areaModule.Area;
|
|
const Area = areaModule.Area;
|
|
|
|
|
+const Coord = coordModule.Coord;
|
|
|
|
|
+const UnionFind = unionFindModule.UnionFind;
|
|
|
|
|
+
|
|
|
const kShapeSize = shapeModule.kShapeSize;
|
|
const kShapeSize = shapeModule.kShapeSize;
|
|
|
const readInputIntoString = inputModule.readInputIntoString;
|
|
const readInputIntoString = inputModule.readInputIntoString;
|
|
|
const parseInput = inputModule.parseInput;
|
|
const parseInput = inputModule.parseInput;
|
|
|
|
|
|
|
|
-const Coord = struct {
|
|
|
|
|
- row: i32,
|
|
|
|
|
- col: i32,
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
pub fn getEligibleCoords(allocator: std.mem.Allocator,
|
|
pub fn getEligibleCoords(allocator: std.mem.Allocator,
|
|
|
- area: Area,
|
|
|
|
|
|
|
+ area: *const Area,
|
|
|
eligibleCoords: *std.ArrayList(Coord)) !void {
|
|
eligibleCoords: *std.ArrayList(Coord)) !void {
|
|
|
eligibleCoords.clearRetainingCapacity();
|
|
eligibleCoords.clearRetainingCapacity();
|
|
|
|
|
|
|
@@ -73,9 +73,10 @@ pub fn calcShapesTotalSize(shapeCounts: []i32, shapeSizes: []usize) usize {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
-pub fn canContainShapes(allocator: std.mem.Allocator, area: Area,
|
|
|
|
|
|
|
+pub fn canContainShapes(allocator: std.mem.Allocator, area: *const Area,
|
|
|
shapeCounts: []i32, shapeTransforms: []const []const Shape,
|
|
shapeCounts: []i32, shapeTransforms: []const []const Shape,
|
|
|
- shapeSizes: []usize) !bool {
|
|
|
|
|
|
|
+ shapeSizes: []usize,
|
|
|
|
|
+ minShapeSize: usize) !bool {
|
|
|
// try std.fs.File.stdout().writeAll("canContainShapes: [");
|
|
// try std.fs.File.stdout().writeAll("canContainShapes: [");
|
|
|
// for (shapeCounts) |shapeCount| {
|
|
// for (shapeCounts) |shapeCount| {
|
|
|
// try std.fs.File.stdout().writeAll(
|
|
// try std.fs.File.stdout().writeAll(
|
|
@@ -117,10 +118,29 @@ pub fn canContainShapes(allocator: std.mem.Allocator, area: Area,
|
|
|
if (try area.appendShape(
|
|
if (try area.appendShape(
|
|
|
allocator,
|
|
allocator,
|
|
|
&shapeTransforms[shapeIndex][shapeVariant],
|
|
&shapeTransforms[shapeIndex][shapeVariant],
|
|
|
- @intCast(row), @intCast(col), '#')) |newArea| {
|
|
|
|
|
|
|
+ @intCast(row), @intCast(col), '#')) |*newArea| {
|
|
|
defer newArea.deinit();
|
|
defer newArea.deinit();
|
|
|
|
|
|
|
|
- // try std.fs.File.stdout().writeAll("Step: \n");
|
|
|
|
|
|
|
+ // try std.fs.File.stdout().writeAll("Before union find: \n");
|
|
|
|
|
+ // try newArea.print(allocator);
|
|
|
|
|
+ // try std.fs.File.stdout().writeAll("\n");
|
|
|
|
|
+
|
|
|
|
|
+ var mutableArea: Area = newArea.*;
|
|
|
|
|
+ var unionFind = try UnionFind.init(allocator, &mutableArea);
|
|
|
|
|
+ for (0 .. @intCast(mutableArea.rows)) |unionRow| {
|
|
|
|
|
+ for (0 .. @intCast(mutableArea.cols)) |unionCol| {
|
|
|
|
|
+ if (mutableArea.getCell(@intCast(unionRow), @intCast(unionCol)) == '.') {
|
|
|
|
|
+ const nodeAIndex:usize = @intCast(unionRow*@abs(mutableArea.cols) + unionCol);
|
|
|
|
|
+ const nodeARootIndex = unionFind.Find(nodeAIndex);
|
|
|
|
|
+ if (unionFind.nodes[nodeARootIndex].size < minShapeSize) {
|
|
|
|
|
+ mutableArea.setCell(@intCast(unionRow), @intCast(unionCol), '#');
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ unionFind.deinit();
|
|
|
|
|
+
|
|
|
|
|
+ // try std.fs.File.stdout().writeAll("After union find: \n");
|
|
|
// try newArea.print(allocator);
|
|
// try newArea.print(allocator);
|
|
|
// try std.fs.File.stdout().writeAll("\n");
|
|
// try std.fs.File.stdout().writeAll("\n");
|
|
|
|
|
|
|
@@ -130,7 +150,7 @@ pub fn canContainShapes(allocator: std.mem.Allocator, area: Area,
|
|
|
newShapeCounts[shapeIndex] -= 1;
|
|
newShapeCounts[shapeIndex] -= 1;
|
|
|
|
|
|
|
|
if (try canContainShapes(allocator, newArea, newShapeCounts,
|
|
if (try canContainShapes(allocator, newArea, newShapeCounts,
|
|
|
- shapeTransforms, shapeSizes)) {
|
|
|
|
|
|
|
+ shapeTransforms, shapeSizes, minShapeSize)) {
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -176,12 +196,20 @@ pub fn main() !void {
|
|
|
const shapeSizes = try calculateShapeSizes(allocator, shapeTransforms);
|
|
const shapeSizes = try calculateShapeSizes(allocator, shapeTransforms);
|
|
|
defer allocator.free(shapeSizes);
|
|
defer allocator.free(shapeSizes);
|
|
|
|
|
|
|
|
|
|
+ var minShapeSize = shapeSizes[0];
|
|
|
|
|
+ for (shapeSizes) |shapeSize| {
|
|
|
|
|
+ if (shapeSize < minShapeSize) {
|
|
|
|
|
+ minShapeSize = shapeSize;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
var counter: usize = 0;
|
|
var counter: usize = 0;
|
|
|
for (0..input.areas.len) |i| {
|
|
for (0..input.areas.len) |i| {
|
|
|
const area = try Area.init(allocator, input.areas[i].rows, input.areas[i].cols);
|
|
const area = try Area.init(allocator, input.areas[i].rows, input.areas[i].cols);
|
|
|
defer area.deinit();
|
|
defer area.deinit();
|
|
|
|
|
|
|
|
- if(try canContainShapes(allocator, area, input.areas[i].shapesCount, shapeTransforms, shapeSizes)) {
|
|
|
|
|
|
|
+ if(try canContainShapes(allocator, &area, input.areas[i].shapesCount,
|
|
|
|
|
+ shapeTransforms, shapeSizes, minShapeSize)) {
|
|
|
try std.fs.File.stdout().writeAll("Can contain shapes!\n");
|
|
try std.fs.File.stdout().writeAll("Can contain shapes!\n");
|
|
|
counter += 1;
|
|
counter += 1;
|
|
|
}
|
|
}
|