飛行機の有効なヘビ


23

Vi Hartのビデオの1つに触発された(潜在的なチャレンジアイデアに満ちた宝庫)

ヘビは同じ長さのセグメントで構成されており、各セグメント間の接続はまっすぐにすることも、90°回転させることもできます。
そのような蛇(最初の方向に依存する回転まで)をエンコードするには、スリッシャーを書き留め、ターンの方向(直線/左/右)を取ります。これは、左上から右を指します

-+    +--+    SR    RSSR
 |  +-+  |     S  RSL  S
 +--+  --+     LSSL  SSR

スリザーで表されます SRSLSSLRLRSSRSRSS

そしてもちろん、平面のヘビは(のようにSSSSLLLSS)それ自体と交差することはできません。

あなたの仕事は、スリザーが有効かどうかを判断することです(少なくとも1つの自己交差が生じる)

入力 有効なスリッターである場合は「何か真実」、そうでない場合は「偽」で出力
される文字から作成された文字列。SLR2 < length < 10000

テストケース

__Valid__
SSLSLSRSRSSRSSSLLSSSRRLRSLRLLSSS
SRRLSLLRRLLSLRRSRLLRSRRLLRRSRLLSSLLRSRRLLRRSRLLRSRRLSLLRRLLSLRR (A hilbert curve)
RLLRSRRLSLLRRLLSLRRSRLLRSRRLLRRSRLLSSLLRSRRLLRRSRLLRSRRLSLLRRLLSLRRSRLLRSRRLLRRSRLLSSLLRSRRLLRR
SRRSRSRSSRSSRSSSRSSSRSSSSRSSSSRSSSSSRSSSSSRSSSSSSRSSSSSSRSSSSSS (Spiral)
SSSSSSSSSSLSSSSSSSLSSSSSSSSLSSSSSLSSSSSSLSSSLLRRLLRRLLSLSSSRRSSSSRSSSRSSSSSSRSSSSSRSSSSSSSSRSSSSSSSRSSSSSSSSS (bigger, squigglier spiral)
LRSLLRLSRSLLSRLSLRSLSSSLRRSSLSRRLRSRLRLSLRLLRLRSSLSLRLRSRSSSSSLSRRLSLSSSRRLRLRLRLRRLLSSLSSSRRLRLRLRLRLSLSSSSSSSSSSSSSRLRLLRLRLRLRLRLRLRLSLSSSLSLSLL

__Invalid__
SRRLSLLRRLLSLRRSRLLRSRRLLRRSRLLLLRSRRLLRRSRLLRSRRLSLLRRLLSLRR
SRRLSLLRRLLSLRRSRLLRSRRLLSRSSSRSSSSSSSRSRSSSSSSSRRLLRRSRLLRSRRLSLLRRLLSLRR
SRRSRSRSSRSSRSSSRSSSRSSSSSSSSSSRSSSSRSSSSSRSSSSSRSSSSSSRSSSSSSRSSSSSS
SSSSSSSSSSLSSSSSSSLSSSSSSSSLSSSSSLSSSSSSLSSSLLRRLRLRRLLSLSSSRRSSSSRSSSRSSSSSSRSSSSSRSSSSSSSSRSSSSSSSRSSSSSSSSS
LRSLLRLSRSLLSRLSLRSLSSSLRRSSLSRRLRSRLRLSLRLLRLRSSLSLRLRSRSSSSSLSRRLSLSSSRRLRLRLRLRRLLSSLSSSRRLRLRLRLRLSLSSSSSSSSSSSSSRLRLLRLRLRLRLRLRLRLSLSSSLSLSLLSLRLSLRSLRSLRSLSLSLRSRLSLRSLRLSRSLLLRLRLRRRRSLSLSSLLSLSLSLSSLLSLSLLRLRSLLRSRLSLSSLLLLSSSSSSSSSSSSSSSSSSSSRLRLLRRLRLRLLRLRLRLRLRLSSSSLSLRLLRLSLSSLSLSLSLSLRLLRLSLLLSRSSSSSSSSSSSSSSSRLRLRLLRLRLSLSRSRSSSLSRLRLRLRSLSLSLSRLLSRLSLSLSLSLSSLSLSLLSLSRLLRLRLRLRLRLRLRLRLRLRLSLSRLRLSLLRRLSLLSLSLSLSLSLLSLSLSLRLRLRLRLRLRLRLRLRLRRLRSLSLSLSLSLSLSLSSLSSSSSLSLSSSLSLSLSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

