Enumeración de vectores N-dimensionales


17

Dado un número entero positivo k > 1y un número entero no negativo i, genera una ktupla (o kvector dimensional) de números enteros no negativos. Para cada k, el mapa de ℕ a ℕ k , debe ser biyectivo . Es decir, cada entrada idebe producir una tupla diferente y cada tupla posible debe ser producida por alguna entrada i.

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).

Puede utilizar cualquier formato de lista plana conveniente, inequívoco para la salida.

Su solución no debería imponer límites artificiales en ky ipero puede suponer que encajan en tamaño entero nativo de su lengua. Por lo menos, debe admitir valores hasta 255, sin embargo, incluso su tamaño entero nativo es más pequeño que eso.

En cualquier caso 1 < k < 32, su código debería producir un resultado en cuestión de segundos (por supuesto, si su respuesta no es tan grande debido a la regla anterior, el límite se ajusta en consecuencia). Esto debería ser ningún problema: es posible resolver este desafío tal que funciona hasta 2 128 en unos pocos segundos, pero el límite está ahí para respuestas Evita que en realidad iterate de que para encontrar el resultado.i < 231i0i

Incluya en su respuesta una descripción de su mapeo elegido y una justificación de por qué es biyectivo (esto no necesita ser una prueba formal).

Este es el código de golf, gana la respuesta más corta (en bytes).

Desafíos relacionados

Respuestas:


5

Pyth, 15 12 bytes

ms+0_%Q>_zdQ

Banco de pruebas

Mi transformación es similar a una de xnor, pero en la base 10. Funciona descomprimiendo la entrada en k números separados:

n = 21003034
k = 3

21003034
 1  3  4    134
2  0  3     203
  0  0        0

Los números se ordenan en posición decreciente del dígito más a la derecha, de modo que todos los ordenamientos de cualquier grupo de números son posibles.

La forma en que funciona el código es que invertimos la entrada, luego cortamos los últimos 0, 1, ... k-1dígitos, luego tomamos cada kdígito, volvemos a invertir , pegamos un 0al comienzo y lo convertimos en int.


4

CJam, 20 bytes

q~({4b2fmd2/z2fb~p}*

El mapeo es biyectivo ya que aplica el mapeo de esta respuesta k - 1 veces.

El programa lee la entrada como i k. Pruébelo en línea en el intérprete de CJam .

Idea

Podemos construir un mapeo biyectivo f: N → N 2 definiendo f (i) de la siguiente manera:

  • Convierta i en la matriz de sus dígitos binarios.

  • Anteponga un 0 a esta matriz si hay un número impar de dígitos.

  • Desintercalar la matriz resultante, formando nuevas en el proceso.

  • Convierta esas matrices de base 2 a entero. Definir f 1 (i) y f 2 (i) como los resultados.

Para obtener un mapeo biyectivo g: N → N 3 , podemos definir g (n): = (f 1 (i), f 1 (f 2 (i)), f 2 (f 2 (i))) .

Para obtener un mapeo biyectivo h: N → N 4 , podemos definir h (i): = (g 1 (i), g 2 (i), f 1 (g 3 (i)), f 2 (g 3 ( yo))) .

Continuando con el proceso anterior, finalmente llegamos a un mapa biyectivo N → N k .

Código

q~      e# Read and evaluate all input. This pushes i and k.
({      e# Do k-1 times:
  4b    e#   Convert the integer on the stack (initially i) to base 4.
  2fmd  e#   Replace each base-4 digit d by d/2 and d%2.
  2/    e#   Split into the chunks [d/2 d%2].
  z     e#   Transpose. This collects all quotients in one array and all
        e#   residues in another one.
  2fb   e#   Convert each array from base 2 to integer.
  ~     e#   Dump both integers on the stack.
  p     e#   Print the topmost one.
}*      e#

La idea de xnor también da 20 bytes (o menos si juegas mejor que yo): q~2bW%1$Te]/zWf%2fbp(orden de entrada opuesto)
Martin Ender

3

CJam, 18 bytes

q~({)2bW%_1#p))b}*

Utiliza una fórmula más estúpida.

Pruébalo aquí .

Explicación

q~          e# Read input.
({          e# Repeat k-1 times:
    )       e# Increment the current integer (initially i), to make it positive.
    2b      e# Convert to binary.
    W%      e# Reverse the binary.
            e# The result can be any non-empty binary string without trailing 0s.
    _1#     e# Find the position of the first 1, or the number of initial 0s.
    p       e# Print.
    )       e# Extract the final bit, which is always 1.
            e# An array that can be any binary string is left in the stack.
    )       e# Increment the 1 to make it 2.
    b       e# Convert the binary string to a number using base 2.
            e# Only the number of initial 0s doesn't affect the result,
            e# which is exactly what is printed before.
}*          e# The final integer is printed automatically when the program ends.

