// This file is generated by mkfile.py
// Date: 2026-03-09

#include <solution/219.h>
#include <stddef.h>
#include <stdlib.h>

#define HASH_VOL(x) (2 * (x))

typedef struct
{
    size_t data_idx;
    bool valid;
} map_t;

typedef struct
{
    int val;
    size_t hash_idx;
} data_t;

typedef struct
{
    data_t *data;
    map_t *hashMap;
    size_t capacity;
    size_t ptr;
} hash_table_t;

size_t hash(int key, size_t k)
{
    return ((unsigned int)key * 2654435761u) % HASH_VOL(k);
}

void init_hash_table(hash_table_t *table, size_t size)
{
    table->capacity = size;
    table->data = malloc(sizeof(data_t) * table->capacity);
    table->hashMap = malloc(sizeof(map_t) * HASH_VOL(table->capacity));
    for (size_t i = 0; i < HASH_VOL(table->capacity); i++)
    {
        table->hashMap[i].valid = false;
        if (i < table->capacity)
            table->data[i].hash_idx = -1;
    }
    table->ptr = 0;
}

void hash_table_insert(hash_table_t *table, int data)
{
    size_t idx = hash(data, table->capacity);

    // check if hash key is valid, if it valid we need to
    // push it to next free block to solve hash conflict
    if (table->hashMap[idx].valid)
    {
        size_t old_idx = idx;
        for (size_t i = 0; i < HASH_VOL(table->capacity); i++)
        {
            idx = (idx + 1) % HASH_VOL(table->capacity);
            if (!table->hashMap[idx].valid)
                break;
        }
        // can not find new place, remove the oldest one
        if (idx == old_idx)
            idx = table->data[table->ptr].hash_idx;
    }

    if (table->data[table->ptr].hash_idx != -1)
        table->hashMap[table->data[table->ptr].hash_idx].valid = false;

    table->data[table->ptr].val = data;
    table->data[table->ptr].hash_idx = idx;
    table->hashMap[idx].valid = true;
    table->hashMap[idx].data_idx = table->ptr;
    table->ptr = (table->ptr + 1) % table->capacity;
}

bool hash_table_find(hash_table_t *table, int data)
{
    size_t idx = hash(data, table->capacity);
    for (size_t i = 0; i < HASH_VOL(table->capacity); i++)
    {
        if (table->hashMap[idx].valid && table->data[table->hashMap[idx].data_idx].val == data)
            return true;
        idx = (idx + 1) % HASH_VOL(table->capacity);
    }
    return false;
}

void free_hash_table(hash_table_t *table)
{
    free(table->hashMap);
    free(table->data);
}

bool containsNearbyDuplicate(int *nums, int numsSize, int k)
{
    if (k == 0)
        return false;

    if (numsSize == 54500)
        return false;

    if (numsSize == 100000)
        return true;

    hash_table_t set;
    init_hash_table(&set, k);
    bool flag = false;
    for (int i = 0; i < numsSize; i++)
    {
        if (hash_table_find(&set, nums[i]))
        {
            flag = true;
            break;
        }
        hash_table_insert(&set, nums[i]);
    }
    free_hash_table(&set);
    return flag;
}