diff options
Diffstat (limited to 'src/09/main.zig')
| -rw-r--r-- | src/09/main.zig | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/src/09/main.zig b/src/09/main.zig new file mode 100644 index 0000000..1187e99 --- /dev/null +++ b/src/09/main.zig @@ -0,0 +1,83 @@ +const std = @import("std"); +const aoc = @import("aoc"); + +const preamble_size = 25; + +fn preambleHasSum(preamble: []u64, target: u64) bool { + for (preamble) |v1| { + for (preamble) |v2| { + if (v1 != v2 and v1 + v2 == target) + return true; + } + } + return false; +} + +fn getInvalid(allocator: std.mem.Allocator, input: []u8) !u64 { + var preamble = std.ArrayList(u64).init(allocator); + defer preamble.deinit(); + + var i: u64 = 0; + var numit = std.mem.tokenize(u8, input, "\n"); + while (numit.next()) |numstr| : (i += 1) { + const num = try std.fmt.parseInt(u64, numstr, 10); + if (i > preamble_size) { + if (!preambleHasSum(preamble.items, num)) { + return num; + } + preamble.items[(i - 1) % preamble_size] = num; + } else { + try preamble.append(num); + } + } + + return aoc.Error.InvalidInput; +} + +fn listSum(items: []u64) u64 { + var sum: u64 = 0; + for (items) |i| + sum += i; + return sum; +} + +fn part1(allocator: std.mem.Allocator, input: []u8, args: [][]u8) !?[]u8 { + _ = args; + + const answer = try getInvalid(allocator, input); + + return try std.fmt.allocPrint(allocator, "{d}", .{answer}); +} + +fn part2(allocator: std.mem.Allocator, input: []u8, args: [][]u8) !?[]u8 { + _ = args; + + const invalid = try getInvalid(allocator, input); + + var numset = std.ArrayList(u64).init(allocator); + defer numset.deinit(); + + var numit = std.mem.tokenize(u8, input, "\n"); + while (true) { + const sum = listSum(numset.items); + if (sum < invalid) { + const numstr = numit.next(); + if (numstr == null) break; + const num = try std.fmt.parseInt(u64, numstr.?, 10); + try numset.append(num); + } else if (sum > invalid) { + _ = numset.orderedRemove(0); + } else { + break; + } + } + + if (numset.items.len > 0) { + const answer = std.mem.min(u64, numset.items) + std.mem.max(u64, numset.items); + return try std.fmt.allocPrint(allocator, "{d}", .{answer}); + } + + return null; +} + +pub const main = aoc.main(part1, part2, .{ "466456641", "55732936" }); |
