Xorting una matriz

105

Conceptualmente, este desafío es realmente simple. Te dan una lista de enteros no negativos . Si es posible, busque un número entero no negativo , de modo que la lista que consiste esté ordenada. Si no existe, la salida debe ser cualquier cosa que no pueda confundirse con un valor válido , por ejemplo, un número negativo, nada, un error, etc.aiNbi = ai XOR NNN

Aquí hay un ejemplo:

[4, 7, 6, 1, 0, 3]

Si tomamos todos los elementos de esta lista XOR 5, obtenemos

[1, 2, 3, 4, 5, 6]

que está ordenado (Tenga en cuenta que no es un requisito que la lista resultante tenga elementos únicos y no contenga lagunas. Si el resultado de tal operación fuera [0, 1, 1, 3]todavía válido). Por otro lado, para la lista

[4, 7, 1, 6, 0, 3]

no Nexiste tal

Puede escribir un programa o función, tomando la entrada a través de STDIN (o la alternativa más cercana), argumento de línea de comando o argumento de función y generando el resultado a través de STDOUT (o la alternativa más cercana), el valor de retorno de la función o el parámetro de función (out).

La entrada puede estar en cualquier lista conveniente o formato de cadena. Puede suponer que son menores que cada uno y que la lista contiene al menos un elemento.ai231

Su código debe manejar cualquiera de los casos de prueba (especialmente los cuatro grandes) en cuestión de segundos.

Aplican reglas estándar de .

Casos de prueba

Para cada caso de prueba que no regresa, -1hay un número infinito de respuestas correctas. El que figura aquí es el más pequeño. Existen soluciones adicionales configurando adicionalmente bits que son los mismos en todos los enteros de la entrada (especialmente aquellos que son más grandes que el bit más significativo en el mayor número de la lista).

[4 7 6 1 0 3] => 5
[4 7 1 6 0 3] => -1
[0 1 3 4 6 7] => 0
[4 2 3 1] => 6
[2 3 0 0 7 7 4 5 11 11] => 2
[2 3 0 0 7 7 5 4 11 11] => -1
[1086101479 748947367 1767817317 656404978 1818793883 1143500039] => -1
[180522983 1885393660 751646477 367706848 331742205 724919510 850844696 2121330641 869882699 1831158987 542636180 1117249765 823387844 731663826 1762069894 240170102 1020696223 1212052937 2041219958 712044033 195249879 1871889904 1787674355 1849980586 1308879787 1743053674 1496763661 607071669 1987302942 178202560 1666170841 1035995406 75303032 1755269469 200581873 500680130 561748675 1749521426 1828237297 835004548 934883150 38711700 1978960635 209243689 1355970350 546308601 590319412 959613996 1956169400 140411967 112601925 88760619 1977727497 672943813 909069787 318174568 385280382 370710480 809689639 557034312 865578556 217468424 346250334 388513751 717158057 941441272 437016122 196344643 379529969 821549457 97008503 872313181 2105942402 603939495 143590999 1580192283 177939344 853074291 1288703007 1605552664 162070930 1325694479 850975127 681702163 1432762307 1994488829 780869518 4379756 602743458 1963508385 2115219284 1219523498 559301490 4191682 1918142271 169309431 346461371 1619467789 1521741606 1881525154] => -1
[37580156 64423492 87193676 91914964 93632157 96332899 154427982 176139560 184435039 228963836 230164674 279802291 301492375 309127664 345705721 370150824 380319820 403997410 410504675 416543032 418193132 424733526 428149607 435596038 477224208 515649925 519407995 525469350 614538124 624884850 642649261 653488151 679260270 685637235 690613185 739141066 825795124 832026691 832633584 833213619 852655299 913744258 917674993 921902522 925691996 931307936 954676047 972992595 997654606 1020009811 1027484648 1052748108 1071580605 1108881241 1113730139 1122392118 1154042251 1170901568 1180031842 1180186856 1206428383 1214066097 1242934611 1243983997 1244736049 1262979035 1312007069 1312030297 1356274316 1368442960 1377432523 1415342434 1471294243 1529353536 1537868913 1566069818 1610578189 1612277199 1613646498 1639183592 1668015280 1764022840 1784234921 1786654280 1835593744 1849372222 1875931624 1877593764 1899940939 2007896363 2023046907 2030492562 2032619034 2085680072 2085750388 2110824853 2123924948 2131327206 2134927760 2136423634] => 0
[1922985547 1934203179 1883318806 1910889055 1983590560 1965316186 2059139291 2075108931 2067514794 2117429526 2140519185 1659645051 1676816799 1611982084 1736461223 1810643297 1753583499 1767991311 1819386745 1355466982 1349603237 1360540003 1453750157 1461849199 1439893078 1432297529 1431882086 1427078318 1487887679 1484011617 1476718655 1509845392 1496496626 1583530675 1579588643 1609495371 1559139172 1554135669 1549766410 1566844751 1562161307 1561938937 1123551908 1086169529 1093103602 1202377124 1193780708 1148229310 1144649241 1257633250 1247607861 1241535002 1262624219 1288523504 1299222235 840314050 909401445 926048886 886867060 873099939 979662326 963003815 1012918112 1034467235 1026553732 568519178 650996158 647728822 616596108 617472393 614787483 604041145 633043809 678181561 698401105 776651230 325294125 271242551 291800692 389634988 346041163 344959554 345547011 342290228 354762650 442183586 467158857 412090528 532898841 534371187 32464799 21286066 109721665 127458375 192166356 146495963 142507512 167676030 236532616 262832772] => 1927544832
[1922985547 1934203179 1883318806 1910889055 1983590560 1965316186 2059139291 2075108931 2067514794 2117429526 2140519185 1659645051 1676816799 1611982084 1736461223 1810643297 1753583499 1767991311 1819386745 1355466982 1349603237 1360540003 1453750157 1461849199 1439893078 1432297529 1431882086 1427078318 1487887679 1484011617 1476718655 1509845392 1496496626 1583530675 1579588643 1609495371 1559139172 1554135669 1549766410 1566844751 1562161307 1561938937 1123551908 1086169529 1093103602 1202377124 1193780708 1148229310 1144649241 1257633250 1241535002 1247607861 1262624219 1288523504 1299222235 840314050 909401445 926048886 886867060 873099939 979662326 963003815 1012918112 1034467235 1026553732 568519178 650996158 647728822 616596108 617472393 614787483 604041145 633043809 678181561 698401105 776651230 325294125 271242551 291800692 389634988 346041163 344959554 345547011 342290228 354762650 442183586 467158857 412090528 532898841 534371187 32464799 21286066 109721665 127458375 192166356 146495963 142507512 167676030 236532616 262832772] => -1

