#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define MAX 100
#define MIN 0
#define HIT 1

#define ANSI_BOLD "\033[1m"
#define ANSI_RESET "\033[0m"
#define ANSI_CYAN "\033[36m"
#define ANSI_GREEN "\033[32m"
#define ANSI_MAGENTA "\033[35m"

unsigned long long rndm()
{
    unsigned long long r = 0;
    FILE *urand = fopen("/dev/urandom", "r");
    if (urand)
    {
        fread(&r, sizeof(r), 1, urand);
        fclose(urand);
    }
    return r % (MAX - MIN + 1) + MIN;
}

int main()
{
    srand(time(NULL));

    int hit = HIT;
    int maxHit = MAX;
    int try = 1;
    clock_t start_time = clock();
    double fastestTime = -1.0;
    int fastestNumber = -1;
    int totalTries = 1;

    while (hit <= maxHit)
    {
        //printf(ANSI_BOLD ANSI_CYAN "Searching for %d (%d of %d)...\n" ANSI_RESET, hit, hit, maxHit);

        while (1)
        {
            totalTries++;
            unsigned long long r = rndm();
            if (r == hit)
            {
                clock_t end_time = clock();
                double elapsed_time = (double)(end_time - start_time) / CLOCKS_PER_SEC;

                //printf(ANSI_BOLD ANSI_GREEN "Found %lld after %d tries\n" ANSI_RESET, r, try);
                //printf(ANSI_MAGENTA "Search took %.10f seconds.\n" ANSI_RESET, elapsed_time);

                if (fastestTime < 0 || elapsed_time < fastestTime)
                {
                    fastestTime = elapsed_time;
                    fastestNumber = r;
                }

                hit++;
                try = 1;
                start_time = clock();
                break;
            }
            else
            {
                try++;
            }
        }
    }

    clock_t finalEnd = clock();
    double elapsed_time = (double)(finalEnd - start_time) / CLOCKS_PER_SEC;

    printf("--------------------------\n");
    printf(ANSI_BOLD ANSI_GREEN "Search is done. " ANSI_MAGENTA "(Took %.20f seconds)\n" ANSI_RESET, elapsed_time);
    printf(ANSI_GREEN "Fastest number found: " ANSI_BOLD "%d\n" ANSI_RESET, fastestNumber);
    printf(ANSI_GREEN "Time for fastest number: " ANSI_BOLD "%.10f seconds\n" ANSI_RESET, fastestTime);
    printf(ANSI_GREEN "Total number of tries: " ANSI_BOLD "%d\n" ANSI_RESET, totalTries - 1);
    printf("--------------------------\n");
    return 0;
}