キューブ上のアリ


33

アリは、ワイヤフレームキューブのエッジ(面ではなく)に沿って歩きます。遭遇する各頂点は、2つの新しいエッジが分岐するフォークを提示します。アリはどちらの方向に曲がるleftかを選択します- またはright。これらの方向は、頂点に向かい、立方体の外側にいるアリに相対的です。あなたの目標は、アリがとったleft/ right選択のシーケンスから、それが開始したのと同じ位置で終了するかどうかを判断することです。

たとえば、アリが4回左に曲がった場合(left left left left)、反時計回りに四角を横切り、開始した場所で終了します。しかし、それが進むleft left left left rightと、キューブ上の別の場所で終了します。また、それが進む場合left right right right left、開始エッジで終了しますが、反対側の頂点に面しますが、同じ位置としてカウントされません。

アリのパスは、開始したエッジを含むエッジを繰り返す場合がありますが、重要なのは、シーケンス全体の後に終了する場所です。

アリのターンシーケンスを受け取り、アリがシーケンスの後に開始位置に戻ったかどうかを出力する名前付き関数を作成します。名前のない関数を変数に割り当てるだけで、名前の付いた関数にできます。

編集変数。)

入力

選択した形式で表される、長さを含む一連のleft/ right決定。これは、文字の文字列/ 、数字のリスト/ 、またはブール値の配列です。コードに役立つメソッド名や文字列にすることなど、安っぽいものはありません。031RL1-1

以下のテストケースと異なる場合は、テストケースを形式で投稿してください。

出力

True/ False0/ 1、またはあなたの言語の類似物。

受賞基準

最少バイトが勝ちます。名前付き関数を指定する必要があることを忘れないでください。関数の外にコードを置くこともできますが、それらのバイトもカウントされます。複数回呼び出された場合、関数は正しく動作するはずです。

テストケース

True ケース(1行に1つ、2つ目は空のリスト):

1 1 1 1

-1 -1 -1 -1
1 -1 1 -1 1 -1
1 1 -1 -1 1 1 -1 -1
-1 1 1 -1 -1 1 1 -1
1 1 1 -1 -1 -1 -1 1
1 -1 -1 1 -1 -1
1 1 1 1 -1 -1 -1 -1 1 -1 -1 1 -1 -1
-1 -1 -1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

False ケース(1行に1つ):

1
1 1
1 1 1
-1 1
1 -1 -1 -1 1
1 -1 -1 1 1
-1 1 -1 1
1 1 1 1 -1
-1 -1 1 -1 1 -1 -1 1
1 -1 1 1 1 1 -1 -1 -1 1 1 -1 -1 -1

これはLR「s 」と「s 」を使用した同じテストケースです。

True ケース:

RRRR

LLLL
RLRLRL
RRLLRRLL
LRRLLRRL
RRRLLLLR
RLLRLL
RRRRLLLLRLLRLL
LLLRLLRRLRLRRRRRRRRRRRRRRRRR

False ケース:

R
RR
RRR
LR
RLLLR
RLLRR
LRLR
RRRRL
LLRLRLLR
RLRRRRLLLRRLLL

追加クレジットチャレンジ

同じことですが、立方体ではなく十二面体を使用しています。アイデアについては、ハンプザワンパスをご覧ください。


これは、名前付き関数のない言語の使用を排除しますか?
マイクプレカップ14

@MikePrecupそのような言語の例をいくつか教えていただけますか?代替案を検討します。
xnor 14

私はすべてのコードゴルフの提出を> <>で行います。これには、一番上に引数をロードし、その結果をスタックに残すことができるスタックがありますが、正確には名前付き関数ではありません。
マイクプレカップ14

@MikePrecup OK、それのための手当を入れました。一部の言語でまだ問題が発生する場合は、言語を除外しないでください。
XNOR

私はbefungeと> <>とこの種の言語について考えることができます
誇りに思ってhaskeller 14

回答:


21

GolfScript、24文字(関数本体のみで19文字)

数学FTW!

{3,.@{[+~@\{@}*~]}/=}:f;

このソリューションをオンラインでテストします。