En resumen, mapea un entero positivo para:

  1. El número de ceros finales.
  2. El entero original con ceros finales eliminados, invertidos, y el final (originalmente inicial) 1 eliminado.

3

Pitón 2, 62

lambda z,k:[int('0'+bin(z)[~i:1:-k][::-1],2)for i in range(k)]

Este código es feo y golfable, pero la idea es muy simple.

Empaque kexpansiones binarias en una leyendo cada kdígito con diferentes desplazamientos. Por ejemplo, con k=3, la entrada se 357asigna a (3,0,7):

101100101 <- 357
  1  0  1 -> 5
 0  0  0  -> 0
1  1  1   -> 7

Comprimir los números de nuevo juntos lo invierte, por lo que es una biyección. Al hacerlo, piense que las expansiones binarias tienen un número infinito de ceros a la izquierda.


3

J, 38 28 27 bytes

(({.,g^:_1@}.)g=:_ q:>:)~<:

Este es un verbo tácito y diádico que toma i y k como argumentos izquierdo y derecho. Pruébelo en línea con J.js .

Idea

Definimos un mapa f: N → N k por f (i): = (α 1 , ... α k-1 , p 1 α k ... p 2 α k + 1 ... - 1) , donde ⟨p n es la secuencia de números primos e i + 1 = p 1 α 1 p 2 α 2 .

Según el teorema aritmético fundamental, el mapa g: N → N ω definido por g (i): = (α 1 , α 2 , ...) (exponentes de la factorización prima de i + 1 ) es biyectivo.

Como f (i) = (g 1 (i),… g k-1 (i), g -1 (g k (i), g k + 1 (i), ...)) , el mapa f es biyectivo como bien.

Código

                            Left argument: i -- Right argument: k
                         <: Decerement k.
(                      )~   Reverse the order of the arguments and apply the
                            dyadic verb inside the parentheses to k-1 and i.
              g=:            Define a monadic helper verb g:
                     >:       Increment its right argument.
                 _ q:         Calculate the exponents of the prime factorization.
                             (implicit) Apply g to i.
(            )               Apply the dyadic verb inside the parentheses to k-1
                             and (g i).
           }.                 Drop the first k-1 elements of (g i)...
          @                   and...
     g^:_1                    apply the inverse of g to the result.
  {.                          Take the first k-1 elements of (g i).
    ,                         Append the rightmost result to the leftmost one.

¿Por qué su función es biyectiva?
xnor

@xnor Al menos el de mi explicación no lo era, ya que había cambiado un par de índices por error. He añadido un boceto de prueba.
Dennis

1

Pitón 2, 72

q=lambda z:z and z%2+2*q(z/4)
g=lambda z,k:1/k*[z]or[q(z)]+g(q(z/2),k-1)

La función qactúa sobre números binarios tomando cada segundo bit comenzando desde el final. Como resultado, q(z), q(z>>1)da dos números cuyos dígitos binarios se entremezclan para dar z. Por ejemplo, 594 se divide en 12 y 17.

1001010010   <- 594
 0 1 1 0 0   ->  12
1 0 0 0 1    ->  17

Esto es una biyección porque podemos volver a unir los números para recuperar el número original.

La función gaplica estos k-1tiempos de biyección , expandiéndose de un solo elemento a un par a un triple ... a una ktupla. Cada vez, el último elemento se expande a dos elementos. Esto se hace recursivamente mapeando la entrada a un par a través de la biyección, tomando el primer elemento del par para la primera entrada de la salida y aplicando la función recursivamente con k-1el segundo elemento para producir las entradas restantes.


Me di cuenta de que estoy haciendo de esta manera también complicado ...
XNOR
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.