const std = @import("std");

const max_score = 1000;
const p1_start = 7;
const p2_start = 9;

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

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

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

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

    var p1_pos: usize = p1_start;
    var p2_pos: usize = p2_start;

    var p1_score: usize = 0;
    var p2_score: usize = 0;

    var dice: usize = 1;

    var round: usize = 1;
    while (true) : (round += 1) {
        // player 1
        const d1 = (p1_pos + dice + dice + 1 + dice + 2) % 10;
        if (d1 == 0) p1_pos = 10 else p1_pos = d1;
        p1_score += p1_pos;
        dice += 3;

        // std.debug.print("p1: {d} {d}\n", .{ p1_pos, p1_score });

        if (p1_score >= max_score) {
            return p2_score * (6 * round - 3);
        }

        // player 2
        const d2 = (p2_pos + dice + dice + 1 + dice + 2) % 10;
        if (d2 == 0) p2_pos = 10 else p2_pos = d2;
        p2_score += p2_pos;
        dice += 3;

        // std.debug.print("p2: {d} {d}\n", .{ p2_pos, p2_score });

        if (p2_score >= max_score) {
            return p1_score * (6 * round);
        }
    }
}

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