この関数は、入力としてバイナリ配列(左が0、右が1)を受け取り、trueの場合は1、falseの場合は0を返します。

概念的には、 キューブをて、アリが常に同じ位置と方向を維持し、最終的にキューブが最初と同じ方向になっているかどうかを確認することで機能します。

特に、左と右のターンを3次元の2つの線形マップとして表すことができます。左のターンはx軸を中心とした90°の回転に対応します。つまり、マップ(xyz)→(xz、 − y)、右回転はy軸を中心とした90°の回転に対応します。つまり、マップ(xyz)→(zy、− x)に対応します。

関数の最初に、明確な正の値(1、2、3)を含む3要素ベクトルを設定し、回転マップのシーケンスを適用して、結果のベクトルが最初のベクトルと等しいかどうかを確認します。

(実際には、いくつかの文字を保存するために、実際に初期ベクトルが(0、1、2)で、マップが(xyz)→(xz、−1− y)になるように座標を変換しますおよび(xyz)→(zy、−1− x)、ただし最終結果は同じです。)

追伸 おかげ誇りhaskellerこのソリューションの元のバージョンでバグを発見してます。


Perl、58文字

コメントで要求されたように、Perlに移植された同じソリューションがあります。(このバージョンでは、変換によってPerlで文字が保存されないため、実際には変換されていない座標が使用されます。)

sub f{@a=@b=1..3;@a[$_,2]=($a[2],-$a[$_])for@_;"@a"eq"@b"}

このソリューションをオンラインでテストします。


ボーナス:十二面体の蟻(GolfScript、26文字)

