|
| 1 | +const std = @import("std"); |
| 2 | + |
| 3 | +const print = std.debug.print; |
| 4 | + |
| 5 | +fn get_input(ac: std.mem.Allocator) ![]const u8 { |
| 6 | + const args = try std.process.argsAlloc(ac); |
| 7 | + defer std.process.argsFree(ac, args); |
| 8 | + const file_name = try std.fmt.allocPrint(ac, "inputs/{s}/{s}.txt", .{ args[1], args[2] }); |
| 9 | + defer ac.free(file_name); |
| 10 | + var input_file = try std.fs.cwd().openFile(file_name, .{ .mode = .read_only }); |
| 11 | + defer input_file.close(); |
| 12 | + const file_size = (try input_file.stat()).size; |
| 13 | + const buffer = try ac.alloc(u8, file_size); |
| 14 | + try input_file.reader().readNoEof(buffer); |
| 15 | + return buffer; |
| 16 | +} |
| 17 | + |
| 18 | +pub fn main() !void { |
| 19 | + var GPA = std.heap.GeneralPurposeAllocator(.{}){}; |
| 20 | + const gpa = GPA.allocator(); |
| 21 | + defer _ = GPA.deinit(); |
| 22 | + const input = try get_input(gpa); |
| 23 | + defer gpa.free(input); |
| 24 | + |
| 25 | + try solve(input, gpa); |
| 26 | +} |
| 27 | + |
| 28 | +fn solve(input: []const u8, ac: std.mem.Allocator) !void { |
| 29 | + var res_1: u64 = 0; |
| 30 | + var res_2: u64 = 0; |
| 31 | + |
| 32 | + // |
| 33 | + var containers = std.ArrayList(u8).init(ac); |
| 34 | + defer containers.deinit(); |
| 35 | + var idx: usize = 0; |
| 36 | + while (idx < input.len) : (idx += 1) { |
| 37 | + var size: u8 = 0; |
| 38 | + while (input[idx] != '\n') : (idx += 1) size = size * 10 + input[idx] - 48; |
| 39 | + try containers.append(size); |
| 40 | + } |
| 41 | + |
| 42 | + var dp = try ac.alloc([EGGNOG_QTY + 1]Aaaaa, containers.items.len + 1); |
| 43 | + defer ac.free(dp); |
| 44 | + |
| 45 | + for (dp) |*row| { |
| 46 | + inline for (0..(EGGNOG_QTY + 1)) |c| row.*[c] = Aaaaa.init(ac); |
| 47 | + } |
| 48 | + defer for (dp) |*row| { |
| 49 | + inline for (0..(EGGNOG_QTY + 1)) |c| row.*[c].deinit(); |
| 50 | + }; |
| 51 | + |
| 52 | + try dp[containers.items.len][EGGNOG_QTY].append(.{ 0, 1 }); |
| 53 | + |
| 54 | + _ = try make_dp(dp, containers, 0, 0); |
| 55 | + |
| 56 | + for (dp[0][0].items) |qq| res_1 += qq[1]; |
| 57 | + res_2 = dp[0][0].items[0][1]; |
| 58 | + |
| 59 | + print("part 1: {}\npart 2: {}", .{ res_1, res_2 }); |
| 60 | +} |
| 61 | + |
| 62 | +fn make_dp(dp: [][EGGNOG_QTY + 1]Aaaaa, containers: std.ArrayList(u8), idx: usize, en: u8) !bool { |
| 63 | + if (idx == containers.items.len) return en == EGGNOG_QTY; |
| 64 | + if (en > EGGNOG_QTY) return false; |
| 65 | + if (dp[idx][en].items.len != 0) return true; |
| 66 | + |
| 67 | + const len0 = if (try make_dp(dp, containers, idx + 1, en)) dp[idx + 1][en].items.len else 0; |
| 68 | + const len1 = if (try make_dp(dp, containers, idx + 1, en + containers.items[idx])) dp[idx + 1][en + containers.items[idx]].items.len else 0; |
| 69 | + |
| 70 | + var ii: usize = 0; |
| 71 | + var jj: usize = 0; |
| 72 | + |
| 73 | + while (ii < len0 and jj < len1) { |
| 74 | + const aa = dp[idx + 1][en].items[ii]; |
| 75 | + const bb = dp[idx + 1][en + containers.items[idx]].items[jj]; |
| 76 | + switch (order(aa[0], bb[0] + 1)) { |
| 77 | + .lt => { |
| 78 | + try dp[idx][en].append(aa); |
| 79 | + ii += 1; |
| 80 | + }, |
| 81 | + .gt => { |
| 82 | + try dp[idx][en].append(.{ bb[0] + 1, bb[1] }); |
| 83 | + jj += 1; |
| 84 | + }, |
| 85 | + .eq => { |
| 86 | + try dp[idx][en].append(.{ aa[0], aa[1] + bb[1] }); |
| 87 | + ii += 1; |
| 88 | + jj += 1; |
| 89 | + }, |
| 90 | + } |
| 91 | + } |
| 92 | + while (ii < len0) : (ii += 1) try dp[idx][en].append(dp[idx + 1][en].items[ii]); |
| 93 | + while (jj < len1) : (jj += 1) { |
| 94 | + const aa = dp[idx + 1][en + containers.items[idx]].items[jj]; |
| 95 | + try dp[idx][en].append(.{ aa[0] + 1, aa[1] }); |
| 96 | + } |
| 97 | + |
| 98 | + return dp[idx][en].items.len != 0; |
| 99 | +} |
| 100 | + |
| 101 | +const Aaaaa = std.ArrayList([2]u32); |
| 102 | +const order = std.math.order; |
| 103 | +const EGGNOG_QTY: u8 = 150; |
0 commit comments