Finalmente, aquí hay cuatro casos de prueba muy grandes para garantizar que las presentaciones sean lo suficientemente eficientes:

¿Por qué alguien haría esto?

El otro día se me ocurrió que una operación XOR puede "ordenar" una matriz, lo que hace posible realizar una búsqueda binaria en la matriz en O (log n) sin tener que ordenarla primero. Parece ser posible determinar Nen tiempo pseudolinear, lo que haría que esta sea una alternativa más rápida a la mayoría de los algoritmos de clasificación, y no tiene los requisitos de memoria de clasificación de radix. Por supuesto, una búsqueda lineal directa a través de la matriz sin clasificar será más rápida, pero si desea buscar la misma matriz muchas veces, un solo cálculo previo lineal puede reducir significativamente el tiempo requerido para cada búsqueda.

Desafortunadamente, la clase de listas en las que funciona es bastante limitada (es poco probable que las distribuciones uniformemente aleatorias admitan una N).

Una pregunta interesante es si existen otras funciones biyectivas que sean más fáciles de verificar y / o que sean aplicables para una clase más amplia de listas.

Martin Ender
fuente
42
" Xorting " es un nombre realmente genial para eso.
insertusernamehere
77
@insertusernamehere Créditos para eso van a randomra.
Martin Ender
3
¡Un desafío extremadamente interesante!
DavidC
44
Paebbels: suponiendo que tenga la tecla Xorting, es posible calcular el valor original. Para los propósitos aquí (una búsqueda binaria), XOR la ​​entrada con la clave y luego verifica que exista en la matriz 'ordenada'. Ciertamente es un tipo, pero la relación / función que está seleccionando se elige para que la posición de cada elemento permanezca igual.
meiamsome
8
@ Paebbels Nunca afirmé que esto está ordenando. Lo llamé por una palabra inventada y el párrafo que cita tiene "ordenar" entre comillas por una razón. Mi punto fue que esta es una transformación biyectiva que permite que la matriz sea tratada como si estuviera ordenada para ciertas operaciones (como una búsqueda binaria) sin tener que ordenarla.
Martin Ender

Respuestas:

7

Jalea, 25 bytes

ṡ2Zµ^/Bo1Ḅ‘×>/|/H
Ç-¹^Ç¥?

Las últimas confirmaciones son posteriores a este desafío, pero el código anterior funciona con esta revisión , que es anterior. Pruébalo en línea!

Para ejecutar los casos de prueba grandes, dependiendo de su shell, puede ser necesario ajustar el código anterior en un programa que lea la entrada de STDIN. Pruébalo en línea!

Casos de prueba

$ xxd -c 13 -g 1 xort-prog.jelly 
0000000: ae 32 5a 8c 5e 2f 42 6f 31 a4 b6 94 3e  .2Z.^/Bo1...>
000000d: 2f 7c 2f 48 0a 92 2d 8e 5e 92 84 3f     /|/H..-.^..?
$ ./jelly f xort-prog.jelly '[4, 7, 6, 1, 0, 3]'; echo
5
$ ./jelly f xort-prog.jelly '[4, 7, 1, 6, 0, 3]'; echo
-1
$ ./jelly f xort-prog.jelly '[0, 1, 3, 4, 6, 7]'; echo
0
$ ./jelly f xort-prog.jelly '[4, 2, 3, 1]'; echo
6
$ ./jelly f xort-prog.jelly '[2, 3, 0, 0, 7, 7, 4, 5, 11, 11]'; echo
2
$ ./jelly f xort-prog.jelly '[2, 3, 0, 0, 7, 7, 5, 4, 11, 11]'; echo
-1
$
$ wget -q http://pastebin.com/raw/{P96PNi79,zCNLMsx9,GFLBXn5b,6F1Yn3gG}
$ xxd -c 14 -g 1 xort-func.jelly 
0000000: ae 32 5a 8c 5e 2f 42 6f 31 a4 b6 94 3e 2f  .2Z.^/Bo1...>/
000000e: 7c 2f 48 0a 92 2d 8e 5e 92 84 3f 0a a0 92  |/H..-.^..?...
$ tr \  , < P96PNi79 | time -f '\n%es' ./jelly f xort-func.jelly
-1
3.69s
$ tr \  , < zCNLMsx9 | time -f '\n%es' ./jelly f xort-func.jelly
0
2.78s
$ tr \  , < GFLBXn5b | time -f '\n%es' ./jelly f xort-func.jelly
1096442624
2.73s
$ tr \  , < 6F1Yn3gG | time -f '\n%es' ./jelly f xort-func.jelly
-1
2.70s

Idea

Utiliza el mismo enfoque que la respuesta de @ Jakube , pero mi implementación es un poco diferente.

Jelly aún no tiene clasificación, por lo que calculamos un candidato de clasificación, XOR la ​​lista de entrada con él, calculamos un candidato de clasificación de la lista XORed, y verificamos si el nuevo candidato es cero. Si es así, imprimimos el primer candidato; de lo contrario, imprimimos -1 .

Además, Jelly parece que todavía no tiene una forma sensata de convertir a entero (incluso la división de enteros puede devolver flotantes), por lo que tuve que encontrar una forma bastante creativa de redondear una lista de números a la siguiente potencia de 2 . En lugar de log-floor-pow, convierto todos los enteros a binario, reemplazo todos los dígitos binarios por 1 , vuelvo a convertir a entero, agrego 1 y divido por 2 .

Código

ṡ2Zµ^/Bo1Ḅ‘×>/|/H  Helper link. Argument: M (list of integers)

ṡ2                 Yield all overlapping slices of length 2 (pairs) of M.
  Z                Zip to group first and second coordinates.
   µ               Begin a new, monadic chain.
    ^/             XOR the corresponding coordinates.
      B            Convert all results to binary.
       o1          OR (logical) all binary digits with 1.
         Ḅ         Convert back to integer.
          ‘        Increment all integers.
           ×>/     Multiply each rounded (a ^ b) by (a > b).
                   This replaces (a ^ b) with 0 unless a > b.
              |/   OR all results.
                H  Halve the result.

Ç-¹^Ç¥?            Main link. Input: L (list of integers)

Ç                  Call the helper link on L. Result: C (integer)
     ¥             Create a dyadic chain:
   ^                 XOR the elements of L with C.
    Ç                Call the helper link on the result.
      ?            If the result in non-zero:
 -                   Yield -1.
  ¹                Else, yield C.
