diff options
author | Mathias Magnusson <mathias@magnusson.space> | 2024-12-10 18:31:08 +0100 |
---|---|---|
committer | Mathias Magnusson <mathias@magnusson.space> | 2024-12-10 18:31:08 +0100 |
commit | 6c9e409af814c00a17209730913cf1104547ce21 (patch) | |
tree | 3085eca01c748101ca388b659c035c72b4827b72 /aoc24/src/day9.zig | |
parent | f8cc65a1ae6e6587e316757c7eb0d7d56624cdb0 (diff) | |
download | programming-problem-solving-6c9e409af814c00a17209730913cf1104547ce21.tar.gz |
aoc2024: day 9 part 1
Diffstat (limited to 'aoc24/src/day9.zig')
-rw-r--r-- | aoc24/src/day9.zig | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/aoc24/src/day9.zig b/aoc24/src/day9.zig new file mode 100644 index 0000000..520391d --- /dev/null +++ b/aoc24/src/day9.zig @@ -0,0 +1,89 @@ +const std = @import("std"); + +const Input = struct { + compressed: []Entry, + uncompressed: std.ArrayList(?u32), + + const Entry = struct { taken: u8, free: u8 }; +}; + +pub fn parse(allocator: std.mem.Allocator, data: []const u8) !Input { + var compressed = std.ArrayList(Input.Entry).init(allocator); + var i: usize = 0; + while (i < data.len) : (i += 2) { + try compressed.append(.{ .taken = data[i] - '0', .free = if (i + 1 == data.len or data[i + 1] == '\n') 0 else data[i + 1] - '0' }); + } + + var uncompressed = std.ArrayList(?u32).init(allocator); + for (0.., compressed.items) |j, entry| { + try uncompressed.appendNTimes(@intCast(j), entry.taken); + try uncompressed.appendNTimes(null, entry.free); + } + return .{ .compressed = compressed.items, .uncompressed = uncompressed }; +} + +const test_input = "2333133121414131402"; + +test "part1" { + var arena = std.heap.ArenaAllocator.init(std.testing.allocator); + defer arena.deinit(); + + const output = try part1(arena.allocator(), try parse(arena.allocator(), test_input)); + std.debug.print("got {}\n", .{output}); + std.debug.assert(output == 1928); +} + +pub fn part1(allocator: std.mem.Allocator, input: Input) !u64 { + var filesystem = std.ArrayList(u32).init(allocator); + var unmoved: u32 = 0; + var moved: u32 = @intCast(input.compressed.len); + var moved_left: u8 = 0; + while (unmoved < moved) { + try filesystem.appendNTimes(unmoved, input.compressed[unmoved].taken); + for (0..input.compressed[unmoved].free) |_| { + while (moved_left == 0) { + moved -= 1; + moved_left = input.compressed[moved].taken; + } + try filesystem.append(moved); + moved_left -= 1; + } + unmoved += 1; + } + try filesystem.appendNTimes(moved, moved_left); + + // for (filesystem.items) |item| { + // std.debug.print("{}", .{item}); + // } + // std.debug.print("\n", .{}); + + var sum: u64 = 0; + for (0.., filesystem.items) |pos, id| { + sum += pos * @as(u64, @intCast(id)); + } + + return sum; +} + +test "part2" { + var arena = std.heap.ArenaAllocator.init(std.testing.allocator); + defer arena.deinit(); + + const output = try part2(arena.allocator(), try parse(arena.allocator(), test_input)); + std.debug.print("got {}\n", .{output}); + std.debug.assert(output == 2858); +} + +pub fn part2(allocator: std.mem.Allocator, input: Input) !u32 { + var filesystem = std.ArrayList(u32).init(allocator); + + _ = .{ filesystem, input }; + filesystem = undefined; + + var sum: u64 = 0; + for (0.., filesystem.items) |pos, id| { + sum += pos * @as(u64, @intCast(id)); + } + + return sum; +} |