ここでスリザー描くことができます(RとLは反転しますが、有効性には影響しません)


入力はプログラムで行う必要がありますか、それともファイルから読み取ることができますか?
MIライト

1
SRRRをTrueまたはFalseにする必要がありますか?接続しますが、交差しません。
orlp

蛇に触れるとNSFWに挑戦しますか?
ユアン

3
SRRRセグメントごとに1つの正方形でグラフ用紙に描画すると、重複するため無効になりますが、RRR重複することなくちょうど2x2の正方形を占有します(古典的なゲームのように)
-DenDenDo

似ているが、重複していない(異なる目的と異なる構築規則のため)。
trichoplax

回答:


20

Pyth、22 20バイト

ql{m+=Z*=T^.j)hCdzlz

自分で試してみるか、テストスイートを実行してください

SRLのASCII値、それぞれ83、76、82に注意してください。次の事実を悪用します。

i 83 + 1 = 1
i 76 + 1 = i
i 82 + 1 = -i

ここから、現在の位置と現在の方向の変数を保持します。すべての文字について、現在の方向に上記の複素数を乗算し、それを現在の位置に追加します。

最後に、訪問した位置がすべて一意であるかどうかを確認します。


SRRR = true ????
ユアン

@Ewanよく調べてみると、それが間違っているべきかどうかわかりません。頭と尾はつながっていますが、交差していません。
orlp

SRRRSはどうですか?
ユアン

@Ewan同じ話-接続はあるが交差点はない。質問は、これらのために何を返すべきか明確ではありません。
orlp

1
どのようにSRRRを描きますか?
ユアン

6

CJam、30バイト

q{iF%U+:U[XWe4W1e4]=T+:T}%__&=

すぐに続く説明。

こちらからオンラインで試す、スイート全体を実行してください


くそー、それは速かった。アルゴリズムを自分で解決することすらまだ考えていませんでした。
-DenDenDo

SRRRS = true ???
ユアン

@Ewanうーん、最初は0がいっぱいになってカウントされると仮定していますか?
オプティマイザー

1
動きが空間のブロックを占めるヘビのゲームのように解釈していると思います。そしてあなた方の何人かはそれをゼロ幅の線として解釈しています
ユアン

@Ewan私の質問は少し異なります。たとえばS、単一の動きがある場合、ヘビが既に(0,0)と(1,0)の両方を占有しているということですか?
オプティマイザー

6

JavaScript(ES6)、84 89

Firefoxでスニペットを実行してテストします。

いくつかのメモ:

  • ヘビはf配列内を移動します。未訪問のセルには値がありますundefined。最初の訪問で、チルダ演算子はそれを-1に変更します。最終的に、2回目のアクセスで値が0に変更されますが、これは偽であり、everyループは終了してfalseを返します。
  • JSでは、非標準的なインデックス(数値でも負でもない)を持つ配列要素は何らかの方法で「隠されています」が、実際には存在します。ここでは、問題なく負のインデックスを使用します。

F=s=>[...s].every(c=>f[p+=[1,1e5,-1,-1e5][d=d+{R:1,L:3,S:0}[c]&3]]=~f[p],d=p=0,f=[])

//TEST
$('#S').on('keyup mouseup change', Draw);

function Draw(){
  var s = S.value.toUpperCase();
  if (!s) {
    C.width = C.height = 0;
    return
  }
  C.width = 600;
  C.height = 400;
  
  var ctx = C.getContext("2d");  
  var px, py, int=0;
  
  ctx.strokeStyle = '#008';
  ctx.lineWidth = 2;
  ctx.translate(300,200);
  ctx.beginPath();
  ctx.moveTo(0,0);
  
  [...s].forEach(c=>{
    (f[p+=[1,1e4,-1,-1e4][d=d+{R:1,L:3,S:0}[c]&3]]=~f[p])
    ? 1 
    : (++int)
    if (int==1) ctx.stroke(), ctx.strokeStyle = '#800', ctx.beginPath(), ctx.moveTo(10*px,10*py);
    
    py = (p / 1e4 | 0) - 5e3;
    px = (p % 1e4) -5e3
    ctx.lineTo(10*px, 10*py);
  }, d=0,p=50005000,f=[]);
  ctx.stroke();
  
}