Dennis
fuente
36

Pyth, 40 36 31 30 bytes

Ju.|G^2slHxMf>FT.:Q2Z|tSIxRJQJ

Pruébelo en línea: Demostración o conjunto de pruebas

Cada uno de los grandes casos de prueba termina en un par de segundos.

Explicación:

Primero explicaré el método y por qué funciona. Voy a hacer esto con la lista de ejemplo: [7, 2, 13, 9].

Los dos primeros números ya están equivocados ( 7 > 2). Queremos xor con algún número para cambiar ese símbolo de desigualdad ( 7 xor X < 2 xor X). Como xor opera en las representaciones binarias, veámoslas.

7 = 1 1 1
2 =   1 0

Cuando aplicamos xor con algún número a cada número, el valor en algunas posiciones cambiará. Si cambia los valores en la primera posición ( 2^0), el símbolo de desigualdad no cambia. Lo mismo sucede cuando cambiamos los valores en la segunda posición ( 2^1). También el símbolo no cambiará si cambiamos los valores en la cuarta, quinta, ... posiciones ( 2^3, 2^4, ...). El símbolo de desigualdad solo cambia de dirección, si cambiamos la tercera posición ( 2^2).

7 xor 2^0 = 1 1 0   7 xor 2^1 = 1 0 1   7 xor 2^2 =   1 1   7 xor 2^3 = 1 1 1 1
2 xor 2^0 =   1 1   2 xor 2^1 =     0   2 xor 2^2 = 1 1 0   2 xor 2^3 = 1 0 1 0
     6 > 3               5 > 0               3 < 6               15 > 10

Si cambiamos varias posiciones a la vez, por supuesto, sucede lo mismo. Si alguna de las posiciones que cambiamos es la tercera, entonces el símbolo de desigualdad cambia, de lo contrario no.

El siguiente par ya está ordenada: 2 < 13. Si observamos la representación binaria, notamos que podemos hacer cualquier cosa y el símbolo de desigualdad aún es correcto, excepto cuando cambiamos la cuarta posición ( 2^3).

 2 =     1 0    2 xor 2^3 = 1 0 1 0
13 = 1 1 0 1   13 xor 2^3 =   1 0 1
   2 < 13            10 > 5

Entonces no queremos cambiar la cuarta posición. Para el próximo par queremos cambiar algo, desde entonces 13 > 9. Aquí nuevamente tenemos que cambiar la tercera posición.

13 = 1 1 0 1   13 xor 2^2 = 1 0 0 1
 9 = 1 0 0 1    9 xor 2^2 = 1 1 0 1
   13 > 9            9 < 13

Ahora, resumen: para terminar en una lista ordenada, nuevamente tenemos que cambiar la tercera posición y no queremos cambiar la cuarta posición. Todas las demás posiciones no importan. El número más pequeño es simplemente 4 = 0100. Otras opciones serían 5 = 0101, 6 = 0110, 7 = 0111, 20 = 10100, 21 = 10101, ...

Xoring con 4dará como resultado la lista [3, 6, 9, 13], con 6will get [1, 4, 11, 15]y with 21will get [18, 23, 24, 28].

Entonces, para una lista, necesitamos encontrar las posiciones, que cambiarán el símbolo de desigualdad si apunta en la dirección incorrecta. Encontramos la posición simplemente tomando el bit más significativo del xor del par. Combinamos todas estas posiciones (con o) para dar como resultado un número de candidato. Lo comprobamos, si no hemos destruido accidentalmente los pares ya ordenados.

Ju.|G^2slHxMf>FT.:Q2Z   implicit: Q = input list
                .:Q2    all substrings of length 2
            f>FT        filter for pairs that are in descending order
          xM            apply xor to each such pair
 u                  Z   reduce this list, start value G = 0
                           iteration value is H
     ^2slH                 2 to the power of floor(logarithm base 2 of H)
                           this gives a mask representing the most significant bit
  .|G                      update G with the bitwise or of G and ^
J                       store the result in J


|tSIxRJQJ   
    xRJQ      xor each element of the input list with J
  SI          check if the list is sorted
 t            subtract 1
|       J     this number or (if equal to zero) J
              implicit print
Jakube
fuente
3
Estoy exhortando a la existencia de una solución tan limpia y simple.
quintopia
Sería increíble si pudieras dar una explicación de por qué esto funciona para aquellos de nosotros que somos más matemáticamente obtusos. Entiendo todos los pasos, pero no entiendo por qué el bit a bit o del MSB de cada par descendente xor'ed será el valor correcto.
Lucas
1
@Luke agregó una larga explicación. Espero que ayude.
Jakube
Maravillosa explicación!
edc65
1
Si mantiene 2 valores binarios, los bits que tienen que cambiar y los bits que no tienen que cambiar, entonces tiene su resultado final sin más iteraciones
edc65
15

Rubí 2, 119

->a,*o{a.each_cons(2){|x,y|x==y||o[i=(x^y).bit_length-1]==1-(o[i]=x[i])&&(return-1)};(o.map(&:to_i).reverse*'').to_i 2}

Se ejecuta en 42 milisegundos en los casos de prueba grandes.

Sin golf:

def first_differing_bit(a,b)
  (a^b).bit_length - 1
end

def xort(ary)
  required_bits = []
  ary.each_cons(2) do |a,b|
    i = first_differing_bit(a,b)
    if i > -1
      bit = a[i]
      if required_bits[i] && required_bits[i] != bit
        return -1
      else
        required_bits[i] = bit
      end
    end
  end
  required_bits.map(&:to_i).reverse.join.to_i(2)
end

Por una vez, escribí la versión sin golf primero, luego la jugué, ya que descubrir el algoritmo correcto era un desafío en sí mismo.

De hecho, intenté escribir algo como esto hace unos años para hacer una estructura de árbol binario que se autoequilibre localmente al permitir que cada nodo redefina su función de comparación dinámicamente. Al principio pensé que podría usar xor, pero como dices para datos aleatorios, es poco probable que haya un valor viable.

histocrat
fuente
Buena solución, me gusta la inicialización de la matriz y la función bit [] de ruby. Pero intente, por ejemplo, la lista [4,4,4], esto le dará un SyntaxError mientras intenta evaluar 0b. Afortunadamente, como me sucedió a menudo, hay otra forma de hacer lo mismo en la misma cantidad de bytes. Esto debería funcionar, espero:->a,*o{a.each_cons(2){|x,y|x==y||o[i=(x^y).bit_length-1]==1-(o[i]=x[i])&&(return-1)};(o.map(&:to_i).reverse*'').to_i 2}
blutorange
De hecho lo hace, buena captura!
histocrat
11

