// Compara los 8 bytes de una palabra de control a la vez, con operaciones de bits.
#include <cinttypes>
#include <cstdint>
#include <cstdio>

#include "mini_swiss.h"

namespace {

void show(std::uint64_t ctrl, unsigned char h2) {
    std::printf("buscar h2 = %3u: casillas candidatas:", h2);
    std::uint64_t marks = match_h2(ctrl, h2);
    if (marks == 0) {
        std::printf(" ninguna");
    }
    while (marks != 0) {
        std::printf(" %d", first_marked(marks));
        marks &= marks - 1;
    }
    std::printf("\n");
}

}  // namespace

int main() {
    // El byte de la casilla 0 es el de menor peso.
    const unsigned char bytes[8] = {23, 89, 50, kCtrlEmpty, 89, kCtrlDeleted, 7, kCtrlEmpty};
    std::uint64_t ctrl = 0;
    for (int slot = 7; slot >= 0; slot--) {
        ctrl = (ctrl << 8) | bytes[slot];
    }
    std::printf("palabra de control: 0x%016" PRIx64 "\n", ctrl);
    std::printf("bytes por casilla:");
    for (unsigned char byte : bytes) {
        std::printf(" %u", byte);
    }
    std::printf("\n");
    show(ctrl, 89);
    show(ctrl, 50);
    show(ctrl, 100);
    std::printf("casillas vacías:");
    std::uint64_t marks = match_empty(ctrl);
    while (marks != 0) {
        std::printf(" %d", first_marked(marks));
        marks &= marks - 1;
    }
    std::printf("\n");

    // Un falso positivo: 0x03 justo después de una coincidencia real con 0x02.
    std::printf("otra palabra, bytes por casilla: 2 3 128 128 128 128 128 128\n");
    show(0x0302ULL | (kLowBits * kCtrlEmpty << 16), 2);
    return 0;
}
