day12 part2
jesus
This commit is contained in:
parent
3e8dca665f
commit
d80a39e7dc
@ -14,8 +14,8 @@ const Solution = struct {
|
||||
b: usize,
|
||||
};
|
||||
|
||||
fn hash(alloc: mem.Allocator, pattern: []const u8, groups: []const u8, curr_group: u8) ![]const u8 {
|
||||
var a = try std.ArrayList(u8).initCapacity(alloc, pattern.len + groups.len + curr_group);
|
||||
fn hash(alloc: mem.Allocator, pattern: []const u8, groups: []const u8, curr_group: u8) ![]u8 {
|
||||
var a = try std.ArrayList(u8).initCapacity(alloc, pattern.len + groups.len + 1);
|
||||
try a.appendSlice(pattern);
|
||||
try a.appendSlice(groups);
|
||||
try a.append(curr_group);
|
||||
@ -25,10 +25,10 @@ fn hash(alloc: mem.Allocator, pattern: []const u8, groups: []const u8, curr_grou
|
||||
// Mystery records to whether they fit.
|
||||
var memo: std.StringHashMap(u32) = undefined;
|
||||
|
||||
fn copy(comptime T: type, alloc: mem.Allocator, s: []const T) ![]T {
|
||||
var a = try std.ArrayList(T).initCapacity(alloc, s.len);
|
||||
try a.insertSlice(0, s);
|
||||
return try a.toOwnedSlice();
|
||||
fn clone(comptime T: type, alloc: mem.Allocator, s: []const T) ![]T {
|
||||
var a = try alloc.alloc(T, s.len);
|
||||
@memcpy(a, s);
|
||||
return a;
|
||||
}
|
||||
|
||||
fn solvePattern(alloc: mem.Allocator, pattern: []const u8, groups: []const u8, curr_group: u8) !u32 {
|
||||
@ -37,12 +37,12 @@ fn solvePattern(alloc: mem.Allocator, pattern: []const u8, groups: []const u8, c
|
||||
const h = try hash(alloc, pattern, groups, curr_group);
|
||||
if (memo.get(h)) |m| {
|
||||
alloc.free(h);
|
||||
std.debug.print("==> short-circuit {}\n", .{m});
|
||||
std.debug.print("== short-circuit {}\n", .{m});
|
||||
return m;
|
||||
}
|
||||
|
||||
if (pattern.len == 0) {
|
||||
std.debug.print("=> done ok: {}\n", .{groups.len == 0});
|
||||
std.debug.print("== done {}\n", .{groups.len == 0});
|
||||
return if (groups.len == 0) 1 else 0;
|
||||
}
|
||||
|
||||
@ -56,6 +56,7 @@ fn solvePattern(alloc: mem.Allocator, pattern: []const u8, groups: []const u8, c
|
||||
}
|
||||
// Special-case last #
|
||||
if (pattern.len == 1 and groups.len == 1 and groups[0] == curr_group + 1) {
|
||||
std.debug.print("== done true\n", .{});
|
||||
break :b 1;
|
||||
}
|
||||
break :b try solvePattern(alloc, pattern[1..], groups, curr_group + 1);
|
||||
@ -68,7 +69,6 @@ fn solvePattern(alloc: mem.Allocator, pattern: []const u8, groups: []const u8, c
|
||||
break :b 0;
|
||||
} else {
|
||||
// Group done
|
||||
std.debug.print("=> group {} ok\n", .{groups[0]});
|
||||
break :b try solvePattern(alloc, pattern[1..], groups[1..], 0);
|
||||
}
|
||||
} else {
|
||||
@ -77,9 +77,9 @@ fn solvePattern(alloc: mem.Allocator, pattern: []const u8, groups: []const u8, c
|
||||
}
|
||||
},
|
||||
'?' => {
|
||||
const p1 = try copy(u8, alloc, pattern);
|
||||
const p1 = try clone(u8, alloc, pattern);
|
||||
defer alloc.free(p1);
|
||||
const p2 = try copy(u8, alloc, pattern);
|
||||
const p2 = try clone(u8, alloc, pattern);
|
||||
defer alloc.free(p2);
|
||||
|
||||
p1[0] = '#';
|
||||
@ -99,12 +99,24 @@ fn solvePattern(alloc: mem.Allocator, pattern: []const u8, groups: []const u8, c
|
||||
return res;
|
||||
}
|
||||
|
||||
fn unfold(alloc: mem.Allocator, input: []const u8, sep: u8) ![]const u8 {
|
||||
var buf = try std.ArrayList(u8).initCapacity(alloc, input.len * 5 + 5);
|
||||
for (0..5) |i| {
|
||||
if (i > 0 and sep > 0) try buf.append(sep);
|
||||
try buf.appendSlice(input);
|
||||
}
|
||||
return try buf.toOwnedSlice();
|
||||
}
|
||||
|
||||
fn solve(alloc: mem.Allocator, input: []const u8) !Solution {
|
||||
memo = std.StringHashMap(u32).init(alloc);
|
||||
defer memo.deinit();
|
||||
|
||||
var sum: u32 = 0;
|
||||
var sum1: u32 = 0;
|
||||
var sum2: u32 = 0;
|
||||
|
||||
var it = util.splitLines(input);
|
||||
var i: u32 = 0;
|
||||
while (it.next()) |line| {
|
||||
if (line.len == 0) continue;
|
||||
|
||||
@ -114,9 +126,16 @@ fn solve(alloc: mem.Allocator, input: []const u8) !Solution {
|
||||
const groups = try util.parseIntsScalar(u8, alloc, raw_groups, .{ .sep = ',' });
|
||||
defer alloc.free(groups);
|
||||
|
||||
std.debug.print("-----------------------------------------------\n", .{});
|
||||
sum += try solvePattern(alloc, pattern, groups, 0);
|
||||
std.debug.print("{}\n", .{sum});
|
||||
const unfolded_pattern = try unfold(alloc, pattern, '?');
|
||||
const unfolded_groups = try unfold(alloc, groups, 0);
|
||||
defer alloc.free(unfolded_pattern);
|
||||
defer alloc.free(unfolded_groups);
|
||||
|
||||
std.debug.print("---- {} ----\n", .{i});
|
||||
sum1 += try solvePattern(alloc, pattern, groups, 0);
|
||||
sum2 += try solvePattern(alloc, unfolded_pattern, unfolded_groups, 0);
|
||||
std.debug.print("{} {}\n", .{ sum1, sum2 });
|
||||
i += 1;
|
||||
}
|
||||
|
||||
var mkeys = memo.keyIterator();
|
||||
@ -124,7 +143,7 @@ fn solve(alloc: mem.Allocator, input: []const u8) !Solution {
|
||||
alloc.free(k.*);
|
||||
}
|
||||
|
||||
return .{ .a = sum, .b = 0 };
|
||||
return .{ .a = sum1, .b = sum2 };
|
||||
}
|
||||
|
||||
test "silver" {
|
||||
@ -140,15 +159,34 @@ test "silver" {
|
||||
try std.testing.expectEqual(@as(usize, 21), sln.a);
|
||||
}
|
||||
|
||||
test "gold" {
|
||||
test "gold-2" {
|
||||
const input =
|
||||
\\???.### 1,1,3
|
||||
\\.??..??...?##. 1,1,3
|
||||
\\?#?#?#?#?#?#?#? 1,3,1,6
|
||||
;
|
||||
const sln = try solve(std.testing.allocator, input);
|
||||
try std.testing.expectEqual(@as(usize, 16384), sln.b);
|
||||
}
|
||||
|
||||
test "gold-4" {
|
||||
const input =
|
||||
\\????.#...#... 4,1,1
|
||||
;
|
||||
const sln = try solve(std.testing.allocator, input);
|
||||
try std.testing.expectEqual(@as(usize, 16), sln.b);
|
||||
}
|
||||
|
||||
test "gold-5" {
|
||||
const input =
|
||||
\\????.######..#####. 1,6,5
|
||||
;
|
||||
const sln = try solve(std.testing.allocator, input);
|
||||
try std.testing.expectEqual(@as(usize, 2500), sln.b);
|
||||
}
|
||||
|
||||
test "gold-6" {
|
||||
const input =
|
||||
\\?###???????? 3,2,1
|
||||
;
|
||||
const sln = try solve(std.testing.allocator, input);
|
||||
try std.testing.expectEqual(@as(usize, 525152), sln.b);
|
||||
try std.testing.expectEqual(@as(usize, 506250), sln.b);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user