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