Advertisement
am1x

mtonum002.cpp

Jan 1st, 2023 (edited)
1,355
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.00 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <inttypes.h>
  3. #include <assert.h>
  4. #include <string.h>
  5.  
  6. const uint32_t N = 100000000;
  7. const uint32_t M = 12, Z = 26, ZA = 32, H = M + 1;
  8.  
  9. static const char* mnames[M + 1] = {
  10.     "",
  11.     "Jan",
  12.     "Feb",
  13.     "Mar",
  14.     "Apr",
  15.     "May",
  16.     "Jun",
  17.     "Jul",
  18.     "Aug",
  19.     "Sep",
  20.     "Oct",
  21.     "Nov",
  22.     "Dec"
  23. };
  24.  
  25.  
  26. static const uint32_t mhash[H] = {0, 2, 6, 1, 10, 4, 7, 11, 3, 8, 9, 12, 5};
  27.  
  28. uint32_t month_to_num(const unsigned char *s)
  29. {
  30.     uint32_t c0 = s[0] - 'A';
  31.     if (Z <= c0)
  32.         return 0;
  33.     uint32_t c1 = s[1] - 'a';
  34.     if (Z <= c1)
  35.         return 0;
  36.     uint32_t c2 = s[2] - 'a';
  37.     if (Z <= c2)
  38.         return 0;
  39.     if (s[3])
  40.         return 0;
  41.     uint32_t z = ((1431655833 * c2) ^ c1) % H;
  42.     if (z == 0)
  43.         return z;
  44.     z = mhash[z];
  45.     assert (0 < z && z <= M);
  46.     const unsigned char *s0 = (const unsigned char *) mnames[z];
  47.     if (s[0] != s0[0] || s[1] != s0[1] || s[2] != s0[2])
  48.         return 0;
  49.     return z;
  50. }
  51.  
  52.  
  53. static uint32_t mbs[M + 1][2] = {
  54.     {0, 0},
  55.     {0x417072, 4},
  56.     {0x417567, 8},
  57.     {0x446563, 12},
  58.     {0x466562, 2},
  59.     {0x4a616e, 1},
  60.     {0x4a756c, 7},
  61.     {0x4a756e, 6},
  62.     {0x4d6172, 3},
  63.     {0x4d6179, 5},
  64.     {0x4e6f76, 11},
  65.     {0x4f6374, 10},
  66.     {0x536570, 9}
  67. };
  68.  
  69. uint32_t month_to_num_bs(const unsigned char *s)
  70. {
  71.     uint32_t c0 = s[0];
  72.     if (!c0)
  73.         return 0;
  74.     uint32_t c1 = s[1];
  75.     if (!c1)
  76.         return 0;
  77.     uint32_t c2 = s[2];
  78.     if (!c2)
  79.         return 0;
  80.     if (s[3])
  81.         return 0;
  82.     uint32_t z = c0 * 65536 + c1 * 256 + c2;
  83.  
  84.     uint32_t k;
  85. #if 1
  86. #if 0
  87.     if (z <= mbs[6][0]) {
  88.         k = (z <= mbs[3][0]) ? 3 : 6;
  89.     } else {
  90.         k = (z <= mbs[9][0]) ? 9 : M;
  91.     }
  92. #else
  93.     k = (z <= mbs[6][0]) ? 6 : M;
  94. #endif
  95. #else
  96.     k = M;
  97. #endif
  98.  
  99.     for (; z < mbs[k][0]; k--)
  100.         ;
  101.     return mbs[k][0] == z ? mbs[k][1] : 0;
  102. }
  103.  
  104.  
  105. static uint8_t tree[20][ZA];
  106.  
  107. void prepare_tree()
  108. {
  109.     memset(tree, 0, sizeof(tree));
  110.     uint32_t tree_size = 2;
  111.     for (uint32_t i = 1; i <= M; i++) {
  112.         uint8_t p = 1;
  113.  
  114.         uint32_t c = mnames[i][0] - 'A';
  115.         assert (c < Z);
  116.         if (tree[p][c] == 0) {
  117.             tree[p][c] = tree_size++;
  118.         }
  119.         p = tree[p][c];
  120.  
  121.         c = mnames[i][1] - 'a';
  122.         assert (c < Z);
  123.         if (tree[p][c] == 0) {
  124.             tree[p][c] = tree_size++;
  125.         }
  126.         p = tree[p][c];
  127.  
  128.         c = mnames[i][2] - 'a';
  129.         assert (c < Z);
  130.         assert (tree[p][c] == 0);
  131.         tree[p][c] = i;
  132.     }
  133.     // printf("tree_size = %u \n", tree_size);
  134. }
  135.  
  136. uint32_t month_to_num_tree(const unsigned char *s)
  137. {
  138.     uint32_t c0 = s[0] - 'A';
  139.     if (Z <= c0)
  140.         return 0;
  141.     uint32_t p = tree[1][c0];
  142.  
  143.     uint32_t c1 = s[1] - 'a';
  144.     if (Z <= c1)
  145.         return 0;
  146.     p = tree[p][c1];
  147.  
  148.     uint32_t c2 = s[2] - 'a';
  149.     if (Z <= c2)
  150.         return 0;
  151.     p = tree[p][c2];
  152.  
  153.     if (s[3])
  154.         return 0;
  155.     return p;
  156. }
  157.  
  158.  
  159. int main()
  160. {
  161.     prepare_tree();
  162. #if 1
  163.     uint32_t acc = 0;
  164.     for (uint32_t j = 0; j < N; j++) {
  165.         for (uint32_t i = 0; i <= M; i++) {
  166.             acc += month_to_num_tree((const unsigned char*) mnames[i]);
  167.         }
  168.     }
  169.     printf("acc = %u \n", acc);
  170. #endif
  171.  
  172.     for (uint32_t i = 0; i <= M; i++) {
  173.         uint32_t z = month_to_num_tree((const unsigned char*) mnames[i]);
  174.         printf("%3s %2u %2u \n", mnames[i], z, i);
  175.     }
  176.  
  177.     return 0;
  178. }
  179.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement