// Session 67: deterministic rank-to-symbol histogram batch, 29-symbol lists.
#include <cstdint>
#include <cstring>

extern "C" void recency_histograms(const uint8_t* cipher, const uint8_t* flags,
    int n, const uint8_t* keys, int key_count, int cutoff, int back,
    int32_t* prefix, int32_t* suffix) {
    for (int k = 0; k < key_count; ++k) {
        uint8_t state[29];
        int32_t* h0 = prefix + 29*k;
        int32_t* h1 = suffix + 29*k;
        std::memset(h0, 0, 29*sizeof(int32_t));
        std::memset(h1, 0, 29*sizeof(int32_t));
        const uint8_t* key = keys + 29*k;
        for (int i = 0; i < n; ++i) {
            if (i == 0 || flags[i]) {
                for (int j = 0; j < 29; ++j) state[j] = static_cast<uint8_t>(j);
            }
            int position = key[cipher[i]];
            uint8_t selected = state[position];
            if (i < cutoff) ++h0[selected]; else ++h1[selected];
            if (back) {
                std::memmove(state+position, state+position+1, 28-position);
                state[28] = selected;
            } else {
                std::memmove(state+1, state, position);
                state[0] = selected;
            }
        }
    }
}
