<
,,}:?
.
;(" {(={}{".
,",;=};} }) "{@
入力のN
後には、数字以外の文字で区切られた文字列が続きます。
オンラインでお試しください!
これはSp3000とのコラボレーションで書かれました(つまり、アルゴリズムを理解するのに悩まされなかったので、彼はそれに取り組み始め、118バイトのソリューションを思いつきましたが、それをゴルフに悩ませることができなかったので、ゴルフをしました。 ..チームワークに賛成)。
説明
Spの通常の入門書(通常どおりわずかに変更):
- Labyrinthは、メインと補助の2つのスタックを持つスタックベースの2D言語です。ほとんどすべてがメインスタックで発生しますが、値を他の値にシフトすることができます。たとえば、値を逆にしたり、後で使用するために保存したりできます。
- スタックは底なしでゼロで埋められているため、空のスタックからポップしてもエラーにはなりません。
- 実行は最初の有効な文字(ここでは左上)から始まります。命令ポインタ(IP)が取ることができる2つ以上のパスがある各ジャンクションで、スタックの最上部がチェックされ、次に進むべき場所が決定されます。負は左に、ゼロは前進、正は右に曲がります。これはされたが意味します、曲がりくねった通路を巻きのようなコードを見て作るために、これらの条件はすべての細胞で確認されている「ルーム」を作るからあなたを止めるものは何もありません。これらは非常に予測不可能な動作をもたらす可能性がありますが、ゴルフには最適です。
- ソースコード(したがって迷路のレイアウト)は
<>^v
、行または列またはグリッドを循環的にシフトすることを使用して、実行時に変更できます。
"
ノーオペレーションです。
さあ。
コードはから始まります<
。これは、長い線形コードから始めるときに何度か使ったゴルフのトリックです。最初の行を循環的に左にシフトし、その上にIPがあります。そのため、ソースは次のようになります。
<
,,}:?
.
;(" {(={}{".
,",;=};} }) "{@
しかし、IPはどこにも移動できないため、<
再び実行されます。これは、次の状態になるまで続きます。
<
,,}:?
.
;(" {(={}{".
,",;=};} }) "{@
この時点で、IPはセルを離れ、から始まる2行目の実行を開始でき?
ます。線形コードは以下のとおりです。
? # Read the first integer on STDIN, i.e. N.
:} # Duplicate it and move one copy over to the auxiliary stack.
, # Read the separator character.
,. # Read the first character of the input string and directly print it.
IPは、この2つの2x2時計回りのループである実際に2つの緊密に圧縮された(重複する)この3x2の部屋に入ります。最初のループはN-1
、STDINから文字を読み取り、破棄します。
; # Discard the top of the stack. On the first iteration, this is the
# separator we've already read. On subsequent iterations this will be
# one of the N-1 characters from the input string.
( # Decrement N. If this hits zero, we leave the loop, otherwise we continue.
, # Read the next character from STDIN to be discarded.
次に、入力文字列の残りを読み取る2番目のループに入ります。EOFを検出できるの,
は-1
、その場合に戻るため、IPが左に曲がるからです。
, # Read a character. Exit the loop if EOF.
( # Decrement it.
この減少は実際には有用ではありませんが、後で無料で元に戻すことができ、ここでは2つのループをオーバーラップできます。
我々が取る場合5 ABCDEFGHIJKLMNOP
の例として、入力を、このようなスタックルックス:
Main [ ... 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' -1 | 5 ... ] Auxiliary
これらは実際に入力文字に対応しているFGHIJKLMNOP
ので(デクリメントしたため)、実際にはそれらの最初のN-1
文字を印刷したくない(文字のみを破棄したがスキップしたいN
)ことに注意してください。
次のループに向けてスタックを準備する短い線形ビットがあります。
; # Discard the -1.
= # Swap the tops of the stacks, i.e. N with the last character.
# By putting the last character on the auxiliary stack, we ensure that
# it doesn't get discarded in the next loop.
} # Move N over to the auxiliary stack as well.
スタックは次のようになります。
Main [ ... 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' | 5 'O' ... ] Auxiliary
別の2x2時計回りループに入ります。これN
により、メインスタックから先頭の文字が破棄されます。
; # Discard the top of the main stack.
{ # Pull N over from the auxiliary stack.
( # Decrement it. It it's 0 we leave the loop.
} # Push N back to the auxiliary stack.
ループを終了すると、=
それと0
入力文字列の最後の文字が再び交換されます。スタックは次のようになります。
Main [ ... 'E' 'F' 'G' 'H' 'I' 'O' | ... ] Auxiliary
メインスタックの内容(一番下の要素と1ずつ増加するものを除く)の内容を左から印刷します。つまり、補助スタックに渡す必要があります。それが次の2x2(時計回り)ループの動作です:
{ # Pull an element over from the auxiliary stack. This is necessary so we
# have a 0 on top of the stack when entering the loop, to prevent the IP
# from turning right immediately.
} # Move the top of the main stack back to the auxiliary stack. If this was the
# bottom of the stack, exit the loop.
) # Increment the current character.
} # Move it over to the auxiliary stack.
今すぐスタック:
Main [ ... | 'F' 'G' 'H' 'I' 'J' 'P] ... ] Auxiliary
それらのうちの最初のもの(印刷したくないもの)をメインスタックに戻します{
。そして、最後の2x2(反時計回り)ループに入り、残りを出力します:
{ # Pull another character over from the auxiliary stack. Exit the loop
# if that's the zero at the bottom of the stack.
. # Print the character.
最後に、でプログラムを終了し@
ます。
'
カウント文字のませんか?例:''123321
?