valid=["SSLSLSRSRSSRSSSLLSSSRRLRSLRLLSSS",
"SRRLSLLRRLLSLRRSRLLRSRRLLRRSRLLSSLLRSRRLLRRSRLLRSRRLSLLRRLLSLRR",
"RLLRSRRLSLLRRLLSLRRSRLLRSRRLLRRSRLLSSLLRSRRLLRRSRLLRSRRLSLLRRLLSLRRSRLLRSRRLLRRSRLLSSLLRSRRLLRR",
"SRRSRSRSSRSSRSSSRSSSRSSSSRSSSSRSSSSSRSSSSSRSSSSSSRSSSSSSRSSSSSS",
"SSSSSSSSSSLSSSSSSSLSSSSSSSSLSSSSSLSSSSSSLSSSLLRRLLRRLLSLSSSRRSSSSRSSSRSSSSSSRSSSSSRSSSSSSSSRSSSSSSSRSSSSSSSSS",
"LRSLLRLSRSLLSRLSLRSLSSSLRRSSLSRRLRSRLRLSLRLLRLRSSLSLRLRSRSSSSSLSRRLSLSSSRRLRLRLRLRRLLSSLSSSRRLRLRLRLRLSLSSSSSSSSSSSSSRLRLLRLRLRLRLRLRLRLSLSSSLSLSLL"];
invalid=["SRRLSLLRRLLSLRRSRLLRSRRLLRRSRLLLLRSRRLLRRSRLLRSRRLSLLRRLLSLRR",
"SRRLSLLRRLLSLRRSRLLRSRRLLSRSSSRSSSSSSSRSRSSSSSSSRRLLRRSRLLRSRRLSLLRRLLSLRR",
"SRRSRSRSSRSSRSSSRSSSRSSSSSSSSSSRSSSSRSSSSSRSSSSSRSSSSSSRSSSSSSRSSSSSS",
"SSSSSSSSSSLSSSSSSSLSSSSSSSSLSSSSSLSSSSSSLSSSLLRRLRLRRLLSLSSSRRSSSSRSSSRSSSSSSRSSSSSRSSSSSSSSRSSSSSSSRSSSSSSSSS",
"LRSLLRLSRSLLSRLSLRSLSSSLRRSSLSRRLRSRLRLSLRLLRLRSSLSLRLRSRSSSSSLSRRLSLSSSRRLRLRLRLRRLLSSLSSSRRLRLRLRLRLSLSSSSSSSSSSSSSRLRLLRLRLRLRLRLRLRLSLSSSLSLSLLSLRLSLRSLRSLRSLSLSLRSRLSLRSLRLSRSLLLRLRLRRRRSLSLSSLLSLSLSLSSLLSLSLLRLRSLLRSRLSLSSLLLLSSSSSSSSSSSSSSSSSSSSRLRLLRRLRLRLLRLRLRLRLRLSSSSLSLRLLRLSLSSLSLSLSLSLRLLRLSLLLSRSSSSSSSSSSSSSSSRLRLRLLRLRLSLSRSRSSSLSRLRLRLRSLSLSLSRLLSRLSLSLSLSLSSLSLSLLSLSRLLRLRLRLRLRLRLRLRLRLRLSLSRLRLSLLRRLSLLSLSLSLSLSLLSLSLSLRLRLRLRLRLRLRLRLRLRRLRSLSLSLSLSLSLSLSSLSSSSSLSLSSSLSLSLSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS"];

V.innerHTML=valid.map(s=>F(s)+' '+s).join('\n')
I.innerHTML=invalid.map(s=>F(s)+' '+s).join('\n')
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Type to check and draw <input id=S>
(better full page)<br>
<canvas id=C width=1 height=1 ></canvas><br>
Valid<pre id=V></pre>
Invalid<pre id=I></pre>


6

TI-BASIC、49 56 53 51バイト

