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.

138 lines
3.4 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: *Self, needle: T) bool {
for (0..self.length) |i| {
if (self.mem[i] == needle) {
return true;
}
}
return false;
}
fn getMutableSlice(self: *Self) []T {
return (&self.mem)[0..self.length];
}
fn getSlice(self: *const Self) []const T {
return self.mem[0..self.length];
}
fn init() Self {
return Self{
.mem = undefined,
.length = 0,
};
}
};
}
fn addDigit(result: anytype, digit: u8) void {
result.* = (result.* * 10) + (digit - '0');
}
fn canStartWithGroup(springs: []const u8, group_size: usize) bool {
if (springs.len < group_size) {
return false;
}
if (springs.len > group_size and springs[group_size] == '#') {
return false;
}
var i: usize = 0;
while (i < group_size) : (i += 1) {
if (springs[i] == '.') {
return false;
}
}
return true;
}
fn solve(springs: []const u8, groups: []const usize) u32 {
if (groups.len == 0) {
for (springs) |char| {
if (char == '#') {
return 0;
}
}
return 1;
}
const first_group_size = groups[0];
if (first_group_size > springs.len) {
return 0;
}
const last_check_index = springs.len + 1 - first_group_size;
var i: usize = 0;
var result: u32 = 0;
while (i < last_check_index) : (i += 1) {
switch (springs[i]) {
'.' => {},
'#' => {
if (canStartWithGroup(springs[i..], first_group_size)) {
result += solve(springs[@min(springs.len, i + first_group_size + 1)..], groups[1..]);
}
break;
},
'?' => {
if (canStartWithGroup(springs[i..], first_group_size)) {
result += solve(springs[@min(springs.len, i + first_group_size + 1)..], groups[1..]);
}
},
else => unreachable,
}
}
return result;
}
fn solveLine(line: []const u8) u32 {
var i: usize = 0;
while (line[i] != ' ') : (i += 1) {}
var springs = line[0..i];
i += 1;
var groups = StackList(usize, usize, 15).init();
while (i < line.len) {
var number: usize = 0;
while (i < line.len and line[i] != ',') : (i += 1) {
addDigit(&number, line[i]);
}
groups.add(number);
i += 1;
}
return solve(springs, groups.getSlice());
}
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 result: u32 = 0;
var line_buffer: [1000]u8 = undefined;
while (try reader.readUntilDelimiterOrEof(&line_buffer, '\n')) |line| {
result += solveLine(line);
}
try stdout.print("{d}\n", .{result});
}