5
\$\begingroup\$

The reverse of an n-bit number is just its n binary digits in reverse order:

001010010 → 010010100

Given a number n, generate all n-bit integers ([0, 2n-1]) in an arbitrary order, with only one restriction: there must be a splitting point such that the reverse of an integer is on the opposite side of the splitting point. Integers which are their own reverse must come before the splitting point.

Other than this single splitting point there are no restrictions, all the integers before or after it may come in whatever order you desire.

Example for 4 bits (you don't have to generate this order):

0000, 0001, 0010, 0011, 0101, 0110, 0111, 1001, 1011, 1111,
0100, 1000, 1010, 1100, 1101, 1110

You may output the integers as their binary digits or just as integers. You don't have to explicitly output the splitting point.

\$\endgroup\$
  • 1
    \$\begingroup\$ Could you add the splitting point to your example? \$\endgroup\$ – user9206 Jun 3 '17 at 19:51
  • 1
    \$\begingroup\$ To clarify: you want all the n-bit numbers to be partitioned into two subsets, with the property that a number and its reverse are always in different subsets (other than numbers that are their own reverses). Is that right? \$\endgroup\$ – Greg Martin Jun 3 '17 at 19:58
  • \$\begingroup\$ @Lembik It's already there: the newline. \$\endgroup\$ – orlp Jun 4 '17 at 2:16
  • \$\begingroup\$ @GregMartin Correct. \$\endgroup\$ – orlp Jun 4 '17 at 2:16
3
\$\begingroup\$

JavaScript (ES6), 129 114 bytes

f=n=>[...Array(p=1<<n)].map((_,i)=>(p+i).toString(2).slice(1)).sort((a,b)=>g(a)-g(b),g=a=>[...a].reverse().join``<a)

I appear to have stumbled on the code that happens to generate the given example for 4 bits. Edit: Saved 15 bytes thanks to @ConorO'Brien.

\$\endgroup\$
2
\$\begingroup\$

PHP, 80 Bytes

Make 2 Groups in a 2D Array

After the first Group is the splitting point

In the first group are the integers with their own reverse and the integers that are lower than their reverse

for(;$i<1<<$argn;)$r[strrev($b=sprintf("%0{$argn}b",$i++))<$b][]=$b;print_r($r);

Try it online!

PHP>=7.0, 82 Bytes

Make 3 Groups in a 2D Array

After the second Group is the splitting point

In the first group are the integers with their own reverse

In the second group are the integers that are lower than their reverse

Use the Spaceship Operator

for(;$i<2**$argn;)$r[strrev($b=sprintf("%0{$argn}b",$i++))<=>$b][]=$b;print_r($r);

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Jelly, 13 bytes

2ṗ’µżUṢ€QZ;/Q

Try it online!

Group with their reflections, uniquify and sort, then zip.

\$\endgroup\$
1
\$\begingroup\$

Mathematica, 51 bytes (Windows ANSI encoding)

±n_:=SortBy[{0,1}~Tuples~n,(#-Reverse@#).Range@n!&]

Defines a unary function ± taking a positive integer argument and returning a list of lists of 0s and 1s. For example, ±4 returns

{{1, 1, 0, 0}, {1, 0, 0, 0}, {1, 1, 1, 0}, {1, 0, 1, 0}, {0, 1, 0, 0},
 {1, 1, 0, 1}, {0, 0, 0, 0}, {0, 1, 1, 0}, {1, 0, 0, 1}, {1, 1, 1, 1},
 {0, 0, 1, 0}, {1, 0, 1, 1}, {0, 1, 0, 1}, {0, 0, 0, 1}, {0, 1, 1, 1},
 {0, 0, 1, 1}}

SortBy[{0,1}~Tuples~n,...] takes the set of all length-n lists of 0s and 1s and sorts them according to the values that the function ... takes on each such list. It suffices to find a function whose values on a list and its reverse are negatives of each other and whose value is 0 only if the list is its own reverse. Taking the dot product of (the list minus its reverse) and (a sufficiently unbalanced vector, such as Range@n! which is {1!, 2!, ..., n!}) does the trick.

\$\endgroup\$
1
\$\begingroup\$

Pyth, 14 bytes

o&NcNijN2 .5^2

Try it online

How it works

Sort by x / f(x), where f(x0⋅20 + x1⋅21 + x2⋅22 + …) = x0⋅0.50 + x1⋅0.51 + x2⋅0.52 + … (for binary digits xi ∈ {0, 1}). Interestingly, this same ordering works for all n, but with different splitting points. If x is less than or equal to its n bit reversal, then x / f(x) ≤ 2n − 1, otherwise x / f(x) > 2n − 1.

o           ^2Q   sort values [0, …, 2**n-1] by this key:
 &N                 if value is 0, key is 0
   cN               else, key is value divided by
     i    .5          the base 0.5 number whose digits are
      j 2             the base 2 digits of
       N              value
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.