Solution to 19-2
This commit is contained in:
parent
f06c75a2e2
commit
c80bb01c88
@ -399,4 +399,4 @@ rbgruwuugbgbrgrgugrgrrrwruuggubbwrbruubbbr
|
||||
rrrrwugrrrrrubrbrgwgrrgwrubgwuuuburburburwrrgbwu
|
||||
ruwgugbguwuwgrwbrbgwruwurbugwwgbwwugbrrbwguur
|
||||
ugrrwbbwwbwwbbururwguuwwurwrguggggugrwbugwwgwgg
|
||||
gbwurruuubuurrwurbuwwwubbwbwbbrgrbrwbbwrrrbruwrwubbrbgwbwb
|
||||
gbwurruuubuurrwurbuwwwubbwbwbbrgrbrwbbwrrrbruwrwubbrbgwbwb
|
@ -9,7 +9,7 @@ pub fn main() !void {
|
||||
defer _ = gpa.deinit();
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
const response = try partOne(false, false, allocator);
|
||||
const response = try partTwo(false, false, allocator);
|
||||
print("{}\n", .{response});
|
||||
}
|
||||
|
||||
@ -26,6 +26,8 @@ fn partOne(is_test_case: bool, debug: bool, allocator: std.mem.Allocator) !u16 {
|
||||
|
||||
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| {
|
||||
@ -77,12 +79,68 @@ fn parseTowels(line: []const u8, allocator: std.mem.Allocator) [][]const u8 {
|
||||
return response.toOwnedSlice() catch unreachable;
|
||||
}
|
||||
|
||||
test "partOne" {
|
||||
// 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);
|
||||
// }
|
||||
|
||||
fn partTwo(is_test_case: bool, debug: bool, allocator: std.mem.Allocator) !u128 {
|
||||
const input_file = try util.getInputFile("19", is_test_case);
|
||||
const data = try util.readAllInputWithAllocator(input_file, allocator);
|
||||
defer allocator.free(data);
|
||||
|
||||
var data_lines_it = std.mem.splitScalar(u8, data, '\n');
|
||||
const towels = parseTowels(data_lines_it.next().?, allocator);
|
||||
defer allocator.free(towels);
|
||||
|
||||
_ = data_lines_it.next();
|
||||
|
||||
var ways_to_make_designs = std.StringHashMap(u128).init(allocator);
|
||||
defer ways_to_make_designs.deinit();
|
||||
// Not priming the "ways to make design" count, here, because this isn't as simple as the boolean yes-no in the
|
||||
// previous case - e.g. if we have towels `rbr`, `r`, and `br`, then the count for `rbr` should be 2, not 1.
|
||||
|
||||
var count: u128 = 0;
|
||||
while (data_lines_it.next()) |design| {
|
||||
const ways = waysToMakeDesign(design, towels, &ways_to_make_designs, debug);
|
||||
print("Found {} ways to make {s}\n", .{ ways, design });
|
||||
count += ways;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
fn waysToMakeDesign(design: []const u8, towels: [][]const u8, ways_to_make_designs: *std.StringHashMap(u128), debug: bool) u128 {
|
||||
if (design.len == 0) {
|
||||
return 1;
|
||||
}
|
||||
if (!(ways_to_make_designs.contains(design))) {
|
||||
var accum: u128 = 0;
|
||||
for (towels) |towel| {
|
||||
if (design.len >= towel.len and std.mem.eql(u8, towel, design[0..towel.len])) {
|
||||
const remainder = design[towel.len..];
|
||||
const response = waysToMakeDesign(remainder, towels, ways_to_make_designs, debug);
|
||||
if (response > 0) {
|
||||
log("Got response {} to add to accum {} for remainder {s}\n", .{ response, accum, remainder }, debug);
|
||||
accum += response;
|
||||
}
|
||||
}
|
||||
}
|
||||
ways_to_make_designs.put(design, accum) catch unreachable;
|
||||
}
|
||||
return ways_to_make_designs.get(design).?;
|
||||
}
|
||||
|
||||
test "partTwo" {
|
||||
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 partTwo(true, true, allocator);
|
||||
print("Part Two response is {}\n", .{response});
|
||||
try expect(response == 16);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user