am1x icon

mtonum002.cpp

am1x | PRO | 01/02/23 12:34:25 PM UTC (Edited) | 0 ⭐ | 1798 👁️ | Never ⏰ | []
C++ |

3 KB

|

None

|

0 👍

/

0 👎

#include <stdio.h>
#include <inttypes.h>
#include <assert.h>
#include <string.h>
 
const uint32_t N = 100000000;
const uint32_t M = 12, Z = 26, ZA = 32, H = M + 1;
 
static const char* mnames[M + 1] = {
    "",
    "Jan",
    "Feb",
    "Mar",
    "Apr",
    "May",
    "Jun",
    "Jul",
    "Aug",
    "Sep",
    "Oct",
    "Nov",
    "Dec"
};
 
 
static const uint32_t mhash[H] = {0, 2, 6, 1, 10, 4, 7, 11, 3, 8, 9, 12, 5};
 
uint32_t month_to_num(const unsigned char *s)
{
    uint32_t c0 = s[0] - 'A';
    if (Z <= c0)
        return 0;
    uint32_t c1 = s[1] - 'a';
    if (Z <= c1)
        return 0;
    uint32_t c2 = s[2] - 'a';
    if (Z <= c2)
        return 0;
    if (s[3])
        return 0;
    uint32_t z = ((1431655833 * c2) ^ c1) % H;
    if (z == 0)
        return z;
    z = mhash[z];
    assert (0 < z && z <= M);
    const unsigned char *s0 = (const unsigned char *) mnames[z];
    if (s[0] != s0[0] || s[1] != s0[1] || s[2] != s0[2])
        return 0;
    return z;
}
 
 
static uint32_t mbs[M + 1][2] = {
    {0, 0},
    {0x417072, 4},
    {0x417567, 8},
    {0x446563, 12},
    {0x466562, 2},
    {0x4a616e, 1},
    {0x4a756c, 7},
    {0x4a756e, 6},
    {0x4d6172, 3},
    {0x4d6179, 5},
    {0x4e6f76, 11},
    {0x4f6374, 10},
    {0x536570, 9}
};
 
uint32_t month_to_num_bs(const unsigned char *s)
{
    uint32_t c0 = s[0];
    if (!c0)
        return 0;
    uint32_t c1 = s[1];
    if (!c1)
        return 0;
    uint32_t c2 = s[2];
    if (!c2)
        return 0;
    if (s[3])
        return 0;
    uint32_t z = c0 * 65536 + c1 * 256 + c2;
 
    uint32_t k;
#if 1
#if 0
    if (z <= mbs[6][0]) {
        k = (z <= mbs[3][0]) ? 3 : 6;
    } else {
        k = (z <= mbs[9][0]) ? 9 : M;
    }
#else
    k = (z <= mbs[6][0]) ? 6 : M;
#endif
#else
    k = M;
#endif
 
    for (; z < mbs[k][0]; k--)
        ;
    return mbs[k][0] == z ? mbs[k][1] : 0;
}
 
 
static uint8_t tree[20][ZA];
 
void prepare_tree()
{
    memset(tree, 0, sizeof(tree));
    uint32_t tree_size = 2;
    for (uint32_t i = 1; i <= M; i++) {
        uint8_t p = 1;
 
        uint32_t c = mnames[i][0] - 'A';
        assert (c < Z);
        if (tree[p][c] == 0) {
            tree[p][c] = tree_size++;
        }
        p = tree[p][c];
 
        c = mnames[i][1] - 'a';
        assert (c < Z);
        if (tree[p][c] == 0) {
            tree[p][c] = tree_size++;
        }
        p = tree[p][c];
 
        c = mnames[i][2] - 'a';
        assert (c < Z);
        assert (tree[p][c] == 0);
        tree[p][c] = i;
    }
    // printf("tree_size = %u \n", tree_size);
}
 
uint32_t month_to_num_tree(const unsigned char *s)
{
    uint32_t c0 = s[0] - 'A';
    if (Z <= c0)
        return 0;
    uint32_t p = tree[1][c0];
 
    uint32_t c1 = s[1] - 'a';
    if (Z <= c1)
        return 0;
    p = tree[p][c1];
 
    uint32_t c2 = s[2] - 'a';
    if (Z <= c2)
        return 0;
    p = tree[p][c2];
 
    if (s[3])
        return 0;
    return p;
}
 
 
int main()
{
    prepare_tree();
#if 1
    uint32_t acc = 0;
    for (uint32_t j = 0; j < N; j++) {
        for (uint32_t i = 0; i <= M; i++) {
            acc += month_to_num_tree((const unsigned char*) mnames[i]);
        }
    }
    printf("acc = %u \n", acc);
#endif
 
    for (uint32_t i = 0; i <= M; i++) {
        uint32_t z = month_to_num_tree((const unsigned char*) mnames[i]);
        printf("%3s %2u %2u \n", mnames[i], z, i);
    }
 
    return 0;
}
 

Comments