Прогулка по гиперкубу

9

Недавно я прочитал теорию графов, особенно гиперкубы, и подумал об интересных способах построения путей на них. Вот что я придумал.

Как вы знаете, вы можете построить п-мерный гиперкуб путем принятия всех кортежей , состоящих из 1и в 0качестве вершин и соединить их, тогда и только тогда они различаются по одной цифре. Если вы интерпретируете эти двоичные цифры как целое число, вы получите граф с хорошо пронумерованными вершинами. Например для n=3:

введите описание изображения здесь

Допустим, вы хотите прогуляться по этому гиперкубу и начать с вершины 0. Теперь, как вы определяете, какую вершину вы хотите посетить дальше? Правило, которое я придумал, состоит в том, чтобы взять номер aвершины, в которой вы находитесь, перевернуть ее mod(a,n)бит s (индексирование с нуля) и перейти к полученной вершине. Формально это правило может быть рекурсивно определено как

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

Следуя этому правилу, вы всегда будете оставаться на кубе и путешествовать по краям. Получившийся путь выглядит так

введите описание изображения здесь

Как видите, вы будете ходить по кругу! Фактически, во всех измерениях и для всех начальных точек ваш путь окажется в петле. Например, n=14и a[0]=0это выглядит так

введите описание изображения здесь

Для заядлого любителя длина его запланированного маршрута является весьма важной информацией. Итак, ваша задача - написать функцию или программу, которая принимает измерение гиперкуба в nкачестве входной вершины в a[0]качестве входных данных и выводит количество вершин в результирующем цикле.

Контрольные примеры

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

правила

  • Стандартные лазейки запрещены
  • Вывод / ввод может быть в любом подходящем формате
  • Вы можете считать a[0]допустимой вершину

счет

Самый короткий код в байтах побеждает.

Если у вас есть дополнительная информация по этой теме, я буду рад услышать!

Murphy
источник
Учитывая правило a[m+1] = xor(a[m], 2^mod(a[m],n)), это не имеет значения, если вершины принадлежат гиперкубу, верно?
Луис Мендо
Правильно. Если бы a[m]был на гиперкубе, a[m+1]тоже будет. И, как вы можете предположить, a[0]что это верная вершина, вам почти не нужно заботиться о каких-либо вещах гиперкуба и просто следовать правилу.
Мерфи
1
Где гипер муравьи?
Bassdrop Cumberwubwubwub

Ответы:

4

Желе, 9 байт

%⁴2*^µÐḶL

Принимает два аргумента командной строки.

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

Попробуй это здесь .

lirtosiast
источник
2

Хаскелл, 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)

Это находит круг с помощью алгоритма двух указателей, обходящих разные скорости, и интенсивно использует / злоупотребляет подходом Haskell к спискам (например, два указателя на самом деле являются списками).

gэто функция, которая вычисляет ответ. дайте его nи затем, a[0]и он вернет вам номер (обратите внимание, что он nдолжен быть определен как тип, Intчтобы избежать неоднозначности типа).

гордый хаскеллер
источник
1

JavaScript (ES6), 69 байт

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

Возвращает 18812 для (23, 10).

Нил
источник
1

MATL , 38 37 28 байт

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

Это работает в текущей версии (15.0.0) языка.

Попробуйте онлайн !

объяснение

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 Правда! Спасибо. Отредактировано
Luis Mendo
1

Pyth, 22 17 байт

Lx^2%bQbl.uyNuyGE

Объяснение:

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.

Попробуй это здесь .

lirtosiast
источник