1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
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);
}
|