Search code examples
pythondictionarylookup-tablesmagic-numbers

How do I store lookup tables in magic numbers?


I have seen something interesting here, saying you can store lookup tables at magic numbers.

I have tried using brute-force to find the magic number, but all the results are incorrect.

How do I find the correct magic number for a certain lookup table? Thank you.


Solution

  • As the author of that answer puts it:

    The magic number stores the table as a bitstring, with the n-th digit (from the end) corresponding to the nth table entry

    Here's a really simple example:

    Entry   Value   Bit
    -----   -----   ---
      0     True     1
      1     False    0
      2     False    0
      3     True     1
                     b  # needed to indicate
                     0  # 'binary number'
    

    So the "magic number" for this lookup table, reading up from the bottom, is:

    >>> 0b1001  # (1 * 8) + (0 * 4) + (0 * 2) + (1 * 1)
    9
    

    Or, to rotate it:

                  3      2      1      0      | Entry
                  True   False  False  True   | Value
    0      b      1      0      0      1      | Bit    # -> 0b1001
    

    In terms of extracting the output, the right-shift binary operator x >> y moves all bits in x right by y places, truncating the last y bits:

    >>> for x in range(4):
            print(x, '0b{:04b}'.format(9>>x))
    
    
    0 0b1001
    1 0b0100
    2 0b0010
    3 0b0001
    

    and the bitwise AND & 1 tells you the value of the last bit. Getting the results back out:

    >>> for x in range(4):
        print(x, 9>>x&1)
    
    
    0 1
    1 0
    2 0
    3 1
    

    Another example:

    Entry   Value   Bit
    -----   -----   ---
      0     True     1
      1     False    0
      2     True     1
      3     False    0
                     b  # needed to indicate
                     0  # 'binary number'
    

    So the "magic number" for this lookup table, reading up from the bottom, is:

    >>> 0b0101  # (0 * 8) + (1 * 4) + (0 * 2) + (1 * 1)
    5
    

    Or, to rotate it:

                  3      2      1      0      | Entry
                  False  True   False  True   | Value
    0      b      0      1      0      1      | Bit    # -> 0b0101