Caminando en el hipercubo

9

Recientemente leí sobre teoría de grafos, especialmente hipercubos y pensé en formas interesantes de construir caminos en ellos. Esto es lo que se me ocurrió.

Como puede saber, puede construir un hipercubo n-dimensional tomando todas las n-tuplas que consisten en 1y 0como vértices y conectarlos, si difieren en un dígito. Si interpreta estos dígitos binarios como un número entero, termina con un gráfico con vértices bien numerados. Por ejemplo para n=3:

ingrese la descripción de la imagen aquí

Digamos que desea dar un paseo por este hipercubo y comenzar en el vértice 0. Ahora, ¿cómo determina qué vértice desea visitar a continuación? La regla que se me ocurrió es tomar el número adel vértice en el que se encuentra, voltear su mod(a,n)bit s (indexación basada en cero) e ir al vértice resultante. Formalmente, esta regla puede definirse recursivamente como

a[m+1] = xor(a[m], 2^mod(a[m],n)).

Al seguir esta regla, siempre permanecerá en el cubo y viajará a lo largo de los bordes. El camino resultante se ve así

ingrese la descripción de la imagen aquí

Como puedes ver, ¡caminarás en círculo! De hecho, en todas las dimensiones y para todos los puntos de partida, su camino terminará en un bucle. Por ejemplo para n=14y a[0]=0se ve así

ingrese la descripción de la imagen aquí

Para el ambicioso ambler, la longitud de su ruta planeada es una información bastante crucial. Entonces, su trabajo es escribir una función o un programa que tome la dimensión del hipercubo ncomo el vértice inicial a[0]como entradas y genere el número de vértices en el bucle resultante.

Casos de prueba

n   a[0]   Output
-----------------
3   0      6
14  0      50
5   6      8
17  3      346

Reglas

  • Las lagunas estándar están prohibidas
  • La salida / entrada puede estar en cualquier formato adecuado
  • Puede asumir a[0]que es un vértice válido

Puntuación

El código más corto en bytes gana.

Si tiene información adicional sobre este tema, ¡me encantaría saberlo!

murphy
fuente
Dada la regla a[m+1] = xor(a[m], 2^mod(a[m],n)), es irrelevante si los vértices pertenecen a un hipercubo, ¿verdad?
Luis Mendo
Derecha. Si a[m]estaba en el hipercubo, también a[m+1]lo estará. Y como puede suponer a[0]que es un vértice válido, prácticamente no necesita preocuparse por nada de hipercubos y simplemente seguir la regla.
murphy
1
¿Dónde están las hormigas hiper?
Bassdrop Cumberwubwubwub

Respuestas:

4

Jalea, 9 bytes

%⁴2*^µÐḶL

Toma dos argumentos de línea de comandos.

%⁴2*^µÐḶL        A monadic link. Inputs: a_0. b also taken from command line.
%⁴2*^              Variadic link. Input: a
%⁴                   a modulo b. ⁴ is second input, b.
  2*                 Get 2 to that power
    ^                and bitwise xor with a.
     µ             Start a new, monadic link (input: a_0)
      ÐḶ             All elements of the cycle created when the preceding link
                     is applied repeatedly, starting with a_0.
        L            Length.

Probarlo aquí .

lirtosiast
fuente
2

Haskell, 124

import Data.Bits
(y:z:w)%(x:s)|x==y||x==z=[i|(i,r)<-zip[1..]s,r==x]!!0|0<1=w%s
g n=(tail>>=(%)).iterate(\a->xor a$2^mod a n)

Esto encuentra el círculo mediante el algoritmo de dos punteros dando vueltas en diferentes velocidades, y usa / abusa en gran medida del enfoque de Haskell a las listas (por ejemplo, los dos punteros son en realidad listas).

ges la función que calcula la respuesta. dáselo ny luego a[0]te devolverá el número (ten en cuenta quen debe definirse como de tipo Intpara evitar la ambigüedad de tipo).

orgulloso Haskeller
fuente
1

JavaScript (ES6), 69 bytes

(n,a)=>{g=m=>m^1<<m%n;for(c=1,b=a;(b=g(g(b)))!=(a=g(a));)c++;return c}

Devuelve 18812 para (23, 10).

Neil
fuente
1

MATL , 38 37 28 bytes

xi`vt0)2y1G\^Z~yywP=fn~]2M1$

Esto funciona en la versión actual (15.0.0) del lenguaje.

Pruébalo en línea !

Explicación

x       % take first input: n. Delete (gets copied into clipboard G)
i       % take second input: initial value of a
`       % do...while loop
  v     %   concatenate all stack contents vertically
  t0)   %   duplicate. Get last element of that array: current a
  2     %   push 2
  y     %   duplicate second-top element in stack: current a
  1G    %   push first input (n)
  \     %   a modulo n
  ^     %   2 raised to that
  Z~    %   xor of that with current a
  yy    %   duplicate top two elements in stack: array of old a's and new a
  w     %   swap: move array of old a's to top
  P     %   reverse that array. So first entry is most recent a (before current)
  =f    %   indices of old values that equal current value. There may be 0 or 1
  n~    %   is it empty?
]       % if so, continue with a new iteration
2M      % push array of indices. It contains exactly 1 index
1$      % set 1 input for implicit display function, so it only displays the index
Luis Mendo
fuente
@lirtosiast cierto! Gracias. Editado
Luis Mendo
1

Pyth, 22 17 bytes

Lx^2%bQbl.uyNuyGE

Explicación:

Lx^2%bQbl.uyNuyGE     Implicit: Q=first line n. E=second line a[0].
Lx^2%bQb              y = lambda b: do one iteration
                      Then
             uyGE     Apply y until a previous result is found.
                      This makes sure we're in the cycle.
         .uyN         Then apply y again until a previous result is found.
                      Keep all intermediate values but not the repeat.
        l             Get the length; i.e. the length of the cycle.

Probarlo aquí .

lirtosiast
fuente