Julia, 174 144 77 75 71

[EDITAR] Gracias a Alex A. por el anonimato y varios shorthands.
[EDIT 2] Reemplazó mi propia implementación por el incorporado issorted().

Se ejecuta en tiempo lineal y maneja los archivos grandes sin demora notable. Funciona igual de bien para números negativos.

l->(r=0;s=issorted;for d=63:-1:0 s((l$r).>>d)||(r$=2^d)end;s(l$r)?r:[])

Otra variante que calcula el resultado más cercano a una clave dada (lo anterior devuelve el más pequeño).

(l,r)->(s=issorted;for d=63:-1:0 s((l$r).>>d)||(r$=2^d)end;s(l$r)?r:[])

uso:

julia> xort = l->(r=0;s=issorted;for d=63:-1:0 s((l$r).>>d)||(r$=2^d)end;s(l$r)?r:[])
(anonymous function)

julia> xort([4 7 6 1 0 3])
5

Ejemplo, paso a paso: [4 7 6 1 0 3] => 5

Start with:
     4  0b0100
     7  0b0111
     6  0b0110
     1  0b0001
     0  0b0000
     3  0b0011
result  0b0000

If the first n bits are sorted, do nothing.
        0b0
        0b0
        0b0
        0b0
        0b0
        0b0
result  0b0000
          ^
If the first n bits are not sorted, flip the nth bit.
        0b01            0b00
        0b01            0b00
        0b01            0b00
        0b00      =>    0b01
        0b00            0b01
        0b00            0b01
result  0b0000          0b0100
           ^               ^
        0b000
        0b001
        0b001
        0b010
        0b010
        0b011
result  0b0100
            ^
        0b0000          0b0001  1
        0b0011          0b0010  2
        0b0010          0b0011  3
        0b0101    =>    0b0100  4
        0b0100          0b0101  5
        0b0111          0b0110  6
result  0b0100          0b0101  5
             ^               ^
If the bit flip does not sort the truncated integers, xorting is
impossible. We continue anyway and check for success in the end.
Rainer P.
fuente
2
71 bytes:l->(r=0;s=issorted;for d=63:-1:0 s((l$r).>>d)||(r$=2^d)end;s(l$r)?r:[])
Alex A.
8

JavaScript (ES6) 85 97114117

Editar Eliminado estúpido, inútil último Y
Editar2 Búsqueda de bits superiores acortada
Editar3 ¡Guau! Descubrí que ES6 (casi) tiene un bit incorporado para encontrar el bit superior (Math.clz32 cuenta los 0 bits superiores)

Esto se basa en la solución de @Jakube (por favor, vota). Nunca podría haberlo encontrado solo.

Aquí voy un paso adelante, iterando la lista una vez y manteniendo una máscara de bits con los bits que se deben voltear, y otra con los bits que se deben mantener.

Si hay una superposición de las máscaras de bits, entonces no hay solución posible, de lo contrario, la solución es "bits para voltear"

Como las operaciones binarias en javascript solo funcionan en enteros de 32 bits con signo, el valor de retorno es un entero de 32 bits con signo que puede ser negativo o 0.

Si no hay solución, el valor de retorno es 'X'

l=>l.map(v=>(t=v^p&&1<<(31-Math.clz32(v^p)),v>p?k|=t:c|=t,p=v),p=l[c=k=0])&&c&k?"X":c

Prueba

Las pruebas más largas en jsfiddle

X=l=>l.map(v=>(t=v^p&&1<<(31-Math.clz32(v^p)),v>p?k|=t:c|=t,p=v),p=l[c=k=0])&&c&k?"X":c

console.log=x=>O.textContent+=x+'\n'
;[
[[4,7,6,1,0,3], 5],
[[4,7,1,6,0,3], 'X'],
[[0,1,3,4,6,7], 0],
[[4,2,3,1], 6], 
[[2,3,0,0,7,7,4,5,11,11], 2],
[[2,3,0,0,7,7,5,4,11,11], 'X'],
[[1086101479,748947367,1767817317,656404978,1818793883,1143500039],'X'],
[[180522983,1885393660,751646477,367706848,331742205,724919510,850844696,2121330641,869882699,1831158987,542636180,1117249765,823387844,731663826,1762069894,240170102,1020696223,1212052937,2041219958,712044033,195249879,1871889904,1787674355,1849980586,1308879787,1743053674,1496763661,607071669,1987302942,178202560,1666170841,1035995406,75303032,1755269469,200581873,500680130,561748675,1749521426,1828237297,835004548,934883150,38711700,1978960635,209243689,1355970350,546308601,590319412,959613996,1956169400,140411967,112601925,88760619,1977727497,672943813,909069787,318174568,385280382,370710480,809689639,557034312,865578556,217468424,346250334,388513751,717158057,941441272,437016122,196344643,379529969,821549457,97008503,872313181,2105942402,603939495,143590999,1580192283,177939344,853074291,1288703007,1605552664,162070930,1325694479,850975127,681702163,1432762307,1994488829,780869518,4379756,602743458,1963508385,2115219284,1219523498,559301490,4191682,1918142271,169309431,346461371,1619467789,1521741606,1881525154],'X'],
[[37580156,64423492,87193676,91914964,93632157,96332899,154427982,176139560,184435039,228963836,230164674,279802291,301492375,309127664,345705721,370150824,380319820,403997410,410504675,416543032,418193132,424733526,428149607,435596038,477224208,515649925,519407995,525469350,614538124,624884850,642649261,653488151,679260270,685637235,690613185,739141066,825795124,832026691,832633584,833213619,852655299,913744258,917674993,921902522,925691996,931307936,954676047,972992595,997654606,1020009811,1027484648,1052748108,1071580605,1108881241,1113730139,1122392118,1154042251,1170901568,1180031842,1180186856,1206428383,1214066097,1242934611,1243983997,1244736049,1262979035,1312007069,1312030297,1356274316,1368442960,1377432523,1415342434,1471294243,1529353536,1537868913,1566069818,1610578189,1612277199,1613646498,1639183592,1668015280,1764022840,1784234921,1786654280,1835593744,1849372222,1875931624,1877593764,1899940939,2007896363,2023046907,2030492562,2032619034,2085680072,2085750388,2110824853,2123924948,2131327206,2134927760,2136423634],0],
[[1922985547,1934203179,1883318806,1910889055,1983590560,1965316186,2059139291,2075108931,2067514794,2117429526,2140519185,1659645051,1676816799,1611982084,1736461223,1810643297,1753583499,1767991311,1819386745,1355466982,1349603237,1360540003,1453750157,1461849199,1439893078,1432297529,1431882086,1427078318,1487887679,1484011617,1476718655,1509845392,1496496626,1583530675,1579588643,1609495371,1559139172,1554135669,1549766410,1566844751,1562161307,1561938937,1123551908,1086169529,1093103602,1202377124,1193780708,1148229310,1144649241,1257633250,1247607861,1241535002,1262624219,1288523504,1299222235,840314050,909401445,926048886,886867060,873099939,979662326,963003815,1012918112,1034467235,1026553732,568519178,650996158,647728822,616596108,617472393,614787483,604041145,633043809,678181561,698401105,776651230,325294125,271242551,291800692,389634988,346041163,344959554,345547011,342290228,354762650,442183586,467158857,412090528,532898841,534371187,32464799,21286066,109721665,127458375,192166356,146495963,142507512,167676030,236532616,262832772],1927544832],
[[1922985547,1934203179,1883318806,1910889055,1983590560,1965316186,2059139291,2075108931,2067514794,2117429526,2140519185,1659645051,1676816799,1611982084,1736461223,1810643297,1753583499,1767991311,1819386745,1355466982,1349603237,1360540003,1453750157,1461849199,1439893078,1432297529,1431882086,1427078318,1487887679,1484011617,1476718655,1509845392,1496496626,1583530675,1579588643,1609495371,1559139172,1554135669,1549766410,1566844751,1562161307,1561938937,1123551908,1086169529,1093103602,1202377124,1193780708,1148229310,1144649241,1257633250,1241535002,1247607861,1262624219,1288523504,1299222235,840314050,909401445,926048886,886867060,873099939,979662326,963003815,1012918112,1034467235,1026553732,568519178,650996158,647728822,616596108,617472393,614787483,604041145,633043809,678181561,698401105,776651230,325294125,271242551,291800692,389634988,346041163,344959554,345547011,342290228,354762650,442183586,467158857,412090528,532898841,534371187,32464799,21286066,109721665,127458375,192166356,146495963,142507512,167676030,236532616,262832772],'X']
].forEach(t=>{
  var i=t[0],k=t[1],r=X(i)
  console.log((k==r?'OK ':'Error (expected '+k+') ')+r+' for input '+i)
})
<pre id=O></pre>

