// lottery.c — planificación por lotería con una lista de trabajos.
//
// Uso: ./lottery <semilla> <quanta> <boletos1> <boletos2> ...
// Ejemplo: ./lottery 7 20 100 50
//
// En cada quantum se sortea un número entre 0 y el total de boletos - 1, y se
// recorre la lista sumando boletos hasta pasar el número: ese trabajo gana.
#include <stdio.h>
#include <stdlib.h>

#define MAX_JOBS 8
#define SHOW 20  // cuántos sorteos mostrar uno por uno

struct job {
    char name;
    int tickets;
    int wins;
};

// Generador pseudoaleatorio simple (xorshift32): mismo resultado en
// cualquier máquina para la misma semilla.
static unsigned int rng_state;

static unsigned int next_random(void) {
    unsigned int x = rng_state;
    x ^= x << 13;
    x ^= x >> 17;
    x ^= x << 5;
    rng_state = x;
    return x;
}

// Recorre la lista sumando boletos hasta pasar al ganador: O(n).
static int pick_winner(struct job *jobs, int n, int winner) {
    int counter = 0;
    for (int i = 0; i < n; i++) {
        counter += jobs[i].tickets;
        if (counter > winner)
            return i;
    }
    return n - 1;  // no debería pasar
}

int main(int argc, char *argv[]) {
    if (argc < 4 || argc - 3 > MAX_JOBS) {
        fprintf(stderr, "uso: %s <semilla> <quanta> <boletos>...\n", argv[0]);
        return 1;
    }
    rng_state = (unsigned int)atoi(argv[1]);
    if (rng_state == 0)
        rng_state = 1;  // xorshift no admite estado 0
    int quanta = atoi(argv[2]);
    int n = argc - 3;

    struct job jobs[MAX_JOBS];
    int total = 0;
    for (int i = 0; i < n; i++) {
        jobs[i].name = 'A' + i;
        jobs[i].tickets = atoi(argv[3 + i]);
        jobs[i].wins = 0;
        total += jobs[i].tickets;
    }

    for (int q = 0; q < quanta; q++) {
        int ticket = next_random() % total;  // el boleto sorteado
        int w = pick_winner(jobs, n, ticket);
        jobs[w].wins++;
        if (q < SHOW)
            printf("quantum %2d: boleto %3d -> %c\n", q + 1, ticket, jobs[w].name);
    }
    if (quanta > SHOW)
        printf("... (%d quanta más)\n", quanta - SHOW);

    printf("\n  boletos  esperado  obtenido\n");
    for (int i = 0; i < n; i++)
        printf("%c %7d  %7.1f%%  %7.1f%%\n", jobs[i].name, jobs[i].tickets,
               100.0 * jobs[i].tickets / total, 100.0 * jobs[i].wins / quanta);
    return 0;
}
