Debería escribir un programa o función que tome un entero no negativo N
como entrada y salida o devuelva dos enteros (negativo, cero o positivo) X
y Y
.
Los enteros se entienden en sentido matemático ya que hay infinitos de ellos.
La función implementada tiene que ser biyectiva . Esto significa que para cada N
uno tiene que generar un X
Y
par diferente y cada X
Y
par debe emitirse para alguna entrada, N
es decir, todos los siguientes pares deben emitirse para algunos N
:
...
┌─────┬─────┬────┬────┬────┐
│-2 -2│-2 -1│-2 0│-2 1│-2 2│
├─────┼─────┼────┼────┼────┤
│-1 -2│-1 -1│-1 0│-1 1│-1 2│
├─────┼─────┼────┼────┼────┤
... │0 -2 │0 -1 │0 0 │0 1 │0 2 │ ...
├─────┼─────┼────┼────┼────┤
│1 -2 │1 -1 │1 0 │1 1 │1 2 │
├─────┼─────┼────┼────┼────┤
│2 -2 │2 -1 │2 0 │2 1 │2 2 │
└─────┴─────┴────┴────┴────┘
...
Tenga en cuenta que U V
y V U
son diferentes pares si U!=V
.
Detalles
- Si su idioma no admite enteros arbitrariamente grandes, está bien, pero su algoritmo debería funcionar con un tipo de datos entero arbitrariamente grande. Su código aún debe admitir valores de entrada al menos
2^31-1
. - Si elige imprimir o devolver la salida como cadena, no se permiten signos
0
ni+
signos iniciales. De lo contrario, la representación entera estándar de su idioma está bien.
Ejemplo
Si la tarea fuera hacer una función biyectiva tomando un número entero no negativo N
y generando un número entero, X
una solución podría ser la función
if (input mod 2 == 0) return N/2 else return -(N+1)/2
,
implementado en algún idioma. Esta función devuelve X = 0 -1 1 -2 2...
para N = 0 1 2 3 4...
.
10=>11 12, 9=>10 11
es válido porque se repite 11?Respuestas:
Pyth, 15
Pruébalo en línea.
Una traducción de Python:
o iterativamente:
donde
binlist
convierte un número a una lista de dígitos comobinlist(4) = [1,0,0]
.¿Entonces, cómo funciona esto? Interpreta los dígitos binarios del número como dos números intercalados en dos negativos base como en mi solución Python .norte
El número binario corresponde al par ( x , y ) = ( b 0 - 2 b 2 + 4 b 4 - 8 b 6 + ⋯ , b 1 - 2 b 3 + 4 b 5 - 8 b 7 + ⋯ )
Si aún no hubiéramos procesado el último dígito de n , tendríamos todos los índices más altos en $ 1 $, n ′ = … b 5 b 4 b 3 b 2 b 1 correspondientes al par ( x ′ , y ′ ) = ( b 1 - 2 b 3 + 4 b 5 - 8 b 7 + ⋯ , b 2 - 2 b 4si0 0 norte
Entonces podemos expresar los nuevos valores una vez que se lee en términos de los valores anterioressi0 0
fuente
CJam,
242221 bytesMi cerebro tiene problemas para entender las matemáticas que usan otras soluciones. Pero mi cerebro definitivamente entiende binario, ¡así que aquí hay una idea basada en la manipulación de bits!
Pruébalo en línea.
Explicación
Este enfoque trata la entrada como dos valores binarios intercalados, uno para cada número de salida. Todos, excepto el bit menos significativo de cada uno, codifican una magnitud, y el bit menos significativo indica si tomar o no el complemento en bits de esta magnitud. En esta implementación, los bits de posición impar corresponden al primer número de salida (y los bits de posición par corresponden al segundo) y un LSB de
0
señales para tomar el complemento.Por ejemplo, dada una entrada de
73
, desintercalar su representación binaria de1001001b
produce0 1|0
(bits de posición impar) y1 0 0|1
(bits de posición par). El primer valor tiene una magnitud de01b = 1
y debe complementarse para un valor final de~1 = -2
, y el segundo valor tiene una magnitud de100b = 4
y no debe complementarse.Demostración informal de corrección
Hice un programa de prueba que coloca cada entrada de cero a un número especificado por el usuario menos uno en su ubicación de salida en una cuadrícula 2D. Puedes probarlo en línea también. Aquí hay una salida de este programa que muestra cómo se asigna el algoritmo
0-99
:El patrón de relleno se ve un poco extraño, ¡pero de hecho es biyectivo! Con cada poder sucesivo de 4, llena un cuadrado con el doble de la longitud del lado anterior. Por ejemplo, así es como se asigna el algoritmo
0-15
:Esto constituye el cuadrado de 4x4 en el medio del cuadrado de 8x8 de
0-63
:Lo que constituye el cuadrado de 8x8 en el medio del cuadrado de 16x16 de
0-255
:fuente
li4b2fmd2/
lugar de0li2b+W%2/W%
. Esto da los mismos enteros, pero en orden inverso.Pitón 2, 49
Editar: Mejorado a 49 al usar una mejor recursión de un paso para la base -2.
Aquí hay una versión de Pyth usando
reduce
.Editar: Mejorado a 52 cambiando a base -2 desde ternario equilibrado .
Pitón 2, 52
Pitón 2, 54
Utiliza intercalado de dígitos como la solución Runer112 , pero con binario ternario equilibrado en lugar de binario con signo. Python no tiene una conversión base integrada, por lo que el código la implementa de forma recursiva.
La función auxiliar
h
(con3
en lugar de9
) toma un número natural y lo convierte de ternario a ternario equilibrado con las sustituciones de dígitosEntonces, por ejemplo, 19, que es 201 en base, se convierte en (-1) (0) (+ 1) en ternario balanceado, que es (-1) * 3 ^ 2 + (0) * 3 ^ 1 + (+ 1) * 3 ^ 0 = -8.
El ternario equilibrado es suficiente para codificar cada número entero y, por lo tanto, proporciona una asignación de números naturales a números enteros.
Para mapear a pares de enteros, entrelazamos los dígitos
n
. Para hacerlo, tenemos queh
mirar cada dos dígitos haciendon/9
como el paso recursivo en lugar de hacerlon/3
. Luego, para una coordenada, cambiamosn
dividiendo el piso por3
.Aquí están las primeras 81 salidas, que cubren la región [-4,4] ^ 2.
Una codificación alternativa con un cuarto de imaginario resultó más larga, aunque es muy bonita.
Pitón 2, 63
En un lenguaje con un manejo menos complejo de conversión compleja, este sería probablemente un mejor enfoque. Si pudiéramos generar números complejos, podríamos hacer:
Pitón 2, 38
fuente
L&b-%b2*2y/b4,yQy/Q2
tiene solo 20 bytes de longitud.Python 2, 98 bytes
Comencemos con un enfoque simple:
Simplemente forma
N
unidades espirales rectangulares de largo en una cuadrícula 2D, comenzando desde el origen, y devuelve las coordenadas del último punto.La función es biyectiva ya que:
La espiral se ve más o menos así (excepto a partir de 0 en lugar de 1):
fuente
0**0 == 1
en python, así que es lo mismo queif a == 0: a = b/2
a=a or b/2
es más corto0^0=1
en todas las matemáticas, no solo en Python.0**0
es en realidad forma indeterminada en matemáticasdc, 49
Esto comienza organizando los enteros no negativos en una cuadrícula de esta manera:
Tenga en cuenta que las posiciones de la cuadrícula se llenan diagonalmente con N creciente. Observe que la línea Y = 0 contiene la secuencia de números triangulares, dada por
N = X(X+1)/2
. Esta es una ecuación cuadrática que se resuelve usando la fórmula normal, usando solo la raíz + ve, para que podamos determinar X a partir de N cuando Y = 0. Lo siguiente es una combinación aritmética simple para dar {X, Y} único por cada N.Esto proporciona la calidad biyectiva requerida, pero X e Y no son solo negativos, pero la pregunta requiere todos los enteros posibles. Entonces X e Y se asignan usando
((t+1)/2)*((t+1)~2*2-1)
para dar todos los enteros posibles.dc
tiene números de precisión arbitrarios, por lo que el rango de entrada a2^31-1
no es un problema. Tenga en cuenta también que la precisión predeterminada es 0 dígitos decimales, y elsqrt()
y/
redondee hacia abajo que es el comportamiento necesita aquí.Salida:
fuente
Matlab, 54 bytes
La clave aquí es que
spiral
esto crea una matriz espiral de un tamaño arbitrario.devoluciones
spiral
fuente
Haskell,
7874 bytesPrueba de funcionamiento:
Cómo funciona: enumere todos los pares en el primer cuadrante en el siguiente orden
refleje cada punto en los otros cuadrantes para hacer una lista de 4 listas de elementos. Concatenar todo en una sola lista y tomar el
n
elemento th.Editar: la función no necesita un nombre, ordenó las matemáticas. expresiones
fuente
do
-notation: ¡ Pruébelo en línea!Haskell , 50 bytes
¡Pruébelo en línea o pruébelo con su inverso!
Sin golf
Explicación
(!)
l
xCounter
y
Tenga en cuenta que la función real
f
(ntoN2
) incrementa la entrada antes de comenzar con el procedimiento.fuente
05AB1E , 35 bytes
Pruébalo en línea! o como conjunto de pruebas
Explicación
Considerar
Entonces considerasol: N × N( m , n )⟶ Z × Z⟼ ( h ( m ) , h ( n ) ),
dónde
h : Nnorte⟶ Z⟼ { n2,- n + 12,n incluson impar.
Ya que F , sol y h todos son biyecciones, la composición sol∘ f: N ⟶ Z × Z Es una biyección.
El programa simplemente calculasol∘ f .
fuente
Mathematica, 46
Ordene los vectores según su norma, luego tome el
n
th.fuente
JavaScript,
166168bytes / caracteresNuevo enfoque usando una espiral rectangular como otros están usando.
He utilizado esta respuesta en Math.SE, traduje a JS y comprimido usando UglifyJS .
Este enfoque no utiliza ningún bucle ni crea la espiral de ninguna manera.
Debido a que las coordenadas de la espiral cubren todos los enteros, la función es biyectiva en el sentido deF: N0 0→ Z2 .
Actualización: Guardado 2 caracteres mediante el almacenamiento
Math
enb
.Actualización 2: reemplazadoF( 0 ) = f( 8 ) . Esto ya no genera una espiral, pero funciona para todos los enteros no negativosnorte0 0 (todos los números naturales incluidos 0 0 )
t-=1
port+=4
para solucionar el problema que causófuente