Camminando sull'Ipercubo


9

Di recente ho letto la teoria dei grafi, in particolare ipercubi e ho pensato a modi interessanti per costruirvi dei percorsi. Ecco cosa mi è venuto in mente.

Come forse saprai, puoi costruire un ipercubo n-dimensionale prendendo tutte le n-tuple costituite da 1e 0come vertici e collegandole, se differiscono in una cifra. Se interpretate queste cifre binarie come un numero intero, finirete con un grafico con vertici ben numerati. Ad esempio per n=3:

inserisci qui la descrizione dell'immagine

Diciamo che vuoi fare una passeggiata su questo ipercubo e iniziare dal vertice 0. Ora, come si determina quale vertice si desidera visitare dopo? La regola che mi è venuta in mente è prendere il numero adel vertice in cui ti trovi, capovolgerne il mod(a,n)bit (indicizzazione in base zero) e passare al vertice risultante. Formalmente questa regola può essere definita in modo ricorsivo come

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

Seguendo questa regola, rimarrai sempre sul cubo e viaggerai lungo i bordi. Il percorso risultante è simile al seguente

inserisci qui la descrizione dell'immagine

Come puoi vedere, camminerai in cerchio! In effetti, in tutte le dimensioni e per tutti i punti di partenza, il tuo percorso finirà in un ciclo. Ad esempio per n=14e a[0]=0sembra così

inserisci qui la descrizione dell'immagine

Per l'avido ambler, la lunghezza del suo percorso pianificato è un'informazione piuttosto cruciale. Quindi, il tuo compito è quello di scrivere una funzione o un programma che prenda la dimensione dell'ipercubo ne il vertice iniziale a[0]come input e produca il numero di vertici nel loop risultante.

Casi test

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

Regole

  • Sono vietate le scappatoie standard
  • Output / Input può essere in qualsiasi formato adatto
  • Puoi presumere a[0]di essere un vertice valido

punteggio

Vince il codice più breve in byte.

Se hai ulteriori informazioni su questo argomento, sarei felice di sapere!


Data la regola a[m+1] = xor(a[m], 2^mod(a[m],n)), è irrilevante se i vertici appartengono a un ipercubo, giusto?
Luis Mendo,

Giusto. Se a[m]fosse sull'ipercubo, a[m+1]lo sarà anche. E dato che puoi supporre a[0]che sia un vertice valido, praticamente non devi preoccuparti di alcun materiale ipercubo e seguire semplicemente la regola.
Murphy

Risposte:


4

Gelatina, 9 byte

%⁴2*^µÐḶL

Accetta due argomenti della riga di 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.

Provalo qui .


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)

Questo trova il cerchio con l'algoritmo a due puntatori che va in giro con velocità diverse e usa / abusa pesantemente l'approccio di Haskell agli elenchi (ad esempio, i due puntatori sono in realtà elenchi).

gè la funzione che calcola la risposta. dare ne poi a[0]e ti restituirà il numero (nota che ndovrebbe essere definito come di tipo Intper evitare ambiguità di tipo).


1

JavaScript (ES6), 69 byte

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

Restituisce 18812 per (23, 10).


1

MATL , 38 37 28 byte

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

Funziona con la versione corrente (15.0.0) della lingua.

Provalo online !

Spiegazione

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

@lirtosiast True! Grazie. A cura
Luis Mendo

1

Pyth, 22 17 byte

Lx^2%bQbl.uyNuyGE

Spiegazione:

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.

Provalo qui .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.