Solutions of most (39 out of 50 so far) puzzles in Zig (system language, alternative for C). My first experience with it.
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.

128 lines
3.5 KiB

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