const std = @import("std"); const mem = std.mem; const math = std.math; pub fn main() !void { const input: []const u8 = @embedFile("input.txt"); const part1, const part2 = try problem(input); std.debug.print("Part 1: {}\n", .{part1}); std.debug.print("Part 2: {}\n", .{part2}); } fn problem(input: []const u8) !struct { u64, u64 } { var lines: mem.TokenIterator(u8, .scalar) = mem.tokenizeScalar(u8, input, '\n'); var part1: u64 = 0; var part2: u64 = 0; var pos: u32 = 50; while (lines.next()) |line| { const n = try parseline(line); part2 += countzeros(pos, n); if (pos == 0) part1 += 1; pos = rotatepos(pos, n); } return .{ part1, part2 }; } fn parseline(l: []const u8) !i64 { return switch (l[0]) { 'L' => try std.fmt.parseInt(i64, l[1..], 10), 'R' => - try std.fmt.parseInt(i64, l[1..], 10), else => error{InvalidLine}.InvalidLine, }; } inline fn rotatepos(pos: u32, n: i64) u32 { return @truncate(@abs(@mod(pos + n, 100))); } fn countzeros(pos: u64, n: i64) u64 { var zeros: u64 = 0; var x: u32 = @intCast(pos); var clicks: u64 = @abs(n); const y: i64 = if (n < 0) -1 else 1; while (clicks > 0) : (clicks -= 1){ x = rotatepos(x, y); if (x == 0) zeros += 1; } return zeros; } test "Sample Input" { const input: []const u8 = @embedFile("input_sample.txt"); const part1, const part2 = try problem(input); std.debug.print("Part 1: {}\n", .{part1}); std.debug.print("Part 2: {}\n", .{part2}); try std.testing.expectEqual(3, part1); try std.testing.expectEqual(6, part2); }