ハイパーキューブを歩く


9

私は最近、グラフ理論、特にハイパーキューブについて読み、それらのパスを構築する興味深い方法について考えました。これが私が思いついたものです。

あなたが知っているかもしれませんが、あなたは、以下からなるすべてのnタプルを取ることによってn次元ハイパーキューブを構築することができます1し、0彼らは一桁が異なる場合に限っ、それらを頂点とし、接続します。これらの2進数を整数として解釈すると、頂点が適切に番号付けされたグラフになります。たとえばn=3

ここに画像の説明を入力してください

このハイパーキューブを散歩して、頂点から始めたいとしましょう0。次に、どの頂点を次に訪問するかをどのように決定しますか?私が思いついたルールaは、あなたがいる頂点の番号を取り、そのmod(a,n)ビットを反転させ(ゼロベースのインデックス付け)、結果の頂点に移動することです。正式には、このルールは次のように再帰的に定義できます。

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

このルールに従うことで、常にキューブにとどまり、エッジに沿って移動します。結果のパスは次のようになります

ここに画像の説明を入力してください

ご覧のとおり、円を描くように歩きます!実際、すべての次元で、すべての開始点で、パスはループになります。以下のための例えばn=14a[0]=0、それは次のようになります

ここに画像の説明を入力してください

熱心なアンブラーにとって、彼の計画されたルートの長さは非常に重要な情報です。したがって、あなたの仕事は、入力としてハイパーキューブの次元nと開始頂点を取りa[0]、結果のループ内の頂点の数を出力する関数またはプログラムを作成することです。

テストケース

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

ルール

  • 標準の抜け穴は禁止されています
  • 出力/入力は任意の適切な形式にすることができます
  • a[0]有効な頂点であると想定できます

得点

バイト単位の最短コードが優先されます。

このトピックに関する追加情報がありましたら、お聞かせください。


ルールを考えると、a[m+1] = xor(a[m], 2^mod(a[m],n))頂点がハイパーキューブに属しているかどうかは関係ありませんよね?
Luis Mendo 2016年

正しい。場合はa[m]ハイパーキューブ上にあった、a[m+1]あまりにもなります。そしてa[0]、有効な頂点であると想定できるので、ハイパーキューブのことを気にする必要はほとんどなく、ルールに従うだけです。
マーフィー

回答:


4

ゼリー、9バイト

%⁴2*^µÐḶL

2つのコマンドライン引数を取ります。

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

こちらでお試しください。


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)

これは、2つのポインタが異なる速度で移動するアルゴリズムによって円を見つけ、リストに対するHaskellのアプローチを頻繁に使用または乱用します(たとえば、2つのポインタは実際にはリストです)。

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}

(23、10)に対して18812を返します。


1

MATL38 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 True!ありがとう。編集済み
Luis Mendo 2016年

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.

こちらでお試しください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.