const std = @import("std");

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

const crabs = 1000;
const CrabType = u11;

const P2 = struct {
    crs: [crabs]CrabType = undefined,
    sum: usize,
};

fn parseInput() anyerror!P2 {
    const in = @embedFile(path);
    const input = std.mem.trimRight(u8, in, "\r\n");
    var crbs = std.mem.tokenize(u8, input, ",");

    var ret = P2{ .sum = 0 };

    var idx: usize = 0;
    while (crbs.next()) |crab| : (idx += 1) {
        const crab_pos = try std.fmt.parseUnsigned(CrabType, crab, 10);
        ret.crs[idx] = crab_pos;
        ret.sum += crab_pos;
    }

    ret.sum = ret.sum / crabs;

    return ret;
}

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

    const crbs = try parseInput();

    var fuel: usize = 0;
    for (crbs.crs) |c| {
        var diff: usize = undefined;
        if (c > crbs.sum) {
            diff = c - crbs.sum;
        } else {
            diff = crbs.sum - c;
        }
        fuel += (diff * (diff + 1)) / 2;
    }
    return fuel;
}

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

    try std.testing.expectEqual(ret, @as(usize, 95851339));

    std.debug.print("Day 7b result: {d} \ttime: {d}us\n", .{ ret, s });
}

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