Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const std = @import("std");
- const Coords = struct { x: usize, y: usize };
- const Dir = struct { dx: i32, dy: i32 };
- fn checkNeighbours(grid: [][]u8, x: usize, y: usize) bool {
- const height = grid.len;
- const dirs: [8]Dir = .{
- Dir{ .dx = -1, .dy = -1 }, Dir{ .dx = 0, .dy = -1 }, Dir{ .dx = 1, .dy = -1 },
- Dir{ .dx = -1, .dy = 0 }, Dir{ .dx = 1, .dy = 0 }, Dir{ .dx = -1, .dy = 1 },
- Dir{ .dx = 0, .dy = 1 }, Dir{ .dx = 1, .dy = 1 },
- };
- var count: u8 = 0;
- for (dirs) |d| {
- const nx_i = @as(i32, @intCast(x)) + d.dx;
- const ny_i = @as(i32, @intCast(y)) + d.dy;
- if (nx_i < 0 or ny_i < 0) continue;
- const nx: usize = @intCast(nx_i);
- const ny: usize = @intCast(ny_i);
- if (ny >= height) continue;
- if (nx >= grid[ny].len) continue;
- if (grid[ny][nx] == 1) {
- count += 1;
- if (count > 3) return false;
- }
- }
- return true;
- }
- fn dayFourBothParts(stdout: *std.Io.Writer, allocator: std.mem.Allocator) !void {
- const file = try std.fs.cwd().openFile("data.txt", .{ .mode = .read_only });
- defer file.close();
- var file_buffer: [4096]u8 = undefined;
- var file_reader = file.reader(&file_buffer);
- const reader = &file_reader.interface;
- var placement_list: std.ArrayList([]u8) = .empty;
- defer placement_list.deinit(allocator);
- while (reader.takeDelimiterExclusive('\n')) |line| {
- reader.toss(1);
- var list: std.ArrayList(u8) = .empty;
- for (line) |char| {
- if (char == '@') {
- try list.append(allocator, 1);
- } else {
- try list.append(allocator, 0);
- }
- }
- const slice = try list.toOwnedSlice(allocator);
- try placement_list.append(allocator, slice);
- } else |err| switch (err) {
- error.EndOfStream => {},
- else => return err,
- }
- var coordinates_list: std.ArrayList(Coords) = .empty;
- defer coordinates_list.deinit(allocator);
- const placement = try placement_list.toOwnedSlice(allocator);
- var movable_part_one: u16 = 0;
- var movable_part_two: u32 = 0;
- var y: usize = 0;
- while (y < placement.len) : (y += 1) {
- var x: usize = 0;
- while (x < placement[y].len) : (x += 1) {
- if (placement[y][x] == 1) {
- if (checkNeighbours(placement, x, y)) {
- movable_part_one += 1;
- movable_part_two += 1;
- const coords = Coords{ .x = x, .y = y };
- try coordinates_list.append(allocator, coords);
- }
- }
- }
- }
- // Moving the rolls
- for (coordinates_list.items) |coords| {
- const cx = coords.x;
- const cy = coords.y;
- placement[cy][cx] = 0;
- }
- coordinates_list.clearRetainingCapacity();
- try stdout.print("Number of movable rolls: {d}\n", .{movable_part_one});
- try stdout.flush();
- try stdout.print("--" ** 20 ++ "\n", .{});
- const day: u8 = 4;
- try stdout.print("Start of Day {d} Part 2\n", .{day});
- try stdout.print("--" ** 20 ++ "\n", .{});
- try stdout.flush();
- moving_loop: while (true) {
- var moved = false;
- y = 0;
- while (y < placement.len) : (y += 1) {
- var x: usize = 0;
- while (x < placement[y].len) : (x += 1) {
- if (placement[y][x] == 1) {
- if (checkNeighbours(placement, x, y)) {
- movable_part_two += 1;
- const coords = Coords{ .x = x, .y = y };
- try coordinates_list.append(allocator, coords);
- moved = true;
- }
- }
- }
- }
- // Moving the rolls
- for (coordinates_list.items) |coords| {
- const cx = coords.x;
- const cy = coords.y;
- placement[cy][cx] = 0;
- }
- coordinates_list.clearRetainingCapacity();
- if (!moved) break :moving_loop;
- }
- try stdout.print("Number of total rolls moved: {d}\n", .{movable_part_two});
- try stdout.flush();
- }
- pub fn main() !void {
- var stdout_buffer: [1024]u8 = undefined;
- var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer);
- const stdout = &stdout_writer.interface;
- const day: u8 = 4;
- try stdout.print("Start of Day {d} Part 1\n", .{day});
- try stdout.print("--" ** 20 ++ "\n", .{});
- try stdout.flush();
- var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
- defer arena.deinit();
- const allocator = arena.allocator();
- try dayFourBothParts(stdout, allocator);
- }
Advertisement
Add Comment
Please, Sign In to add comment