// Crecer copiando las casillas, sin reinsertar: las claves siguen ahí, y ya no se encuentran.
// Uso: naive_copy archivo_de_palabras
#include <algorithm>
#include <cstddef>
#include <iostream>
#include <string>
#include <vector>

#include "hash_functions.h"
#include "word_file.h"

using Slots = std::vector<std::vector<std::string>>;

bool found(const Slots& slots, const std::string& word) {
    const std::vector<std::string>& chain = slots[fnv1a(word) % slots.size()];
    return std::find(chain.begin(), chain.end(), word) != chain.end();
}

std::size_t count_found(const Slots& slots, const std::vector<std::string>& words) {
    std::size_t count = 0;
    for (const std::string& word : words) {
        count += found(slots, word) ? 1 : 0;
    }
    return count;
}

int main(int argc, char** argv) {
    if (argc != 2) {
        std::cerr << "uso: naive_copy archivo_de_palabras\n";
        return 1;
    }
    std::vector<std::string> words = read_words(argv[1]);
    for (const std::string word : {"lima", "cusco", "tacna", "puno", "arequipa"}) {
        std::uint64_t hash = fnv1a(word);
        std::cout << word << ": hash % 8 = " << hash % 8 << ", hash % 16 = " << hash % 16 << "\n";
    }
    Slots slots(1024);
    for (const std::string& word : words) {
        slots[fnv1a(word) % slots.size()].push_back(word);
    }
    std::cout << "con 1024 casillas: " << count_found(slots, words) << " de " << words.size() << " encontradas\n";
    Slots copied = slots;
    copied.resize(2048);
    std::cout << "copiando a 2048:   " << count_found(copied, words) << " de " << words.size() << " encontradas\n";
    Slots reinserted(2048);
    for (const std::string& word : words) {
        reinserted[fnv1a(word) % reinserted.size()].push_back(word);
    }
    std::cout << "reinsertando:      " << count_found(reinserted, words) << " de " << words.size() << " encontradas\n";
}