edc65
fuente
8

ES6, 84 bytes

a=>(i=e=0,a.reduce((x,y)=>(z=1<<31-Math.clz32(x^y),x>y?i|=z:y>x?e|=z:z,y)),i&e?-1:i)

Editar: para cuando me llevó escribir la respuesta, el algoritmo ya había sido publicado de forma independiente por @Jakube; Mi algoritmo es el mismo, ¡pero esto no fue un plagio honesto! También noté que desde entonces se ha publicado otra respuesta de JavaScript. Lo siento si estoy pisando los pies de alguien.

Editar: Guardado 8 bytes gracias a edc65.

Neil
fuente
No pisas los pies de nadie en absoluto. Esta es una buena respuesta, buen trabajo. :)
Alex A.
¡Bien, venciste a @ edc65! Eso casi nunca sucede.
Mama Fun Roll
Tienes mi voto Creo que tú también deberías usar la función clz32 para ganarme de nuevo.
edc65
Si solo 1<<31>>>32fuera cero, podría guardar otros 4 bytes.
Neil
5

C, 144 bytes

#include <strings.h>
#include <stdio.h>
m[2],l,i;main(v){while(scanf("%d",&v)==1)m[l<v]|=(i++&&v^l)<<~-fls(v^l),l=v;printf("%d",*m&m[1]?-1:*m);}

Este es casi el C99 estándar (pierde algunos intespecificadores y tiene 1 argumento para main). También se basa en 0<<-1ser 0 (lo que parece ser cierto cuando se compila con Clang al menos, no he probado otros)

Tomé el método de Jakube y lo porté a C. Creo que tiene un tamaño sorprendentemente bueno para C. También es súper rápido (0.061s para ejecutar todos los archivos de prueba, incluido el masivo 4). Toma datos de STDIN e imprimirá el valor correspondiente o -1 en STDOUT, así que ejecútelo con uno de:

echo "4 7 6 1 0 0 3" | ./xort
./xort < file.txt

Descompostura:

// Globals initialise to 0
m[2],                                    // Stores our bit masks
                                         // (m[0]=CHANGE, m[1]=MUST NOT CHANGE)
l,                                       // Last value
i;                                       // Current iteration
main(v){
    while(scanf("%d",&v)==1)             // Read each value in turn
        m[l<v]|=                         // If they are sorted, we mark a bit as
                                         // MUST NOT CHANGE (m[1]), otherwise we
                                         // mark as CHANGE (m[0])
                (i++&&v^l)               // If this is the first iteration,
                                         // or the value is unchanged, mark nothing
                          <<~-fls(v^l),  // Mark the highest bit which has changed
                                         // = (1<<(fls(v^l)-1)
        l=v;                             // Update last value
    printf("%d",
                *m&m[1]                  // Check if result is valid (if any bits
                                         // are both MUST NOT CHANGE and CHANGE,
                                         // it is not valid)
                       ?-1               // Print -1 on failure
                          :*m);          // Print value on success
}
Dave
fuente
4

Julia, 124 bytes

