Marcher sur l'hypercube


9

J'ai récemment lu sur la théorie des graphes, en particulier les hypercubes et réfléchi à des façons intéressantes de construire des chemins sur eux. Voici ce que j'ai trouvé.

Comme vous le savez peut-être, vous pouvez construire un hypercube à n dimensions en prenant tous les n-tuples constitués 1et en 0tant que sommets et les connecter, ssi ils diffèrent sur un chiffre. Si vous interprétez ces chiffres binaires comme un nombre entier, vous vous retrouvez avec un graphique avec des sommets bien numérotés. Par exemple pour n=3:

entrez la description de l'image ici

Disons que vous voulez vous promener sur cet hypercube et commencer au sommet 0. Maintenant, comment déterminez-vous le sommet que vous souhaitez visiter ensuite? La règle que j'ai trouvée est de prendre le numéro adu sommet sur lequel vous êtes, de retourner son mod(a,n)bit s (indexation à base zéro) et d'aller au sommet résultant. Formellement, cette règle peut être définie récursivement comme

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

En suivant cette règle, vous resterez toujours sur le cube et voyagerez le long des bords. Le chemin résultant ressemble à ceci

entrez la description de l'image ici

Comme vous pouvez le voir, vous marcherez en cercle! En fait, dans toutes les dimensions et pour tous les points de départ, votre chemin se terminera en boucle. Par exemple pour n=14et a[0]=0cela ressemble à ceci

entrez la description de l'image ici

Pour l'ambler passionné, la longueur de son itinéraire prévu est une information assez cruciale. Donc, votre travail consiste à écrire une fonction ou un programme qui prend la dimension de l'hypercube et nle sommet de départ a[0]comme entrées et à afficher le nombre de sommets dans la boucle résultante.

Cas de test

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

Règles

  • Les failles standard sont interdites
  • La sortie / entrée peut être dans n'importe quel format approprié
  • Vous pouvez supposer a[0]être un sommet valide

Notation

Le code le plus court en octets gagne.

Si vous avez des informations supplémentaires sur ce sujet, je serais heureux de les entendre!


Compte tenu de la règle a[m+1] = xor(a[m], 2^mod(a[m],n)), ce n'est pas pertinent si les sommets appartiennent à un hypercube, non?
Luis Mendo

Droite. Si a[m]était sur l'hypercube, le a[m+1]sera aussi. Et comme vous pouvez supposer a[0]être un sommet valide, vous n'avez pratiquement pas besoin de vous soucier de tout hypercube et de simplement suivre la règle.
murphy

Réponses:


4

Gelée, 9 octets

%⁴2*^µÐḶL

Prend deux arguments de ligne de commande.

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

Essayez-le ici .


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)

Cela trouve le cercle par l'algorithme à deux pointeurs circulant à différentes vitesses et utilise fortement / abuse l'approche de Haskell des listes (par exemple, les deux pointeurs sont en fait des listes).

gest la fonction qui calcule la réponse. donnez-le net puis a[0]et il vous renverra le numéro (notez que cela ndevrait être défini comme étant de type Intpour éviter toute ambiguïté de type).


1

JavaScript (ES6), 69 octets

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

Renvoie 18812 pour (23, 10).


1

MATL , 38 37 28 octets

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

Cela fonctionne dans la version actuelle (15.0.0) de la langue.

Essayez-le en ligne !

Explication

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! Merci. Modifié
Luis Mendo

1

Pyth, 22 17 octets

Lx^2%bQbl.uyNuyGE

Explication:

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.

Essayez-le ici .

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.