Compress 8 bits to 6 when certain bit patterns will never occur Consider an eight bit number in which an even position bit will never be 1 if one of its neighbors is 0 (considering MSB and LSB as neighbors). There are fewer than 64 such numbers, so there is at least some reversible mapping of them to 6 bit numbers.

Your task is to write a pair of functions (or code blocks or your language equivalent), one of which takes an 8-bit number and returns a 6-bit number, the other which reverses the process. "Numbers" here can be literal numbers or a list of booleans or even a string of Xs and Os.

Put another way, the following bit patterns will never occur:

......01
.....10.
....01..
...10...
..01....
.10.....
01......
0......1


PS: I'd really love to see an answer in Lua :)

PPS: Bonus imaginary internet points if you can pack the 47 valid values into a 6-bit number with a maximum of value of 47
Python, 60 bytes



l=[n^170for n in range(256)if n&amp;n*2&lt;1]
l.index,l.__getitem__


Try it online!

l.index compresses and l.__getitem__ decompresses. We just make a list l of all valid patterns as 8-bit numbers, except we ignore wrapping around, which still leaves 55 options which fits in 6 bits.

A useful idea is that if we flip the bits at even positions, which ^170 does, then the condition just becomes "no two 1's are (cyclically) adjacent". This is easy to check without wrapping around using the bit condition n&amp;(n*2)==0, or shorter, n&amp;n*2&lt;1.

Fibonacci numbers

Binary strings with no adjacent ones have interesting connections to Fibonacci numbers. The number of such 8-bit numbers is 55, a Fibonacci number, following the general result. Moreover, Zeckendorf's Theorem tell us that each number can be uniquely expressed in the Fibonacci base without using a pair of adjacent ones, that is as a sum of distinct Fibonacci numbers without two consecutive ones, as these can be merged into the next Fibonacci number.

Perhaps a base conversion to the Zeckendorf Representation can be used for a less brute-force answer than the one here. We've had challenges to convert from and to the Zeckendorf representation, which could be used as the basis of a decoder-encoder pair.

Bonus: 64 bytes

For imaginary internet points, we can tweak the algorithm to accounts for cyclically adjacent ones, so as to limit the compression to 48 valid bit patterns from 55. We do this by modifying the bit check to n&amp;n*2%255&lt;1, at the cost of 4 extra bytes.

64 bytes



l=[n^170for n in range(256)if n&amp;n*2%255&lt;1]
l.index,l.__getitem__


Try it online!

The modulo 255 changes the bit-shift n*2 to a cyclic shift

abcdefgh -&gt; bcdefgha


by moving the post-doubling place value of 256*a to just a. This is, except for n=255, which where n*2%255 is zero, giving a false positive at 255^170=85. But, since the bonus for imaginary internet points gives use one spare slot, with 48 slots for 47 values, we can just live with this hole.