const std = @import("std");

const path = "data/day03/input.txt";

const RetType = u24;
const line_size = getLineSize();

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

    const input = @embedFile(path);
    var lines = std.mem.split(u8, input, "\n");

    var ones = [_]u10{0} ** line_size;
    var zeros = [_]u10{0} ** line_size;

    while (lines.next()) |line| {
        for (line) |bit, idx| {
            if (bit == '0') {
                zeros[idx] += 1;
            } else {
                ones[idx] += 1;
            }
        }
    }

    var gammaRate: [line_size]u8 = undefined;
    var epsilonRate: [line_size]u8 = undefined;

    for (ones) |val, i| {
        if (val > zeros[i]) {
            gammaRate[i] = '1';
            epsilonRate[i] = '0';
        } else {
            gammaRate[i] = '0';
            epsilonRate[i] = '1';
        }
    }

    const gr = try std.fmt.parseUnsigned(RetType, &gammaRate, 2);
    const er = try std.fmt.parseUnsigned(RetType, &epsilonRate, 2);

    return gr * er;
}

fn getLineSize() usize {
    const input = @embedFile(path);

    var ret: usize = 0;
    for (input) |bit, idx| {
        if (bit == '\n') {
            ret = idx;
            break;
        }
    }

    return ret;
}

pub fn main() anyerror!void {
    var timer = try std.time.Timer.start();
    const ret = try first(null);
    const f = timer.lap() / 1000;

    try std.testing.expectEqual(@as(RetType, 3847100), ret);

    std.debug.print("Day 3a result: {d} \t\ttime: {d}us\n", .{ ret, f });
}

test "day03a" {
    try std.testing.expectEqual(@as(RetType, 3847100), try first(std.testing.allocator));
}