-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday17.zig
98 lines (85 loc) · 3.17 KB
/
day17.zig
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
const std = @import("std");
const print = std.debug.print;
const input = @embedFile("input17.txt");
const Registers = struct { a: u32, b: u32, c: u32 };
fn combo(v: u8, regs: Registers) !u32 {
if (v <= 3) return v
else if (v == 4) return regs.a
else if (v == 5) return regs.b
else if (v == 6) return regs.c;
return error.ComboOperand7;
}
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}).init;
defer if (gpa.deinit() != .ok) @panic("GPA LEAK");
const alloc = gpa.allocator();
var num_strs = std.mem.tokenizeAny(u8, input, "RegisterABCProgram:, \n");
const a_str = num_strs.next() orelse return error.MissingRegisterA;
const b_str = num_strs.next() orelse return error.MissingRegisterB;
const c_str = num_strs.next() orelse return error.MissingRegisterC;
var regs: Registers = .{
.a = try std.fmt.parseInt(u32, a_str, 10),
.b = try std.fmt.parseInt(u32, b_str, 10),
.c = try std.fmt.parseInt(u32, c_str, 10),
};
var program = std.ArrayListUnmanaged(u8).empty;
defer program.deinit(alloc);
while (num_strs.next()) |num_str| {
const num = try std.fmt.parseInt(u8, num_str, 10);
try program.append(alloc, num);
}
var output = std.ArrayListUnmanaged(u8).empty;
defer output.deinit(alloc);
var ip: usize = 0;
while (ip < program.items.len) {
switch (program.items[ip]) {
0 => { // adv
const operand = try combo(program.items[ip + 1], regs);
const divisor = std.math.pow(u32, 2, operand);
regs.a = @divFloor(regs.a, divisor);
},
1 => { //bxl
regs.b = regs.b ^ program.items[ip + 1];
},
2 => { // bst
regs.b = (try combo(program.items[ip + 1], regs)) % 8;
},
3 => { // jnz
if (regs.a != 0) {
ip = program.items[ip + 1];
continue;
}
},
4 => { // bxc
regs.b = regs.b ^ regs.c;
},
5 => { // out
const value = try combo(program.items[ip + 1], regs);
try output.append(alloc, @intCast(value % 8));
},
6 => { // bdv
const operand = try combo(program.items[ip + 1], regs);
const divisor = std.math.pow(u32, 2, operand);
regs.b = @divFloor(regs.a, divisor);
},
7 => { // cdv
const operand = try combo(program.items[ip + 1], regs);
const divisor = std.math.pow(u32, 2, operand);
regs.c = @divFloor(regs.a, divisor);
},
else => unreachable,
}
ip += 2;
}
if (output.items.len > 0) {
print("{d}", .{output.items[0]});
for (output.items[1..]) |o| print(",{d}", .{o});
print("\n", .{});
}
//print("{s}", .{input});
//while (num_strs.next()) |ns| print("{s}\n", .{ns});
//print("{d} {d} {d}\n", .{ regs.a, regs.b, regs.c });
//print("{d}\n", .{program.items.len});
//_ = ®s;
}
test "decls" { std.testing.refAllDecls(@This()); }