You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.5 KiB
129 lines
3.5 KiB
1 year ago
|
const std = @import("std");
|
||
|
|
||
|
fn StackList(comptime T: type, comptime capacity_type: type, comptime capacity: capacity_type) type {
|
||
|
return struct {
|
||
|
const Self = @This();
|
||
|
mem: [capacity]T,
|
||
|
length: capacity_type,
|
||
|
|
||
|
fn add(self: *Self, value: T) void {
|
||
|
self.mem[self.length] = value;
|
||
|
self.length += 1;
|
||
|
}
|
||
|
|
||
|
fn has(self: *const Self, needle: T) bool {
|
||
|
for (0..self.length) |i| {
|
||
|
if (self.mem[i] == needle) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
fn getSlice(self: *Self) []T {
|
||
|
//var mem_full_slice = &self.mem;
|
||
|
//var mem_slice: []T = mem_full_slice[0..self.length];
|
||
|
//return mem_slice;
|
||
|
return (&self.mem)[0..self.length];
|
||
|
}
|
||
|
|
||
|
fn getLoopedValue(self: *const Self, index: usize) T {
|
||
|
return self.mem[index % self.length];
|
||
|
}
|
||
|
|
||
|
fn reset(self: *Self) void {
|
||
|
self.length = 0;
|
||
|
}
|
||
|
|
||
|
fn init() Self {
|
||
|
return Self{
|
||
|
.mem = undefined,
|
||
|
.length = 0,
|
||
|
};
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
const SIXTEEN_BITS = 65535;
|
||
|
|
||
|
const Directions = StackList(usize, usize, 1000);
|
||
|
|
||
|
fn parseDirections(line: []const u8) Directions {
|
||
|
var result = Directions.init();
|
||
|
|
||
|
const left: usize = SIXTEEN_BITS << 16;
|
||
|
const right: usize = SIXTEEN_BITS;
|
||
|
|
||
|
var index: usize = 0;
|
||
|
while (index < line.len) : (index += 1) {
|
||
|
result.add(switch (line[index]) {
|
||
|
'L' => left,
|
||
|
'R' => right,
|
||
|
else => unreachable,
|
||
|
});
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
const Nodes = [26 * 26 * 26]usize;
|
||
|
|
||
|
fn parseNodeNumber(line: []const u8) usize {
|
||
|
var result: usize = 0;
|
||
|
for (line) |char| {
|
||
|
result = (result * 26) + (char - 'A');
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
fn parseNodeLine(line: []const u8, state: *Nodes) usize {
|
||
|
const current_node_number = parseNodeNumber(line[0..3]);
|
||
|
state[current_node_number] = (parseNodeNumber(line[7..10]) << 16) | parseNodeNumber(line[12..15]);
|
||
|
return current_node_number;
|
||
|
}
|
||
|
|
||
|
fn solve(nodes: Nodes, directions: Directions, start: usize, end: usize) usize {
|
||
|
var current = start;
|
||
|
var i: usize = 0;
|
||
|
while (current != end) : (i += 1) {
|
||
|
const mask = nodes[current] & directions.getLoopedValue(i);
|
||
|
current = (mask | (mask >> 16)) & SIXTEEN_BITS;
|
||
|
|
||
|
//if (i % directions.length == 0) {
|
||
|
//std.debug.print("Iteration {d}; current: {d}\n", .{ i, current });
|
||
|
//}
|
||
|
}
|
||
|
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
pub fn main() !void {
|
||
|
const stdout = std.io.getStdOut().writer();
|
||
|
|
||
|
const raw_in = std.io.getStdIn();
|
||
|
var buffered_reader = std.io.bufferedReader(raw_in.reader());
|
||
|
var reader = buffered_reader.reader();
|
||
|
|
||
|
var line_buffer: [1000]u8 = undefined;
|
||
|
const first_line = (try reader.readUntilDelimiterOrEof(&line_buffer, '\n')).?;
|
||
|
var directions = parseDirections(first_line);
|
||
|
_ = try reader.readUntilDelimiterOrEof(&line_buffer, '\n');
|
||
|
|
||
|
var nodes: Nodes = undefined;
|
||
|
for (&nodes) |*node| {
|
||
|
node.* = (SIXTEEN_BITS << 16) | SIXTEEN_BITS;
|
||
|
}
|
||
|
const third_line = (try reader.readUntilDelimiterOrEof(&line_buffer, '\n')).?;
|
||
|
const start = parseNodeLine(third_line, &nodes);
|
||
|
_ = start;
|
||
|
var end: usize = 0;
|
||
|
while (try reader.readUntilDelimiterOrEof(&line_buffer, '\n')) |line| {
|
||
|
end = parseNodeLine(line, &nodes);
|
||
|
}
|
||
|
|
||
|
const result = solve(nodes, directions, 0, nodes.len - 1);
|
||
|
try stdout.print("{d}\n", .{result});
|
||
|
}
|