{5,.@{{2*2%[~\]}*(+}/=}:f;

このソリューションをオンラインでテストします。

上記のant-on-a-cube関数と同様に、この関数は入力としてバイナリ配列(左は0、右は1)を受け取り、アリが開始時と同じ位置と方向になった場合は1を返します。または0さもないと。

このソリューションでは、上記のキューブソリューションよりも少し抽象的な表現を使用しています。具体的には、十二面体の回転対称群が交互群 A 5、つまり5つの要素の偶数順列の群と同型であるという事実を利用します。したがって、十二面体の各可能な回転(エッジをエッジに、頂点を頂点にマップする)は、置換として一意に表すことができます。 5要素配列の、連続した回転は、対応する順列を順番に適用することに対応します。

したがって、行う必要があるのは、左右の回転を表すことができる2つの順列LRを見つけることだけです。具体的には、これらの順列は5サイクルである必要があり(5回適用すると元の状態に戻ります)、互いのべき乗(つまり、nに対してRL n)であってはならず、関係を満たす必要があります(LR5 =(1)、ここで(1)は恒等置換を表します。(実際には、この基準は、パスが元の位置に戻る必要があることを示しています。)LRLRLRLRLR

L順列を単純な左へのバレルシフトに修正します。つまり、GolfScriptに2つだけ実装できるため、マッピング(abcde)→(bcdea) chars((+)、R置換には5つの可能な選択肢があることがわかります。それらのうち、マッピング(abcde)→(ced ba)、比較的コンパクトなGolfScript実装もあるため。(実際には、要素をインターリーブ2*2%して(acebd)を取得し、最後の2つの要素を[~\]で交換し、最後にL順列を無条件に適用してaを末尾に移動することで実装します。)

上記のオンラインデモリンクには、次のような、原点に戻る12面体上の有効なパスのテストケースが含まれています。

           # empty path
1 1 1 1 1  # clockwise loop
0 0 0 0 0  # counterclockwise loop
1 0 0 0 0 1 1 0 0 0 0 1  # figure of 8
1 0 1 0 1 0 1 0 1 0      # grand circle
1 0 0 0 1 0 0 0          # loop around two faces 
1 0 0 0 1 1 1 0 1 0 1 0 0 0 1 1 1 0 1 0  # Hamilton cycle

いい解決策!これは、アリが別の方向から同じ頂点に戻る場合を除外しますか?
xnor 14

私は理解していません-基本的にここであなたがしていることは3ビットを使用してアリの位置を表すことですが、24の可能な位置があります。どうやって?
誇りに思ってhaskeller 14

1
@proudhaskeller:バグを見つけてくれてありがとう。これを修正し、テストスイートに反例を追加しました。
イルマリカロネン14

1
@xnor:12面体のソリューションも追加しました。
イルマリカロネン14

1
十二面体の順列の素敵なペア。ハンプ・ザ・ワンプスに使用したものは、1文字長くなります:{[~@]-1%}*[~@]または){[~@]-1%}*-1%あなたを置き換える{2*2%[~\]}*(+
ピーターテイラー14

7

Python、68

1と-1のリストを取ります。3D回転に基づく:一連の回転を適用した後、ポイント(3,2,1)が同じ位置に到達するかどうかを確認します。1と-1に対応する2つの可能な回転があります。それぞれは、2つの座標を並べ替え、そのうちの1つの符号を変更することによって行われます。変更する正確な座標と置換するサインは重要ではありません。

def f(l):
 p=[3,2,1]
 for d in l:p[d],p[0]=-p[0],p[d]
 return[3,2]<p

編集:これは実際には「Perl、58」とほとんど同じ解決策です。


あなたは正しい、それは確かです。
誇りに思ってhaskeller

+1、それはまだPythonソリューションでの私の試みよりも短いです。しかし、私が持っているものを見ると、入力を0と1として取り、最後の要素をp別の変数に分割することで、さらにいくつかの文字を節約できると思います。
イルマリカロネン14

3
うわー、この問題をテスト解決するとき、変数名を除いて文字ごとにまったく同じ解決策を書きました!
xnor 14

5

Mathematica

Ilmari Karonenのソリューションに触発されました。立方体の回転対称群は、S 4と同型です。

キューブ、51バイト

Fold[Part,r=Range@4,{{2,3,4,1},{3,4,2,1}}[[#]]]==r&

1sおよび-1sのリストを入力として受け取ります。

オンラインでお試しください!

十二面体、55バイト

Fold[Part,r=Range@5,{{2,3,4,5,1},{3,5,4,2,1}}[[#]]]==r&

のリストを取る 1sおよび-1sの入力として受け取ります。

オンラインでお試しください!


私はそれがS3と同型であることをどのように見つけることができるかを探していましたか?
誇りに思ってhaskeller 14

?おっと、私はそれはそれはS4に同型だということを証明/見つけることができますどのように」意味
誇りhaskeller

@proudhaskellerここで見つけることができます:en.wikipedia.org/wiki/Octahedral_symmetry
alephalpha 14

5

C(GCC) 118の 116 107 105バイト

ceilingcatのおかげで-2バイト

f(char*s){char*p,n[]="@ABCDEFG",y;for(;*s;s++)for(p=n;*p;*p++^=*s^82?y%2+1:4-(y&2))y=*p/2^*p;y=n[2]==66;}

オンラインでお試しください!

キューブに次の座標を与えたとします:

            (1,1,1)       (1,1,0)
          G +--------------+ C
           /|             /|
          / |            / |
         /  |    (0,1,0)/  |
(0,1,1) +--------------+ D |
      H |   |          |   |
        |   |          |   |
        | F +----------|---+ (1,0,0)
        |  /(1,0,1)    |  / B           x
        | /            | /           y / 
        |/             |/            |/  
      E +--------------+ A      z ---*   
        (0,0,1)       (0,0,0)

コーナーDから開始する場合、CまたはHに移動することは、代わりにキューブを回転させることと考えることができます。右に移動すると、Z軸を中心に反時計回りに回転し、左に移動すると、X軸を中心に時計回りに回転します。これらは、気にする必要のある2つの回転です。各回転は正確に90度であるため、角がエッジに沿って「スライド」することを想像できます。右に移動する場合、これはA-> B、B-> C、C-> D、D-> Aを意味し、反対側はE-> Fなどを実行します。左に移動する場合、代わりにA-> E、E- > Hなど

各コーナーはエッジに沿ってスライドするだけなので、各ポイントの寸法のうち1つだけが回転ごとに変化することを意味します。BがCに移動すると、そのyコンポーネントのみが変化し、HがDに移動すると、そのzコンポーネントのみが変化します。さらに、座標は0と1に制限されているため、各ポイントは、移動時に適切なビットが反転した2進数と考えることができます。

右への移動では、AとCがxを反転させ、DとBがyを反転させることがわかります。遠近法を変更して立方体の向こう側を見ると、zコンポーネント(この回転でも変化しない)を無視すると、次のようになります。

D (0,1)         C (1,1)
 +-------------+
 |             |
 |             |
 |             |
 |             |
 |             |
 |             |
 +-------------+
A (0,0)         B (1,0)

パターンが出現します。xを反転するポイントの場合、x == yですが、yを反転するポイントの場合は逆になります。これは、他のタイプの回転にも当てはまりますが、xの代わりにzを使用します。

言い換えると:

Right
    if (x == y) x = !x
    if (x != y) y = !y

Left
    if (z == y) z = !z
    if (z != y) y = !y

これで、すべての回転を簡単に実行でき、最後に最終Dが初期Dと一致するかどうかを確認できます。

各ポイントを1つの数値として保存することはできますが、Cでは、char配列を割り当てることはint配列よりはるかにコンパクトです。下位3ビットが000..111に一致する文字を選択するように注意し、残りのビットのみを無視できるようにします。座標の反転は、適切なビットマスクとのXORの問題です。


1
長い説明に感謝し、他の答えは私の頭の中ではあまりクリックしませんでしたが、これはすぐに意味をなしました。
Nit

4

Python-110、150

-1左折、右折で整数のリストを受け取ります1

キューブ、110:

def f(l):
    c,p='07'
    for d in l:a="100134462634671073525275"[int(c)::8];c,p=a[(a.index(p)+d)%3],c
    return'1'>c

テスト:

l=map(int,'1 1 1 1'.split())
print f(l)

十二面体、150:

def f(l):
    c,p='0J'
    for d in l:a="I5H76E8BBA8F76543100JI0J21D3A5C7E9CJI2132H4GF94C6D98AHGBEDGF"[int(c,36)::20];c,p=a[(a.index(p)+d)%3],c
    return'1'>c

1
3分でこれを書いた方法はかなり印象的です:-P
xnor

6
このボスの質問が生まれるのをかなり待っていました。;-)
2014

Python 3.2でこれを実行すると、「TypeError:expected a object with buffer interface」と表示されます。
XNOR

@xnor編集、現在はPython 2。
ベクトル化

4

マーベラス 188

新しい言語を誇示するためのIlmari Karonenのアルゴリズムの恥知らずな盗難。

このスクリプトは、stdinの左に0x00、右に0x01の文字列を想定し、その後に0x0A(改行)が続きます。失敗した場合は「0」、成功した場合は「1」を出力します。

......@5@3FF
@0@1@2\\]]@5
010203@4=A@4
&0&0&0&0/\
MVMVMVMV..
@0@1@2@3..!!
:MV
}2}2}1}0}1}0}3
&0&1&0&1~~~~<A@P
{0{1{1{0&1&0=0&1
}0}1}2@P{2{2&030
=1=2=3&2FF}3..//
&2&2&231&2{3
\/\/\/&2!!..//

実行例:

# echo -e "\x0\x0\x0\x1\x0\x0\x1\x1\x0\x1\x0\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1" | marbelous.py ant-on-a-cube.mbl
1

1
言語の説明を読むまで、この答えがどれほどクレイジーかはわかりませんでした。それはゴルフ言語にとって本当にクールなコンセプトです!
xnor 14

@xnorそれはゴルフの分野で真剣な競争相手になることはまずありませんが、それでもやや楽しいです:)
スパー14

4

Python 2、57バイト

f=lambda l:reduce(lambda n,x:n%4*64+n/4*16**x%63,l,27)<28

オンラインでお試しください!

これは順列表現を使用します

0: abcd -> dabc
1: abcd -> dcab

ここで、左と右(0と1)は4要素の長さ4サイクルに対応します。示された順列を適用して入力を反復処理し、結果が初期値と等しいかどうかを確認します。

a,b,c,d4要素のリストから始めます0,1,2,3。それらを4を基数とする単一の基数に圧縮します。n=abcd初期値は基数4にn=27対応し0123ます。それぞれの順列を算術的にインスタンス化しますn

両方の結果が d、我々は行うことができますn%4抽出するためにd、その後、n%4*64右の位置に移動しますd___。他の数字はabcn/4ます。それらを下位3桁の値に挿入する必要があります。

方向についてはそのままx=0挿入abcし、についてはとしてx=1回転しますcab。以下のように回転を達成することができる*16%63とる、abcabc00しますcab。(%63に間違って行くだろうa==b==c==3ますが、これらの値は使用できません。)ただ行うこと%63は何もしないので、方向依存式*16**x%63は、必要に応じて、abcまたはcabを与えます。


Python 2、55バイト

f=lambda l:reduce(lambda n,x:n^(n*8%63|7*8**x),l,10)<11

オンラインでお試しください!


3

ハスケル、104 103 99 97 96/ 67 64の文字

右/左に相当するものは、データ型の方向であると感じます。

Direction = R | L

だから私は答えでそれらが利用可能であると仮定しました。
編集:実際にはブール値が短いコードにつながることを実現しました。Trueは左折を表し、Falseは右折を表します(ただし、技術的には、コードが反転しても同じように機能しますが、対称です)。

96文字:

m[p,l,r]b|b=[p%l,7-r-l,r]|0<1=[p%r,l,7-r-l]
p%x|odd$div p x=p-x|0<1=p+x
g l=foldl m[0..2]l<[0,2]

gは、方向のリストを指定すると、アリが元の場所に戻らなかったという天気を返す関数です。

位置の表現の説明: アリの位置は整数の3つのタプルとしてコード化されます。最初の整数は、アリが向かう頂点を表します。最初のビットは、頂点が上/下半分、2番目が左/右半分、3番目が後/前半分であるかどうかを表します。これは、頂点から隣接する頂点への移動が1ビットを反転することで行えるように行われます。

2番目の整数は、アリの頂点が去った場合に変化する量です。たとえば、アリが頂点3にあり、2番目の整数が4だった場合、左に曲がった後、頂点は7になります。1つの頂点を移動すると正確に1ビットが反転するため、常に2のべき乗になります。

3番目の整数は同じですが、正しく進むためのものです。これは最初の2つで計算できることは知っていますが、方法はわかりません。アイデアがあったら教えてください。

左に曲がるとき、3番目の整数は同じままであり、2番目は1 2と4の間の2番目の整数でも3番目でもないものになり、これはたまたま7と同じです- 2番目の整数-3番目の整数。

(前の段落で述べたように)次のポジションを計算するのは簡単だったので、ポジションを表すこの方法を選択しました。

機能の説明:

(%)関数は、現在の頂点とそれを変更する量を取り、変更する関数です。変更されるビットに到達し、それを反転します(非常に数値的な方法で)。

m関数は、アリの位置と方向を取得し、前述のメモを使用して新しい位置を返す関数です。

次に、m関数をfoldl(reducejavascript に似ていますが、もう少し表現力があります)を使用して結合し、この質問に対する答えである関数gを作成します。


Haskell、64文字

@alphaalphaの答えに触発され、haskellに移植されたバージョンは次のとおりです。

m[a,b,c,d]p|p=[b,c,d,a]|0<1=[b,d,a,c]
g l=foldl m[0..3]l<[0,1,3]



編集: 今lmari Karonenの答えのために私は信じられないほど愚かです。多分私は彼の答えをhaskellに移植します。 別の編集:彼の答えが間違っていたように愚かはない
編集:実際にタプルを使用することからOrdインスタンスとしてリストを使用するように切り替えられ、[ ... ]構文糖は短くなります


1
これは特にエレガントに見えます。[0,1,2,3]変数に割り当てるためにさらに多くの文字を保存し、式への入力と結果のチェックの両方として使用できますか?
xnor 14

@xnorあなたのコメントは私の心がゴルフを考え出すことを決めたので[0..3]...私はなぜ私が以前に気付かなかったのか分かりません。ありがとう。しかし今、あなたのトリックは機能しません。しかたがない。
誇りに思ってhaskeller 14


3

APL(Dyalog Unicode)、22バイト(AdámのSBCS

f←{x∊(-@3∘⌽⌽)/⍵,x←⊂⍳3}

オンラインでお試しください!

H.PWizは、手順を逆にしても違いはないことを示唆し、-2バイトになりました。

まあ、これは恥ずかしいです。GolfScriptよりもずっと短くすることを意図していたからです。少なくとも私はしようとしました。

この関数にはという名前が付けられf、テストケースで1は、左折(ブール値の真)と0右折(ブール値の偽)を表します。空のリストを表します。



3

Bash71 65バイト

f()(a=1234;for i;{ a=`tr 1-4 4$[$i?123:312]<<<$a`;};((a==1234));)

オンラインでお試しください!

以前の多くの回答と同様に、1234-> 4123および1234-> 4312によって生成されたキューブの回転グループの表現を使用します。算術展開で三項演算子を使用できるように、文字の代わりに数字を使用します。入力をスペースで区切られた0と1として期待し、終了コードを介して出力します。

@manatworkのコメントのおかげで6バイト節約されました!


1
パラメータリストのループについては、DennisBashのヒントを参照してください。
マナトワーク

3

brainfuck、119バイト、137バイト

立方体の回転グループが次と同型であるという事実を使用します S4。Brainfuckには名前付きまたはその他の機能がまったくないため、これはSTDINを介して入力を受け取り、STDOUTに出力する完全なプログラムです。(変数を主張する場合、プログラムが終了するセルの値が変数であると仮定します。)

キューブ、119バイト

++++>+++>++>+>,[+++[->+++<]<<<<[->>>>+<<<<]>[>]<+[[-]<[->+<]<<<[->>>+<<<]>[>]],]<[[<]>[->]<[>>]<]<[>>-<]-[----->+<]>--.

オンラインでお試しください!

++++>+++>++>+    Initialize tape as 4 3 2 1

>,[              For each input byte:

  +++[->+++<]       Add 3 and multiply by 3; if input is R, this will be 255

  <<<<[->>>>+<<<<]  Move first number to end (BCDA)

  >[>]<+[           If input wasn't R:

    [-]                Zero input cell (which is now negative 18)

    <[->+<]            Move previously moved number one slot further (BCD_A)

    <<<[->>>+<<<]      Move first number into vacated slot (CDBA)

  >[>]]

,]

<[[<]>[->]<[>>]<]     Determine whether tape is still 4 3 2 1

<[>>-<]               If not: subtract 1 from output cell

-[----->+<]>--.       Create "1" in output cell and output

十二面体、137バイト

+++++>++++>+++>++>+>,[+++[->+++<]<<<<<[>>>>>+[<]>-]>[>]<+[[-]<<[[->>+<<]<<]>[>>>>>>+[<]<-]>>[>]],]<[[<]>[->]<[>>]<]<[>>-<]-[----->+<]>--.

オンラインでお試しください!

2つのプログラムの唯一の違いは、セットアップと順列です。ここで使用されている左の順列はDCAEBです。


1

ゼリー、14バイト

3RðW;ṙN1¦ṚƊ/⁼⁸

オンラインでお試しください!

1 =左折、 0 =右折。私のDyalogソリューションに基づいています。

残念ながら、Jellyには名前付き関数がありません。暗黙的な入力を使用できず、変数にあると仮定する必要がある場合、この同じ長さのバージョンでは次のようになります。

3RµW;®ṙN1¦ṚƊ/⁼

入力がレジスタ(©/®)にあると想定しています。


0

Perl-120、214

ブール値の配列(リスト)を受け取ります。

キューブ(120):

sub e{$a=$b=0;for$c(@_){$_=(13,62,53,40,57,26,17,'04')[$b];$d=s/$a/($b-1)%8/e;($a,$b)=($b,substr($_,$c^$d,1))}return!$b}

十二面体(214):

sub e{$a=$b='00';for$c(@_){$_=('01041102090307040500061807160308091502101114121019131714151016081706131819051200'=~/\d{4}/g)[$b];$d=s/$a/sprintf'%02d',($b-1)%20/e;($a,$b)=($b,substr($_,($c^$d)*2,2));}return!($b+0)}

2
マジックナンバーエンコーディングとは何ですか?
xnor
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.