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}); }