abs(e^(i)-cumSum(i^cumSum(seq(inString("SL",sub(Ans,X,1))-1,X,1,length(Ans→X
SortA(∟X
min(ΔList(∟X

orlpの方法と同様に、これは、原点から開始して、ヘビが訪れた複雑な平面内のすべてのポイントのリストを作成します。リストに重複する要素がない場合、コードは正の値を返します。999を超える要素の文字列では、計算機が十分に長いリストを生成できず、エラーになることに注意してください。

編集:複雑な平面上の2つの格子点がe ^ iから同じ距離にあることができないため、さを犠牲にして2バイトを保存しました。


5

TI-BASIC、60 58バイト

編集:以下をすべて無視します:thomas-kwaによる実用的なti-basicソリューションがここにあります。賛成してください!

ある[(-)]キー、およびAnsです[2ND]->[(-)]。ヘビの指示を引用符([ALPHA]->[+])で囲み、その後にコロン、プログラム名を続けて実行します。たとえば、プログラムに「SNAKE」という名前を付けた場合、OPでテストケースをとして実行します"SRSLSSLRLRSSRSRSS":prgmSNAKE

seq(inString("SRL",sub("0"+Ans,I,1)),I,1,length(Ans
Disp 0<sum(⁻1+2seq(Ans(I)≠(Ans(I-1),I,2,dim(Ans

編集:で失敗しSRRLSLLRRRSます。61バイトの改訂版を使用していますが、最初の無効なテストケースで失敗します。

seq(inString("SRL",sub("0"+Ans,I,1)),I,1,length(Ans
cumSum(⁻1+2seq(Ans(I)≠(Ans(I-1),I,2,dim(Ans
Disp 0<Ans(dim(Ans

明日修正しようと思います。


更新:したがって、問題は実際には私のアルゴリズムに欠陥があるということです。seq((同じことを達成するために)ではなくFor(ループを使用した場合)(実際には上記の両方のアルゴリズム)は次のように記述できます。

  1. カウンター変数を1に初期化します。
  2. 文字列を読み取ります。シンボルが変更された場合、カウンター変数をインクリメントします。シンボルが繰り返される場合は、デクリメントします。
  3. カウンター変数が0より大きい場合、1(有効)を表示します。それ以外の場合は、0(無効)を表示します。

ただし、これはのような無効なスリザーでは失敗しますSRLRLRLRLRRRSS。ここで、より良いアルゴリズムを考え出すか、別の答えを盗もうとします。


これはseq(実際には単一のコマンドで置き換えることができると90%確信していますが、今のところ、これは手に入れることができる限り小さいものです。あなたが使用して8xpにこれを構築する場合Sourcecoderを実際にそれを入力すると対照的に、ノートに置き換えるべき!=⁻1+ビットに置き換えてください~1+


1

ルビー87 89

F=->s{d=[1,w=1e4,-1,-w]
v=[w]+s.chars.map{|c|w+=d.rotate!(c<?R?-1:c>?R?0:1)[0]}
v==v&v}

オンラインテスト:http : //ideone.com/pepeW2

ゴルフされていないバージョン:

F = -> input {
  # Coordinates are expressed using one number,
  # that is computed using the formula `y + x*max_x`.
  # Assume max horizontal field width (max_x) to be 10000,
  # since that's the max length of the input.
  position = max_x = 1e4

  # These are possible directions to move to (coordinate deltas).
  # The current direction is always the first in the array.
  directions = [1,max_x,-1,-max_x]

  visited = [position]

  visited += input.chars.map{|c|
    # adjust current direction...
    directions.rotate! case c
    when ?L
      -1
    when ?R
      1
    when ?S
      0
    end

    # ...and move there
    position += directions[0]
  }

  # Return `true` if `visited` only contains distinct elements, `false` otherwise
  visited == visited & visited
}

0

Golfscript 48 49 50

[10.4?:z-10z~)]z*z@{'R L S'?@>(@+.`n}%n/@;\;..&=

文字列がスタック上に存在することを予期し、0またはを返します1

有効ヘビと無効なヘビのテストでオンラインで試すことができます

これは基本的に同じ考えです 私のRubyの回答です。AFAIK Golfscriptにはarary rotate機能がないため、方向配列だけが異なって処理されます。この場合、十分に大きな方向配列を作成します。10000回乗算し、現在のコマンド(S、R、またはL)に応じて、開始0、1、または3要素からトリミングします。移動する現在の「方向」は、常に配列の最初の項目です。

ここにコメントがあります:

# Build the direction array and set current position
[1 10000:z-1z~)]z*z

@{
  # For each character in the input:

  # set current direction by cutting 0, 1 or 3 elements 
  # from the beginning of the directions array
  'SR L'?
  @>

  # move to current direction
  .0=@+.

  # format as number and addd newline
  `n
}%

# split by newlines
n/

# cleanup
@;\;

# return 1 if array contains distinct elements, 0 otherwise
..&=

編集:

「directions」配列の使用方法を変更して、1文字を保存しました。

編集:

?(power)構文を使用するために、1ではなく10の増分を移動して1文字を節約しました。

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