This commit is contained in:
parent
d80a39e7dc
commit
fa7a9aab14
@ -22,8 +22,7 @@ fn hash(alloc: mem.Allocator, pattern: []const u8, groups: []const u8, curr_grou
|
|||||||
return try a.toOwnedSlice();
|
return try a.toOwnedSlice();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mystery records to whether they fit.
|
var memo: std.StringHashMap(usize) = undefined;
|
||||||
var memo: std.StringHashMap(u32) = undefined;
|
|
||||||
|
|
||||||
fn clone(comptime T: type, alloc: mem.Allocator, s: []const T) ![]T {
|
fn clone(comptime T: type, alloc: mem.Allocator, s: []const T) ![]T {
|
||||||
var a = try alloc.alloc(T, s.len);
|
var a = try alloc.alloc(T, s.len);
|
||||||
@ -31,32 +30,26 @@ fn clone(comptime T: type, alloc: mem.Allocator, s: []const T) ![]T {
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn solvePattern(alloc: mem.Allocator, pattern: []const u8, groups: []const u8, curr_group: u8) !u32 {
|
fn solvePattern(alloc: mem.Allocator, pattern: []const u8, groups: []const u8, curr_group: u8) !usize {
|
||||||
std.debug.print("{s}, {any}, {}\n", .{ pattern, groups, curr_group });
|
|
||||||
|
|
||||||
const h = try hash(alloc, pattern, groups, curr_group);
|
const h = try hash(alloc, pattern, groups, curr_group);
|
||||||
if (memo.get(h)) |m| {
|
if (memo.get(h)) |m| {
|
||||||
alloc.free(h);
|
alloc.free(h);
|
||||||
std.debug.print("== short-circuit {}\n", .{m});
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pattern.len == 0) {
|
if (pattern.len == 0) {
|
||||||
std.debug.print("== done {}\n", .{groups.len == 0});
|
|
||||||
return if (groups.len == 0) 1 else 0;
|
return if (groups.len == 0) 1 else 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const res: u32 = b: {
|
const res: usize = b: {
|
||||||
switch (pattern[0]) {
|
switch (pattern[0]) {
|
||||||
'#' => {
|
'#' => {
|
||||||
// Too many #
|
// Too many #
|
||||||
if (groups.len == 0 or curr_group >= groups[0]) {
|
if (groups.len == 0 or curr_group >= groups[0]) {
|
||||||
std.debug.print("== bad fit\n", .{});
|
|
||||||
break :b 0;
|
break :b 0;
|
||||||
}
|
}
|
||||||
// Special-case last #
|
// Special-case last #
|
||||||
if (pattern.len == 1 and groups.len == 1 and groups[0] == curr_group + 1) {
|
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 1;
|
||||||
}
|
}
|
||||||
break :b try solvePattern(alloc, pattern[1..], groups, curr_group + 1);
|
break :b try solvePattern(alloc, pattern[1..], groups, curr_group + 1);
|
||||||
@ -65,7 +58,6 @@ fn solvePattern(alloc: mem.Allocator, pattern: []const u8, groups: []const u8, c
|
|||||||
if (curr_group > 0) {
|
if (curr_group > 0) {
|
||||||
if (groups.len == 0 or curr_group != groups[0]) {
|
if (groups.len == 0 or curr_group != groups[0]) {
|
||||||
// Too many #
|
// Too many #
|
||||||
std.debug.print("== bad fit\n", .{});
|
|
||||||
break :b 0;
|
break :b 0;
|
||||||
} else {
|
} else {
|
||||||
// Group done
|
// Group done
|
||||||
@ -85,7 +77,6 @@ fn solvePattern(alloc: mem.Allocator, pattern: []const u8, groups: []const u8, c
|
|||||||
p1[0] = '#';
|
p1[0] = '#';
|
||||||
p2[0] = '.';
|
p2[0] = '.';
|
||||||
|
|
||||||
std.debug.print("=> test ?\n", .{});
|
|
||||||
break :b try solvePattern(alloc, p1, groups, curr_group) +
|
break :b try solvePattern(alloc, p1, groups, curr_group) +
|
||||||
try solvePattern(alloc, p2, groups, curr_group);
|
try solvePattern(alloc, p2, groups, curr_group);
|
||||||
},
|
},
|
||||||
@ -93,7 +84,6 @@ fn solvePattern(alloc: mem.Allocator, pattern: []const u8, groups: []const u8, c
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std.debug.print("<= {s}, {any}, {} = {}\n", .{ pattern, groups, curr_group, res });
|
|
||||||
try memo.put(h, res);
|
try memo.put(h, res);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@ -109,16 +99,17 @@ fn unfold(alloc: mem.Allocator, input: []const u8, sep: u8) ![]const u8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn solve(alloc: mem.Allocator, input: []const u8) !Solution {
|
fn solve(alloc: mem.Allocator, input: []const u8) !Solution {
|
||||||
memo = std.StringHashMap(u32).init(alloc);
|
memo = std.StringHashMap(usize).init(alloc);
|
||||||
defer memo.deinit();
|
defer memo.deinit();
|
||||||
|
|
||||||
var sum1: u32 = 0;
|
var sum1: usize = 0;
|
||||||
var sum2: u32 = 0;
|
var sum2: usize = 0;
|
||||||
|
|
||||||
var it = util.splitLines(input);
|
var it = util.splitLines(input);
|
||||||
var i: u32 = 0;
|
var i: usize = 1;
|
||||||
while (it.next()) |line| {
|
while (it.next()) |line| {
|
||||||
if (line.len == 0) continue;
|
if (line.len == 0) continue;
|
||||||
|
std.debug.print("line {} ", .{i});
|
||||||
|
|
||||||
var lit = util.splitSpace(line);
|
var lit = util.splitSpace(line);
|
||||||
const pattern = lit.next().?;
|
const pattern = lit.next().?;
|
||||||
@ -131,7 +122,6 @@ fn solve(alloc: mem.Allocator, input: []const u8) !Solution {
|
|||||||
defer alloc.free(unfolded_pattern);
|
defer alloc.free(unfolded_pattern);
|
||||||
defer alloc.free(unfolded_groups);
|
defer alloc.free(unfolded_groups);
|
||||||
|
|
||||||
std.debug.print("---- {} ----\n", .{i});
|
|
||||||
sum1 += try solvePattern(alloc, pattern, groups, 0);
|
sum1 += try solvePattern(alloc, pattern, groups, 0);
|
||||||
sum2 += try solvePattern(alloc, unfolded_pattern, unfolded_groups, 0);
|
sum2 += try solvePattern(alloc, unfolded_pattern, unfolded_groups, 0);
|
||||||
std.debug.print("{} {}\n", .{ sum1, sum2 });
|
std.debug.print("{} {}\n", .{ sum1, sum2 });
|
||||||
@ -159,34 +149,15 @@ test "silver" {
|
|||||||
try std.testing.expectEqual(@as(usize, 21), sln.a);
|
try std.testing.expectEqual(@as(usize, 21), sln.a);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "gold-2" {
|
test "gold" {
|
||||||
const input =
|
const input =
|
||||||
|
\\???.### 1,1,3
|
||||||
\\.??..??...?##. 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
|
\\????.#...#... 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
|
\\????.######..#####. 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
|
\\?###???????? 3,2,1
|
||||||
;
|
;
|
||||||
const sln = try solve(std.testing.allocator, input);
|
const sln = try solve(std.testing.allocator, input);
|
||||||
try std.testing.expectEqual(@as(usize, 506250), sln.b);
|
try std.testing.expectEqual(@as(usize, 525152), sln.b);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user