Advent of Code 2020 solutions in Zig
const std = @import("std");

const Str = []const u8;

const PATH = "input/day05.txt";
const ROWS = 876;
const SMALLEST = 99;

pub fn first(allocator: ?std.mem.Allocator) anyerror!usize {
    _ = allocator;

    const file = @embedFile(PATH);
    var passes = std.mem.tokenize(u8, file, "\n");

    var max: usize = 0;

    while (passes.next()) |pass| {
        const row = getRow(pass);
        const col = getCol(pass[7..]);
        const id = row * 8 + col;
        if (id > max) max = id;
    }

    return max;
}

pub fn second(allocator: ?std.mem.Allocator) anyerror!usize {
    _ = allocator;

    const file = @embedFile(PATH);
    var passes = std.mem.tokenize(u8, file, "\n");

    var seats = std.StaticBitSet(ROWS).initFull();

    while (passes.next()) |pass| {
        const row = getRow(pass);
        const col = getCol(pass[7..]);
        const id = row * 8 + col;
        seats.unset(id - SMALLEST);
    }

    return seats.findFirstSet().? + SMALLEST;
}

fn getRow(in: Str) usize {
    var min: usize = 0;
    var max: usize = 127;
    for (in) |ch| {
        switch (ch) {
            'F' => max = min + (max - min) / 2,
            'B' => min += (max - min) / 2 + 1,
            else => break,
        }
        // std.debug.print("{d} {d}\n", .{ min, max });
    }
    return min;
}

fn getCol(in: Str) usize {
    var min: usize = 0;
    var max: usize = 7;
    for (in) |ch| {
        switch (ch) {
            'L' => max = min + (max - min) / 2,
            'R' => min += (max - min) / 2 + 1,
            else => unreachable,
        }
        // std.debug.print("{d} {d}\n", .{ min, max });
    }
    return min;
}

test "getRow" {
    try std.testing.expectEqual(@as(usize, 44), getRow("FBFBBFFRLR"));
}

test "getCol" {
    try std.testing.expectEqual(@as(usize, 5), getCol("RLR"));
}

test "day05a" {
    try std.testing.expectEqual(@as(usize, 974), try first(std.testing.allocator));
}

test "day05b" {
    try std.testing.expectEqual(@as(usize, 646), try second(std.testing.allocator));
}