f(x,g=0)=issorted(([g|=2^Int(log2(h1)for h=map(k->k[1]$k[2],filter(j->j[1]>=j[2],[x[i-1:i]for i=2:endof(x)]))];g)$x)?g:-1

Esta es una función que acepta una matriz de enteros y devuelve un entero. Utiliza el enfoque de Jakube .

Sin golf:

function f{T<:Integer}(x::Array{T,1}, g::T=0)
    # Get all pairs of elements in the input array
    pairs = [x[i-1:i] for i = 2:endof(x)]

    # Filter to pairs in descending order
    desc = filter(j -> j[1]  j[2], pairs)

    # Map XOR over these pairs
    xord = map(k -> k[1] $ k[2], desc)

    # For each element of this array, update the
    # parameter g (which defaults to 0) as the
    # bitwise OR of itself and 2^floor(log2(element))
    for h in xord
        g |= 2^Int(log2(h) ÷ 1)
    end

    # If the array constructed as g XOR the input is
    # sorted, we've found our answer! Otherwise -1.
    return issorted(g $ x) ? g : -1
end
Alex A.
fuente
Por curiosidad, ¿por qué es XOR $?
caird coinheringaahing
3

Python 2, 204 bytes

def f(a):
 m=n=0
 for i in range(32):
  b=2**(31-i);m|=b
  for n in[n,n|b]:
   if not q(a,m,n):break
  else:return-1
 return n
def q(a,m,n):
 if a:p=a[0]&m^n
 for t in a:
  t=t&m^n
  if t<p:return 1
  p=t

La entrada se pasa como una lista para funcionar f.

Este código calcula el valor de N (llamado n en el programa) un bit a la vez, comenzando con el bit más significativo. (el bucle "para i")

Para cada posición de bit, el bucle "for n" primero intenta usar 0 para ese bit de n. Si eso no funciona, intenta usar 1. Si ninguno de estos funciona, entonces no hay solución. Tenga en cuenta que la cláusula else está en el ciclo "for n", no en la instrucción if. En Python, una instrucción for puede tener una cláusula else, que se ejecuta después de que el ciclo se ejecuta hasta su finalización, pero es no se ejecuta si salimos del ciclo.

La función q verifica si hay problemas con el orden de la lista dada la lista (a), una máscara de bits (m) y el valor que se va a copiar con cada valor en la lista (n). Devuelve 1 si hay un problema con el pedido, o Ninguno si el pedido está bien. Ninguno es el valor de retorno predeterminado, por lo que me ahorró varios caracteres.

Este código maneja una lista vacía o una lista con 1 elemento correctamente, devolviendo 0. El "if a:" en la función q solo está ahí para evitar una excepción IndexError cuando la lista está vacía. Por lo tanto, se podrían eliminar 5 bytes más si no se requiere el manejo de listas vacías.

En mi computadora, el caso de prueba grande # 3 tomó 0.262 segundos. # 2 tomó casi lo mismo. Todos los casos de prueba juntos tomaron 0.765 segundos.

Gary Culp
fuente
1
No es necesario manejar listas vacías, lo aclararé.
Martin Ender
3

CJam, 37 bytes

q~_2ew{:>},{:^2mLi2\#}%0+:|_@f^_$=\W?

Pruébalo aquí.

Esto usa el mismo algoritmo que varias de las otras respuestas. Es esencialmente mi implementación de referencia que usé para crear los casos de prueba. Sin embargo, robé el truco de Jakube de verificar solo los pares ofensivos y simplemente probar el resultado con una especie. Eso rompe la pseudolinearity, pero O (n log n) sigue siendo lo suficientemente rápido para los casos de prueba. Mi código original también verificó los pares que ya están en orden, y construyó una lista de bits que no deben alternarse para mantener su orden relativo, y verificó al final que no hay superposiciones entre las máscaras de dos bits. Este algoritmo fue originalmente sugerido por Ben Jackson .

Martin Ender
fuente
2

Pitón 2, 226 214 bytes

Algoritmo simple, construido ayer, golf hoy.

o=input()
s=sorted
p=s(set(o),key=o.index)
n=q=0
while 1:
 a=1
 while 1-q and p[0]<p[1]:p=p[1:];q=len(p)==1
 if q:break
 while not p[0]^a<p[1]^a:a*=2
 n+=a;p=[i^a for i in p]
t=[a^n for a in o]
print[-1,n][s(t)==t]

Sin golf:

def xor(a,b): return a^b

def rm_dupes(seq):
    seen = set()
    seen_add = seen.add
    return [x for x in seq if not (x in seen or seen_add(x))]

def rm_sorted(seq):
    while seq[0] < seq[1]:
        seq = seq[1:]
        if len(seq) == 1: return seq
    return seq

inp = input()
oi = inp

inp = rm_dupes(inp)
n=0
old_inp=0
while old_inp != inp:
    old_inp = inp
    inp = rm_sorted(inp)
    if len(inp)==1:break
    highest_set0 = len(bin(inp[0]))-3 # bin returns in form 0bxxx
    highest_set1 = len(bin(inp[1]))-3 # bin returns in form 0bxxx
    if highest_set1 == 0:
        try:
            t0 = max(int(bin(inp[0])[3:], 2), 1)
        except ValueError: toggle_amount = 1
        else: toggle_amount = t0^inp[0]
    else:
        fallen = False
        for i in xrange(max(highest_set0,highest_set1)+1):
            toggle_amount = 2**i
            if inp[0]^toggle_amount < inp[1]^toggle_amount:
                fallen = True
                break
        assert(fallen)
    n+=toggle_amount
    inp = [i^toggle_amount for i in inp]

out=map(xor, oi, [n]*len(oi))
if sorted(out)==out :print n
else:print -1
Azul
fuente
2

C, 312 bytes

#define R return
t,i,*b;f(int*a,int l,int k){int s=a[0]>>k&1,j=-1,i=1;if(k<0)R 0;for(;i<l;++i){t=a[i]>>k&1;if(s!=t)if(j<0)j=i,s=t;else R 1;}if(j<0)R f(a,l,k-1);else{if(s+b[k]==2)R 1;b[k]=s+1;R f(a,j,--k)||f(a+j,l-j,k);}}h(int*a,int l){int c[32]={0};b=c;if(f(a,l,30))R -1;t=0;for(i=0;i<32;++i)t|=(b[i]&1)<<i;R t;}

Define una función que h(int*a,int l)lleva un puntero a una matriz y su longitud. aquí hay un programa de prueba gigante.

Ligeramente incólume:

int t, i, *b;

int f(int * a, int l, int k) {
    int s = a[0] >> k & 1;
    int j = -1;
    int i = 1;
    if (k < 0) return 0;
    for (; i < l; ++i) {
        t = a[i] >> k & 1;
        if (s != t) {
            if (j < 0) {
                j = i;
                s = t;
            } else return 1;
        }
    }
    if (j < 0) {
        return f(a, l, k - 1);
    } else {
        if (s + b[k] == 2) return 1;
        b[k] = s + 1;
        return f(a, j, --k) || f(a + j, l - j, k);
    }
}

int h(int * a, int l) {
    int c[32] = {0};
    b = c;
    if (f(a, l, 30)) return -1;
    t = 0;
    for (i = 0; i < 32; ++i) {
        t |= (b[i] & 1) << i;
    }
    return t;
}
jcai
fuente
2

Mathematica, 99 97 Personajes

Gracias a Martin Büttner por sus consejos.

x@l_:=If[OrderedQ[l~BitXor~#],#,-1]&@Fold[#+#2Boole@!OrderedQ@⌊l~BitXor~#/#2⌋&,0,2^32/2^Range@32]

Explicación:

Haremos múltiples intentos para modificar a Npartir de cero, y haremos una prueba para validar al candidato N.

Paso 1. Nos conseguir estos números (enteros de 32 bits) "XOR" ed por N( = 0ahora) y dividido por 2^31: ⌊l~BitXor~#/#2⌋. Hay tres casos:

  • ordenado, por ejemplo {0, 0, 1, 1, 1, 1, 1, 1};
  • puede corregirse, por ejemplo {1, 1, 1, 1, 0, 0, 0, 0};
  • de lo contrario, por ejemplo {0, 0, 1, 0, 0, 1, 1, 1}.

No hacemos nada para Npara el primer caso, o añadimos 2^31a Ncorregir el fin de que el segundo caso: #+#2Boole@!OrderedQ@.... Mientras que para el tercer caso, es imposible ampliar la lista de lo que hacemos, por lo tanto solo agregamos 2^31aN por simplicidad (o cualquier cosa).

Paso 2. Obtenemos estos números "xor" ed Ny divididos por 2^30. De nuevo hay tres casos:

  • ordenado, por ejemplo {0, 1, 2, 2, 2, 2, 3, 3};
  • puede corregirse, p. ej. {1, 1 , 0, 0, 3, 2, 2, 2};
  • de lo contrario, por ejemplo {3, 3, 1, 3, 2, 0, 1, 0}.

No hacemos nada para Npara el primer caso, o añadimos 2^30a Ncorregir la orden para el segundo caso. De lo contrario, nos damos cuenta de que xorting es imposible, por lo que solo agregamos 2^30aN por simplicidad de nuevo.

Paso 3 ~ 32. Se forma recursiva obtener estos números "XOR" ed por Ny dividido por 2^29, 2^28, ..., 2^0. Y hacer cosas similares:Fold[...,0,2^32/2^Range[32]]

Paso 33. Ahora finalmente tenemos un candidato N. If[OrderedQ[l~BitXor~#],#,-1]&se usa para verificar si tal Nes la clasificación de la lista. Si la lista puede ser complicada por algunos N, no es difícil probar que siempre encontraremos el primer o el segundo caso.

njpipeorgan
fuente
2

Perl 6 , 79 bytes

Si no hubiera un límite de tiempo, el código más corto de Perl 6 probablemente sería

{first {[<=] $_ X+^@_},^2*.max} # 31 bytes

En cambio, tengo que hacer algo un poco más inteligente.
Como me tomé un tiempo para volver a esto, ya había una respuesta que describe un buen algoritmo y el razonamiento detrás de él.

{$/=0;for @_.rotor(2=>-1) ->(\a,\b){b>=a or$/+|=2**msb a+^b};$/if [<=] $/X+^@_} # 79
{
  # cheat by using a special variable
  # so there is no need to declare it
  $/=0;

  # takes the elements two at a time, backing up one
  for @_.rotor(2=>-1)
    # since that is a non-flat list, desugar each element into 2
    # terms
    ->(\a,\b){
      # if they are not sorted
      b>=a or
      # take the most significant bit of xoring the two values
      # and numeric or 「+|」 it into 「$/」
      $/+|=2**msb a+^b
    };


  # returns 「$/」 if the list is Xorted
  # otherwise returns Empty
  $/if [<=] $/X+^@_

  # 「 $/ X[+^] @_ 」
  # does numeric xor 「+^」 between 「$/」
  # and each element of the original list 「@_」
}

Uso:

# give it a lexical name for ease of use
my &code = {...}

say code [8,4,3,2,1];     # 15

say code [4,7,6,1,0,3]; # 5
say code [4,7,1,6,0,3]; # ()
say code [0,1,3,4,6,7]; # 0
say code [4,2,3,1];     # 6
say code [2,3,0,0,7,7,4,5,11,11]; # 2
say code [2,3,0,0,7,7,5,4,11,11]; # ()
say code [1086101479,748947367,1767817317,656404978,1818793883,1143500039]; # ()

# the example files
for 'testfiles'.IO.dir.sort».comb(/«\d+»/) {
  printf "%10s in %5.2f secs\n", code( @$_ ).gist, now - ENTER now;
}
#         () in  9.99 secs
#          0 in 11.70 secs
# 1096442624 in 13.54 secs
#         () in 11.44 secs
Brad Gilbert b2gills
fuente
1

Mathematica 650415194 bytes

Este desafío me ayudó a entender un poco sobre lo Xorque nunca había pensado. Tomó mucho tiempo reducir el código, pero valió la pena el esfuerzo.

BitXortrabaja directamente en base 10 números. Esto redujo en gran medida el código de las versiones anteriores.

La lógica es simple. Uno funciona, no con pares de números (como lo hicieron algunas presentaciones) sino con el conjunto completo de números después de ser BitXoreditado con la "clave" actual.

Comience con una solución tentativa, o "clave" de cero, es decir, con todos los bits son cero. Cuando los nnúmeros originales se BitXoreditan con cero, se devuelven, sin modificaciones. Correlacione el orden de los números con el rango 1, 2, ...n, que representa una lista perfectamente ordenada. La correlación, con un valor entre -1 y 1, refleja qué tan bien están ordenados los números.

Luego establezca el bit de alta, obtenga la nueva clave y BitXorla clave con el conjunto actual de números. Si la correlación entre la nueva secuencia de números y la lista perfectamente ordenada es una mejora, mantenga el bit establecido. Si no, deje el bit sin ajustar.

Proceda de esta manera del hola al bit bajo. Si la mejor correlación es 1, entonces la clave es la solución. Si no, es -1.

Habría maneras de hacer que el código sea un poco más eficiente, por ejemplo, interrumpiendo el proceso tan pronto como se encuentre una solución, pero esto requeriría más codificación y el enfoque actual es muy rápido. (El caso de prueba final y más largo demora 20 ms).

c@i_:=Correlation[Ordering@i,Range[Length[i]]]//N;
t@{i_,k_,b_,w_}:=(v= c@BitXor[i,m=k+2^(b-1)];{i,If[v>w,m,k],b-1,v~Max~w})
g@i_:= (If[#4==1,#2,-1] &@@Nest[t,{i,0,b=1+Floor@Log[2,Max@i],x=c@i},b])

g[{4, 7, 6, 1, 0, 3}]

5 5


g[{4, 7, 1, 6, 0, 3}]

-1


g2@{0, 1, 3, 4, 6, 7}

0 0


g@{1922985547, 1934203179, 1883318806, 1910889055, 1983590560, 1965316186,2059139291, 2075108931, 2067514794, 2117429526, 2140519185, 1659645051, 1676816799, 1611982084, 1736461223, 1810643297, 1753583499, 1767991311, 1819386745, 1355466982, 1349603237, 1360540003, 1453750157, 1461849199, 1439893078, 1432297529, 1431882086, 1427078318, 1487887679, 1484011617, 1476718655, 1509845392, 1496496626, 1583530675, 1579588643, 1609495371, 1559139172, 1554135669, 1549766410, 1566844751, 1562161307,1561938937, 1123551908, 1086169529, 1093103602, 1202377124, 1193780708, 1148229310, 1144649241, 1257633250, 1247607861, 1241535002, 1262624219, 1288523504, 1299222235,840314050, 909401445, 926048886, 886867060, 873099939, 979662326,963003815, 1012918112, 1034467235, 1026553732, 568519178, 650996158,647728822, 616596108, 617472393, 614787483, 604041145, 633043809, 678181561, 698401105, 776651230, 325294125, 271242551, 291800692, 389634988, 346041163, 344959554, 345547011, 342290228, 354762650, 442183586, 467158857, 412090528, 532898841, 534371187, 32464799, 21286066, 109721665, 127458375, 192166356, 146495963, 142507512, 167676030, 236532616, 262832772}

1927544832

DavidC
fuente
1

Añadir ++ , 125 119 bytes

D,g,@@,BxBBBDbU1€oB]BJ2$Bb1+
D,j,@,bUBSVcGbU£{g}B]BkAbUBSVcGbU£>B]BKBcB*¦Bo2/i
L!,B#a=
D,f,?!,{j}Vad{j}BF€Bx1]G$0=-1$Qp

Pruébalo en línea!

De hecho, estoy realmente orgulloso de que Add ++ pueda hacer esto, y no sea la solución más larga aquí

Declara una función fque toma cada elemento como un argumento separado (por ejemplo $f>4>2>3>1)

Cómo funciona

Abróchense el cinturón, va a ser un viaje largo

D,g,@@,		; Declare a function 'g'
		; Example arguments: 		[4 7]
	Bx	; Xor;			STACK = [3]
	BB	; To binary;		STACK = [11]
	BD	; Digits;		STACK = [[1 1]]
	bU	; Unpack;		STACK = [1 1]
	1€o	; Replace 0s with 1s;	STACK = [1 1]
	B]	; Wrap;			STACK = [[1 1]]
	BJ	; Concatenate;		STACK = ['11']
	2$Bb	; From binary;		STACK = [3]
	1+	; Increment;		STACK = [4]
		;			Return   4

D,j,@,		; Declare a function 'j'
		; Example argument:		[[4 7 6 1 0 3]]
	bU	; Unpack;		STACK = [4 7 6 1 0 3]
	BS	; Overlapping pairs;	STACK = [4 7 6 1 0 3 [[4 7] [4 6] [6 1] [1 0] [0 3]]]
	VcG	; Keep first element;	STACK = [[[4 7] [4 6] [6 1] [1 0] [0 3]]]
	bU	; Unpack;		STACK = [[4 7] [4 6] [6 1] [1 0] [0 3]]
	£{g}	; Apply 'g' over each;	STACK = [4 2 8 2 4]
	B]	; Wrap;			STACK = [[4 2 8 2 4]]
	Bk	; Global save;		STACK = []		; GLOBAL = [4 2 8 2 4]
	A	; Push arguments;	STACK = [[4 7 6 1 0 3]]
	bU	; Unpack;		STACK = [4 7 6 1 0 3]
	BSVcGbU	; Overlapping pairs;	STACK = [[4 7] [4 6] [6 1] [1 0] [0 3]]
	£>	; Greater than each;	STACK = [0 1 1 1 0]
	B]	; Wrap;			STACK = [[0 1 1 1 0]]
	BK	; Global get;		STACK = [[0 1 1 1 0] [4 2 8 2 4]]
	BcB*	; Products;		STACK = [[0 2 8 2 0]]
	¦Bo	; Reduce by logical OR;	STACK = [10]
	2/i	; Halve;		STACK = [5]
		;			Return   5

L!,		; Declare 'lambda 1'
		; Example argument:		[[1 2 3 4 5]]
	B#	; Sort;			STACK = [[1 2 3 4 5]]
	a=	; Equal to argument;	STACK = [1]
		; 			Return   1

D,f,?!,		; Declare a function 'f'
		; Example arguments:		[[4 7 6 1 0 3]]
	{j}	; Call 'j';		STACK = [5]
	V	; Save;			STACK = []		; REGISTER = 5
	ad	; Push arguments twice;	STACK = [[4 7 6 1 0 3] [4 7 6 1 0 3]]
	{j}	; Call 'j';		STACK = [[4 7 6 1 0 3] 5]
	BF	; Flatten;		STACK = [4 7 6 1 0 3 5]
	€Bx	; Xor each with 5;	STACK = [1 2 3 4 5 6]
	1]	; Call 'lambda 1';	STACK = [1]
	G$	; Retrieve REGISTER;	STACK = [5 1]
	0=	; If equal to 0:
	-1$Q	;   Return -1
	p	; Else, pop condition;	STACK = [5]
		;			Return   5
caird coinheringaahing
fuente
1

Stax , 29 bytes

¬√▬ⁿ{j╔■α√ï(íP♫_z(.▀ng▒JU↨@b┬

Ejecutar y depurar en línea!

Utiliza la solución de @ RainerP. (Se le ocurrió la parte del bit de volteo de forma independiente pero usa la 32rrparte)

Complejidad lineal del tiempo.

Utiliza la versión desempaquetada para explicar.

32rr{|2Y;{y/m:^!c{,{y|^m~}Mm,:^ud:b
32rr                                   Range [32,31..0]
    {                      m           Map each number `k` in the range with
     |2Y                                   `2^k`
        ;{y/m                              Map each number `l` in the input to `floor(l/2^k)`
             :^!                           The mapped array is not non-decreasing
                                           This is the binary digit `l` is mapped to
                c{       }M                If that's true, do
                  ,{y|^m~                  Flip the corresponding bit of every element in the input
                            ,:^        The final array is sorted
                               ud      Take inverse and discard, if the final array is not sorted this results in zero-division error
                                 :b    Convert mapped binary to integer
Weijun Zhou
fuente