Agregando a la gran respuesta de FatalError, la línea return f(b)^f(a-1);
podría explicarse mejor. En resumen, es porque XOR tiene estas maravillosas propiedades:
- Es asociativo : coloca los corchetes donde quieras
- Es conmutativo , lo que significa que puede mover a los operadores (pueden "conmutar")
Aquí están ambos en acción:
(a ^ b ^ c) ^ (d ^ e ^ f) = (f ^ e) ^ (d ^ a ^ b) ^ c
Me gusta esto:
a ^ b = c
c ^ a = b
Sumar y multiplicar son dos ejemplos de otros operadores asociativos / conmutativos, pero no se invierten. Bien, entonces, ¿por qué son importantes estas propiedades? Bueno, una ruta simple es expandirlo hasta convertirlo en lo que realmente es, y luego podrá ver estas propiedades en funcionamiento.
Primero, definamos lo que queremos y llamémoslo n:
n = (a ^ a+1 ^ a+2 .. ^ b)
Si ayuda, piense en XOR (^) como si fuera un complemento.
Definamos también la función:
f(b) = 0 ^ 1 ^ 2 ^ 3 ^ 4 .. ^ b
b
es mayor que a
, por lo que simplemente colocando de forma segura algunos corchetes adicionales (lo cual podemos porque es asociativo), también podemos decir esto:
f(b) = ( 0 ^ 1 ^ 2 ^ 3 ^ 4 .. ^ (a-1) ) ^ (a ^ a+1 ^ a+2 .. ^ b)
Lo que se simplifica a:
f(b) = f(a-1) ^ (a ^ a+1 ^ a+2 .. ^ b)
f(b) = f(a-1) ^ n
A continuación, usamos esa propiedad de inversión y la comutividad para darnos la línea mágica:
n = f(b) ^ f(a-1)
Si ha estado pensando en XOR como una suma, habría dejado caer una resta allí. ¡XOR es XOR lo que sumar es restar!
¿Cómo se me ocurre esto yo mismo?
Recuerde las propiedades de los operadores lógicos. Trabaje con ellos casi como una suma o una multiplicación si ayuda. Se siente inusual que y (&), xor (^) yo (|) sean asociativos, ¡pero lo son!
Ejecute primero la implementación ingenua, busque patrones en la salida y luego comience a encontrar reglas que confirmen que el patrón es verdadero. Simplifique su implementación aún más y repita. Esta es probablemente la ruta que tomó el creador original, resaltada por el hecho de que no es completamente óptima (es decir, use una declaración de cambio en lugar de una matriz).