代码之家  ›  专栏  ›  技术社区  ›  Aadit M Shah

如何旋转居中的六边形位板?

  •  1
  • Aadit M Shah  · 技术社区  · 6 年前

    考虑以下几点 centered hexagonal 位板表示法(填充为黑体):

                    56
                55      49
            54      48      42
        53      47      41      35
    52      46      40      34      28
        45      39      33      27
    44      38      32      26      20
        37      31      25      19
    36      30      24      18      12
        29      23      17      11
    28      22      16      10      04
        21      15      09      03
    20      14      08      02      60
        13      07      01      59
            06      00      58
                63      57
                    56

    42  43  44  45  46  47  48
    
    35  36  37  38  39  40  41
    
    28  29  30  31  32  33  34
    
    21  22  23  24  25  26  27
    
    14  15  16  17  18  19  20
    
    07  08  09  10  11  12  13
    
    00  01  02  03  04  05  06

    1 回复  |  直到 6 年前
        1
  •  3
  •   user555045    6 年前

    这种排列有点混乱,每个相关位都有一个明显的移动距离。排列图如下所示(输出顶行):

    perm diagram

    不过,这确实说明了一些方法。如果我们靠近顶部看,每个“组”都是通过按升序从输入中收集一些位形成的,因此可以用7来完成 compress_right 操作aka PEXT

    所以如果 佩克斯

    uint64_t g0 = _pext_u64(in, 0x8080808);
    uint64_t g1 = _pext_u64(in, 0x404040404);
    uint64_t g2 = _pext_u64(in, 0x20202020202);
    uint64_t g3 = _pext_u64(in, 0x1010101010101);
    uint64_t g4 = _pext_u64(in, 0x808080808080);
    uint64_t g5 = _pext_u64(in, 0x404040404000);
    uint64_t g6 = _pext_u64(in, 0x202020200000);
    uint64_t out = g0 |  (g1 << 7) |  (g2 << 14) | (g3 << 21) |
                   (g4 << 28) | (g5 << 35) | (g6 << 42);
    

    这种排列不能通过蝶形网络进行路由,但是Bene网络是通用的,因此可以工作。

    所以可以用11个 these 置换步骤,也称为增量交换:

    word bit_permute_step(word source, word mask, int shift) {
      word t;
      t = ((source >> shift) ^ source) & mask;
      return (source ^ t) ^ (t << shift);
      }
    

    x = bit_permute_step(x, 0x1001400550054005, 1);
    x = bit_permute_step(x, 0x2213223111023221, 2);
    x = bit_permute_step(x, 0x01010B020104090E, 4);
    x = bit_permute_step(x, 0x002900C400A7007B, 8);
    x = bit_permute_step(x, 0x00000A0400002691, 16);
    x = bit_permute_step(x, 0x0000000040203CAD, 32);
    x = bit_permute_step(x, 0x0000530800001CE0, 16);
    x = bit_permute_step(x, 0x000C001400250009, 8);
    x = bit_permute_step(x, 0x0C00010403080104, 4);
    x = bit_permute_step(x, 0x2012000011100100, 2);
    x = bit_permute_step(x, 0x0141040000000010, 1);