Andando no hipercubo

9

Recentemente, li a teoria dos grafos, especialmente os hipercubos, e pensei em maneiras interessantes de construir caminhos neles. Aqui está o que eu criei.

Como você deve saber, é possível construir um hipercubo n-dimensional pegando todas as n-tuplas que consistem em 1e 0como vértices e conectá-las, se elas diferirem em um dígito. Se você interpreta esses dígitos binários como um número inteiro, acaba com um gráfico com vértices bem numerados. Por exemplo para n=3:

insira a descrição da imagem aqui

Digamos que você queira dar uma volta neste hipercubo e começar no vértice 0. Agora, como você determina qual vértice deseja visitar a seguir? A regra que inventei é pegar o número ado vértice em que você está, virar o mod(a,n)bit s (indexação baseada em zero) e ir para o vértice resultante. Formalmente, esta regra pode ser definida recursivamente como

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

Seguindo essa regra, você sempre permanecerá no cubo e viajará pelas bordas. O caminho resultante se parece com isso

insira a descrição da imagem aqui

Como você pode ver, você andará em círculo! De fato, em todas as dimensões e em todos os pontos de partida, seu caminho terminará em um loop. Por exemplo, n=14e a[0]=0parece com isso

insira a descrição da imagem aqui

Para o ávido ambler, o comprimento de sua rota planejada é uma informação crucial. Portanto, seu trabalho é escrever uma função ou um programa que leve a dimensão do hipercubo ne o vértice inicial a[0]como entradas e produza o número de vértices no loop resultante.

Casos de teste

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

Regras

  • As brechas padrão são proibidas
  • Saída / Entrada pode estar em qualquer formato adequado
  • Você pode assumir a[0]um vértice válido

Pontuação

O menor código em bytes vence.

Se você tiver mais informações sobre esse tópico, ficarei feliz em ouvir!

Murphy
fonte
Dada a regra a[m+1] = xor(a[m], 2^mod(a[m],n)), é irrelevante se os vértices pertencerem a um hipercubo, certo?
Luis Mendo
Direita. Se a[m]estava no hipercubo, a[m+1]também estará. E como você pode assumir a[0]um vértice válido, praticamente não precisa se preocupar com nada de hipercubo e apenas siga a regra.
21716 Murphy
11
Onde estão as hiper formigas?
você precisa saber é o seguinte

Respostas:

4

Geléia, 9 bytes

%⁴2*^µÐḶL

Leva dois argumentos de linha de comando.

%⁴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.

Experimente aqui .

lirtosiast
fonte
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)

Ele encontra o círculo pelo algoritmo de dois ponteiros que circula em velocidades diferentes e usa / abusa fortemente da abordagem de Haskell às listas (por exemplo, os dois ponteiros são realmente listas).

gé a função que calcula a resposta. forneça-o ne, em seguida, a[0]ele retornará o número para você (observe que ndeve ser definido como do tipo Intpara evitar ambigüidade)

orgulhoso haskeller
fonte
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}

Retorna 18812 para (23, 10).

Neil
fonte
1

MATL , 38 37 28 bytes

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

Isso funciona na versão atual (15.0.0) do idioma.

Experimente online !

Explicação

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
fonte
@lirtosiast True! Obrigado. Editado
Luis Mendo
1

Pyth, 22 17 bytes

Lx^2%bQbl.uyNuyGE

Explicação:

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.

Experimente aqui .

lirtosiast
fonte