Cubix、94 83 82 79 63 56バイト
p>q'-?w.uh'e@U7.'hqi?oqB-!ul.-..$WWu_q<o'\;>....6t?.../!@
拡張:
p > q '
- ? w .
u h ' e
@ U 7 .
' h q i ? o q B - ! u l . - . .
$ W W u _ q < o ' \ ; > . . . .
6 t ? . . . / ! @ . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
ノート
- インタープリターは、プログラムの開始時に入力フィールドを無効にします。そのため、入力の無限ストリームは不可能です。このプログラムは文字ごとに入力を受け取るため、この制限がなければ適切に機能します。
- このプログラムはスタックをクリアせず、非常に早く混乱します。これが使用されるマシンは明らかに無限の入力ストリームを提供する可能性があるため、無限のメモリも持っていると仮定するのが妥当と思われます。
- すべてのゴルフの助けは大歓迎です。
オンラインで試す
ここでプログラムを試すことができます。
説明
一般的なアイデア
一般的な考え方は、文字を読み取ってから、さまざまな文字(最初h
、次にe
、次にl
など)でチェックすることです。逃したキャラクターを追跡するために、スタックの一番下に保持します。必要になったら、簡単に再びトップに戻すことができます。
読み取り/書き込みループ
読み書きループは単純に5 番目のライン。使用されないすべての文字は、no-ops(.
)に置き換えられます。
. . . .
. . . .
. . . .
@ . . .
' h q i ? o q B - ! u l . - . .
. . . . _ . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
これは、読み取りと(書き込みとチェック)の2つの部分に分割できます。最初の部分には、疑問符までの指示が含まれています。2番目の部分は、残りの行です。これはループするため、次のスタックで開始すると仮定します。[...]
@
'hqi?
_
Explanation
'h Push the character code of the h
Stack: [..., 104]
q Send it to the bottom
Stack: [104, ...]
i Read one character of the input (-1 for EOF)
Stack: [104, ..., input]
? Start of condition:
if (input < 0):
@ execute '@', ending the program
if (input = 0):
continue going right
if (input > 0):
_ turn to the right, reflect back ('_') and
turn right again, effectively not changing
the direction at all
2番目の部分(書き込みとチェック)は再び線形です。スタックはから始まります[next-char, ..., input]
。プログラムの後半で変更されるため、次の文字を抽象化しました。
oqB-!ul.- Explanation
o Output the character at the top of the stack
q Send the input to the bottom of the stack
Stack: [input, next-char, ...]
B Reverse the stack
Stack: [..., next-char, input]
- Push the difference of the top two characters, which
is 0 if both are equal, something else otherwise
Stack: [..., next-char, input, diff]
! if (diff = 0):
u make a u-turn to the right
else:
l. execute two no-ops
- push [input - next-char - input], which is disregarded
later, so it effectively is a no-op as well.
これで、このループの開始時にIPが再び開始され、チェックする次の文字がリセットされh
ます。
次の文字に一致
IPがuターンした場合(つまり、読み取って印刷した文字がの次の文字と一致した'hello'
場合)、入力がどの文字であったかを確認し、それに応じて次の文字をスタックの一番下にプッシュします。その後h
、スタックにプッシュせずに読み取り/書き込みループに戻る必要があるため、そこに到達する別の方法が必要です。
まず最初に:入力がどの文字であったかを判断します。スタックは次のようになります[..., prev-char, input, 0]
。
. . . .
- ? . .
u h ' e
. . . .
. . . . . . . . . ! u . . . . .
. . . . . . . . . \ ; . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
入力を比較するために、h
再び文字コードを使用します。最初は、これをどのように処理するのか実際にはわからなかったためh
であり、チェックする文字列の最初の文字でしたが、非常に便利でした。入力からhの文字コードを引くと、-3
入力がe
である0
か、入力がh
である4
か、入力がであるか、入力がl
である7
かが得られますo
。
この?
コマンドを使用すると、負の値を正の値とゼロから簡単に分離できるため便利です。そのため、IPが左に曲がる場合、差は負であったため、入力はe
であったため、次の文字はである必要がありl
ます。IPが直進し続ける場合、差は0
であったため、入力はh
であったため、次の文字はである必要がありe
ます。入力された場合l
やo
、IPを右折します。
前述の疑問符の前に実行されるすべての命令は次のとおりです。
;!e'h- Explanation
; Delete the top of the stack
Stack: [..., prev-char, input]
! if (input = 0):
e execute 'e' (no-op)
'h Push the character code of h
Stack: [..., prev-char, input, 104]
- Push the difference of the input and 104
Stack: [..., prev-char, input, 104, diff]
これで、IPは上記のように方向を変更します。さまざまな可能性を調べてみましょう。
入力 'e'
最初にinputを検討しますe
。これにより、IPはから上に移動します?
。違いは3であるためです。無関係な文字はすべてキューブから削除されています。
. > q '
. ? . .
. . . .
. . . .
. . q . . . . . . . . l . . . .
$ W W . . . . . . . . > . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
文字は次の順序で実行されます(一部の制御フロー文字を除きます)。
q'l$WWq
q Save the difference (-3) to the bottom of the stack so
we can tell whether the l on the bottom of the stack is
the first or the second l in hello
Stack: [-3, ...]
'l Push the character code of l to the stack
Stack: [-3, ..., 108]
$W no-op
W Sidestep into the loop
q Send the character code to the bottom
Stack: [108, -3, ...]
これで、IPは読み取り/書き込みループに再び到達しました。
入力 'h'
入力がの'h'
場合、差は0であるため、IPは方向を変更しません。ここに再びキューブがありますが、無関係な文字はすべて削除されています。このパスにはかなりの数のノーオペレーションが含まれているため、パスに渡されるノーオペレーションはすべてに置き換えられてい&
ます。IPは疑問符で始まります。
. . . .
. ? w .
. . ' e
. . . .
. . . . . . . . . ! . . . . . .
. . . u _ q < . . \ . . . . . .
. . ? & & & / . . & . . . . . .
. . & . . . . . . & . . . . . .
. . . .
& & & &
. . . .
. . . .
実行される命令は次のとおりです。
'e!\?q_
'e Push the character code of the e
Stack: [..., 101]
! if (101 = 0):
\ reflect away (effectively a no-op)
? if (101 > 0):
turn right (always happens)
q Move 101 to the bottom of the stack
Stack: [101, ...]
_ No-op
そして、読み取り/書き込みループに再び入るので、完了です。
その他の入力
他のすべての入力では正の差が生じるため、IPは疑問符で右に曲がります。我々はまだ分離する必要があるl
とo
私たちは次やるの何ということ、。
分離'l'
し、'o'
差は7 for o
と4 forでl
あり、入力がの場合はプログラムを終了する必要があることに注意してくださいo
。ここでは、無関係な部分がaに置き換えられ.
、IPが交差するno-opsがアンパサンドに置き換えられたキューブが再びあります。
. . q .
. ? w .
. h ' .
. U 7 .
. . . . . . . . . . . . . - . .
. . . . . . . . . . . . . & . .
. . . . . . / ! @ . . . . & . .
. . . . . . & . . . . . . & . .
. . & .
. . & .
. . & .
. . & .
h7'wq-!@
h no-op
7 Push 7 to the stack
Stack: [..., diff, 7]
'wq Push w to the stack and send it to
the bottom. We don't care about it,
so it's now part of the ellipsis.
Stack: [..., diff, 7]
-! if (diff = 7):
@ End the program
2つ'l'
の間を識別する
そのため、入力がであることはわかっていますが、l
どちらがかはわかりませんl
。最初の場合l
は、スタックの一番下に別のプッシュする必要がありますが、2番目の場合は、をプッシュする必要がありo
ます。-3
最初にプッシュする直前にスタックの一番下に保存したことを覚えていますl
か?これを使用して、2つのブランチを分離できます。
. . . .
. . . .
. . . .
. . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
6 t ? . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
スタックは次のように始まります [..., -3 or 140, ...]
Explanation
6t?
6t Take the 6th item from the top and move
it to the top (which is either -3 or 140)
? If that's positive, turn right, otherwise,
turn left
最初 'l'
これが最初の場合、'l'
別のプッシュをする必要があり'l'
ます。バイトを節約するために、最初のものと同じ文字を使用し'l'
ます。スタックをに単純化できます[...]
。キューブの関連部分を次に示します。何もしない操作はアンパサンドに置き換えられます。
p > q '
. . . .
. . . .
. . . .
' . q . . . . . . . . l . . . .
$ W W . . . . . . . . > & & & &
. . ? . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
次の指示が実行されます。
$'pq'lq
$' no-op
pq no-op
'l Push the character code of l
Stack: [..., 108]
q Send it to the bottom
Stack: [108, ...]
読み取り/書き込みループに入ろうとしているので、このブランチはこれで完了です。
第二 'l'
入力が第二だった場合'l'
で'hello'
、IPは、疑問符を右に回しました。もう一度、スタックをに簡略化し[...]
て、IPがから始まり、?
今回は南を指すようにします。
. . . .
. . . .
. . . .
. . . .
. . . . . . . . . . . . . . . .
. . . u _ q < o ' \ . . . . . .
. . ? . . . . . . & . . . . . .
. . & . . . . . . & . . . . . .
. . . .
& & & &
. . . .
. . . .
実行される命令は次のとおりです。
'oq_
'o Push the character code of 'o'
Stack: [..., 111]
q Move the top item to the bottom
Stack: [111, ...]
_ No-op
また、IPは読み取り/書き込みループに再び入ろうとしているので、このブランチについても同様です。