From 68c38385ff17c76a6dfc4e4e9c8abd3d1c5aab58 Mon Sep 17 00:00:00 2001 From: Jack Jackson Date: Mon, 20 Jan 2025 13:33:10 -0800 Subject: [PATCH] Refactor to use 16-2 solution in 16-1 --- solutions/19.zig | 56 ++++++++++-------------------------------------- 1 file changed, 11 insertions(+), 45 deletions(-) diff --git a/solutions/19.zig b/solutions/19.zig index 2cabd0d..987e126 100644 --- a/solutions/19.zig +++ b/solutions/19.zig @@ -24,52 +24,18 @@ fn partOne(is_test_case: bool, debug: bool, allocator: std.mem.Allocator) !u16 { _ = data_lines_it.next(); - var known_valid_designs = std.StringHashMap(void).init(allocator); - defer known_valid_designs.deinit(); - // I added in this minor optimization because my code was running _super_ slow and I couldn't figure out why. - // Then I realized I'd acccidentally left in a `std.time.sleep(1000000000)` that I'd introduced while debugging :P - var known_invalid_designs = std.StringHashMap(void).init(allocator); - defer known_invalid_designs.deinit(); - for (towels) |towel| { - known_valid_designs.put(towel, {}) catch unreachable; - } - log("Parsed the towels\n", .{}, debug); + var ways_to_make_designs = std.StringHashMap(u128).init(allocator); + defer ways_to_make_designs.deinit(); var count: u16 = 0; while (data_lines_it.next()) |design| { - if (isDesignValid(design, towels, &known_valid_designs, &known_invalid_designs, debug)) { + if (waysToMakeDesign(design, towels, &ways_to_make_designs, debug) > 0) { count += 1; } - print("Checked a design. Known valid designs now has size {}, and known invalid designs {}\n", .{ known_valid_designs.count(), known_invalid_designs.count() }); } return count; } -fn isDesignValid(design: []const u8, towels: [][]const u8, known_valid_designs: *std.StringHashMap(void), known_invalid_designs: *std.StringHashMap(void), debug: bool) bool { - log("Checking validity of {s}, with {d} known valid designs and {d} known invalid designs\n", .{ design, known_valid_designs.count(), known_invalid_designs.count() }, debug); - if (known_valid_designs.contains(design)) { - log("***** Already found {s} to be a valid design *****\n", .{design}, debug); - return true; - } - if (known_invalid_designs.contains(design)) { - log("***** Already found {s} to be an INVALID design *****\n", .{design}, debug); - return false; - } - for (towels) |towel| { - if (design.len >= towel.len and std.mem.eql(u8, towel, design[0..towel.len])) { - log("{s} is a valid prefix of {s}, so iterating down from there\n", .{ towel, design }, debug); - const remainder = design[towel.len..]; - if (isDesignValid(remainder, towels, known_valid_designs, known_invalid_designs, debug)) { - known_valid_designs.put(design, {}) catch unreachable; - log("===== Adding {s} to known valid designs =====\n", .{design}, debug); - return true; - } - } - } - known_invalid_designs.put(design, {}) catch unreachable; - return false; -} - fn parseTowels(line: []const u8, allocator: std.mem.Allocator) [][]const u8 { var response = std.ArrayList([]const u8).init(allocator); var line_it = std.mem.splitSequence(u8, line, ", "); @@ -79,15 +45,15 @@ fn parseTowels(line: []const u8, allocator: std.mem.Allocator) [][]const u8 { return response.toOwnedSlice() catch unreachable; } -// test "partOne" { -// var gpa = std.heap.GeneralPurposeAllocator(.{}){}; -// defer _ = gpa.deinit(); -// const allocator = gpa.allocator(); +test "partOne" { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + const allocator = gpa.allocator(); -// const response = try partOne(true, true, allocator); -// print("Part One response is {}\n", .{response}); -// try expect(response == 6); -// } + const response = try partOne(true, true, allocator); + print("Part One response is {}\n", .{response}); + try expect(response == 6); +} fn partTwo(is_test_case: bool, debug: bool, allocator: std.mem.Allocator) !u128 { const input_file = try util.getInputFile("19", is_test_case);