Chodzenie po Hypercube

9

Niedawno czytałem teorię grafów, zwłaszcza hipersześcianów i myślałem o interesujących sposobach budowania na nich ścieżek. Oto, co wymyśliłem.

Jak zapewne wiesz, możesz zbudować n-wymiarową hipersześcię, biorąc wszystkie n-krotki składające się z 1i 0jako wierzchołki i łącząc je, jeśli różnią się one jedną cyfrą. Jeśli interpretujesz te cyfry binarne jako liczbę całkowitą, powstaje wykres z ładnie numerowanymi wierzchołkami. Na przykład dla n=3:

wprowadź opis zdjęcia tutaj

Powiedzmy, że chcesz przejść się po tej hipersześcianie i zacząć od wierzchołka 0. Jak ustalić, który wierzchołek chcesz odwiedzić w następnej kolejności? Zasada, którą wymyśliłem, to wziąć numer awierzchołka, na którym jesteś, odwrócić jego mod(a,n)bit (indeksowanie od zera) i przejść do wynikowego wierzchołka. Formalnie tę regułę można rekurencyjnie zdefiniować jako

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

Przestrzegając tej zasady, zawsze pozostaniesz na sześcianie i będziesz podróżował wzdłuż krawędzi. Powstała ścieżka wygląda następująco

wprowadź opis zdjęcia tutaj

Jak widać, będziesz chodzić w kółko! W rzeczywistości we wszystkich wymiarach i dla wszystkich punktów początkowych twoja ścieżka skończy się w pętli. Na przykład dla n=14i a[0]=0wygląda to tak

wprowadź opis zdjęcia tutaj

Dla zapalonego amblera długość jego planowanej trasy jest dość istotną informacją. Twoim zadaniem jest napisanie funkcji lub programu, który przyjmuje wymiar hipersześcianu jako nwierzchołek początkowy a[0]jako dane wejściowe i wyprowadza liczbę wierzchołków w wynikowej pętli.

Przypadki testowe

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

Zasady

  • Standardowe luki są zabronione
  • Dane wyjściowe / wejściowe mogą być w dowolnym odpowiednim formacie
  • Możesz założyć, a[0]że jest poprawnym wierzchołkiem

Punktacja

Najkrótszy kod w bajtach wygrywa.

Jeśli masz dodatkowe informacje na ten temat, z przyjemnością usłyszę!

murphy
źródło
Biorąc pod uwagę zasadę a[m+1] = xor(a[m], 2^mod(a[m],n)), nie ma znaczenia, czy wierzchołki należą do hipersześcianu, prawda?
Luis Mendo,
Dobrze. Jeśli a[m]był na hipersześcianie, też a[m+1]będzie. A ponieważ możesz założyć, a[0]że jest to prawidłowy wierzchołek, właściwie nie musisz przejmować się żadnymi rzeczami związanymi z hipersześcianami i po prostu przestrzegaj reguły.
murphy
1
Gdzie są hiper-mrówki?
Bassdrop Cumberwubwubwub

Odpowiedzi:

4

Galaretka, 9 bajtów

%⁴2*^µÐḶL

Bierze dwa argumenty wiersza polecenia.

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

Wypróbuj tutaj .

lirtosiast
źródło
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)

Znajduje to koło za pomocą algorytmu dwupunktowego zmieniającego prędkość w różnych prędkościach i mocno wykorzystuje / nadużywa podejścia Haskella do list (na przykład dwa wskaźniki są w rzeczywistości listami).

gto funkcja, która oblicza odpowiedź. podaj go, na następnie a[0]zwróci ci numer (pamiętaj, że nnależy zdefiniować typ, Intaby uniknąć niejednoznaczności typu).

dumny haskeller
źródło
1

JavaScript (ES6), 69 bajtów

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

Zwraca 18812 dla (23, 10).

Neil
źródło
1

MATL , 38 37 28 bajtów

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

Działa to w bieżącej wersji (15.0.0) języka.

Wypróbuj online !

Wyjaśnienie

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
źródło
@lirtosiast Prawda! Dzięki. Edytowane
Luis Mendo,
1

Pyth, 22 17 bajtów

Lx^2%bQbl.uyNuyGE

Wyjaśnienie:

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.

Wypróbuj tutaj .

lirtosiast
źródło