いくつかのドミノを倒す!


22

インスピレーションを与えてくれたこの質問に感謝します

この挑戦で、私たちはのストリングとしてドミノのラインを表すでしょう|/そして\。入力としてドミノの文字列が与えられ、落ち着いたときにどのように見えるかを決定する必要があります。ドミノが倒れる方法のルールは次のとおりです

  • |倒れたドミノの左にある立っているドミノは、\同様に左の倒れたドミノになります。

  • |倒れたドミノの右側にある立っているドミノも、/同様に倒れた右のドミノになります。

  • 倒れたドミノが左倒れ\/ドミノと右倒れたドミノの間にある場合、立ったままになります。

これらの規則は、配置が変更されなくなるまで繰り返し適用されます。

単一の入力がその結論に到達する方法の例を次に示します

|||||||\/|||||||\||\|||/||||||\|||||

||||||\\//|||||\\|\\|||//||||\\|||||
|||||\\\///|||\\\\\\|||///||\\\|||||
||||\\\\////|\\\\\\\|||////\\\\|||||
|||\\\\\////|\\\\\\\|||////\\\\|||||
||\\\\\\////|\\\\\\\|||////\\\\|||||
|\\\\\\\////|\\\\\\\|||////\\\\|||||

\\\\\\\\////|\\\\\\\|||////\\\\|||||

あなたの仕事は、入力の最終結果を見つけて出力するコードを書くことです。入力は常に有効で、少なくとも2文字が含まれていると想定できます。

これはため、回答はバイト単位で記録され、バイト数は少ない方が良いでしょう。

テストケース

|||/||||  -> |||/////
|||\||||  -> \\\\||||
|/||||\|  -> |///\\\|
||/|||\|  -> ||//|\\|
||\|||/|  -> \\\|||//

6
バックスラッシュエスケープアホイ!(他のシンボルを使用できますか?)
アーナウド

1
@Arnauldいいえ、スラッシュを使用する必要があります。
小麦ウィザード

1
私は…何を逃れ、何を逃がさないかを理解することはできません。
完全に人間の

入力は空の文字列または単一の文字になりますか?
ドアノブ

3
`///////// | \のようなものが安定していると考えられるのは、それ以上に気になります。
ムースボーイ

回答:


13

網膜、32バイト

+`(/.\\)|(/)\||\|(\\)
$1$2$2$3$3

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

説明

+それは、文字列を変更するには失敗するまでループ内での交換を実行するために、網膜に指示します。各置換は、落下するドミノの1ステップを計算します。交換自体は実際には3つの交換になりますが、これにより確実に同時に交換されます。

(/.\\)...
$1

これだけの試合/|\(だけでなく、/\\そして/\\、しかし、それらは関係ありません)と変わらず、それを再挿入。これの目的は|、両側の倒れたドミノをスキップすることです。これは、他の2つのケースで個別のルックアラウンドを使用してこれらのケースを除外するよりも短いためです。

...(/)\|...
$2$2

これは一致し/|、に変わり//ます。

...\|(\\)
$3$3

これは一致し|\、に変わり\\ます。


私はそれが来るのを見なかったと言うことはできません。Retinaは確かにこの仕事に適したツールです。
小麦ウィザード

@WheatWizard解決するのは簡単ですが、おそらくすべてのエスケープとそれ$1$2$2$3$3がゴルフ言語を打ち負かすにはあまりにも冗長です。
マーティンエンダー


4

V、23バイト

òÓ¯À<!|¨Ü©ü¨¯©|ÜÀ!/±±²²

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

実際、これは網膜の答えに非常によく似ていますが、見た目がいだけです。正規表現圧縮を使用します。

Hexdump:

00000000: f2d3 afc0 3c21 7ca8 dca9 fca8 afa9 7cdc  ....<!|.......|.
00000010: c021 2fb1 b1b2 b2                        .!/....

説明:

ò文字列が変更されなくなるまで実行するようVに指示します。残りは圧縮された正規表現です。vimに相当するものに変換しましょう...

:s/\v\/@<!\|(\\)|(\/)\|\\@!/\1\1\2\2/g

:s/                                     " Substitute...
   \v                                   " Turn on magic (use less escaping)
          \|                            " A bar
            (\\)                        " Followed by a captured backslash
       @<!                              " That is not preceded by
     \/                                 " A forward slash
                |                       " OR...
                 (\/)                   " A captured forward slash
                     \|                 " Followed by a bar
                       \\@!             " That is not followed by a backslash
                           /            " Replace this with
                            \1\1        " Pattern 1 twice (will be empty if we matched the second path)
                                \2\2    " Pattern 2 twice (will be empty if we matched the first path)
                                    /g  " Replace every match on this line

4

SNOBOL4(CSNOBOL4)117 115 112 111バイト

	D =INPUT
S	D '/|\' ='_'	:S(S)
	E =D
	D '/|' ='//'
	D '|\' ='\\'
	D E	:F(S)
R	D '_' ='/|\'	:S(R)
	OUTPUT =D
END

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

功績ロッドのPythonの答えの変更ではなく、テストを参照するには第二の可変と停止状態のためのアイデアD '/|' | '|\'

	D =INPUT		;* read input
S	D '/|\' ='_'	:S(S)	;* replace '/|\' with '_', recursively
	E =D			;* set E to D, this is the while loop
	D '/|' ='//'		;* topple right
	D '|\' ='\\'		;* topple left
	D E	:F(S)		;* if D doesn't match E, goto S
R	D '_' ='/|\'	:S(R)	;* replace '_' with '/|\' (inverse of statement S)
	OUTPUT =D		;* output
END

3

Haskell114 107バイト

until=<<((==)=<<)$g
g s=t<$>zip3('|':s)s(tail s++"|")
t(l,'|',r)|l<'0',r/='\\'=l|r=='\\',l>'/'=r
t(_,e,_)=e

オンラインでお試しください!最初の行は、匿名関数を定義します。

説明:

  • until=<<((==)=<<)$g結果が変化しなくなるまで入力文字列に関数を適用する不動点関数です(説明はこちらを参照)g
  • zip3('|':s)s(tail s++"|")各ドミノ、つまり文字列の文字ごとにs、前と後のドミノ、|エッジのパディングを含むトリプルを作成します。例えば/\|なり[(|,/,\),(/,\,|),(\,|,|)](エスケープ無視します)。
  • 次に、t各トリプルに関数が適用され、トリプルの中央部分の新しい位置が計算されます。


2

プロローグ(SWI)、132バイト

+[]-->[].
+[47,124,92|T]-->"/|\\",+T.
+[47,47|T]-->"/|",+T.
+[92,92|T]-->"|\\",+T.
+[X|T]-->[X],+T.
X+Y:- +(N,X,[]),!,(X=N,Y=N;N+Y).

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

このプログラムは+/2、2番目の引数が最初の引数の確定バージョンである場合にtrueになる述部を定義します。両方の引数は文字コードのリストです。

説明

このソリューションでは、DCGを使用して次のステップが何であるかを把握し、次のステップが現在のステップと同じになるまで次のステップを繰り返し計算します。

DCG

+[]-->[].
+[47,124,92|T]-->"/|\\",+T.
+[47,47|T]-->"/|",+T.
+[92,92|T]-->"|\\",+T.
+[X|T]-->[X],+T.

これらの5行のコードは、+ドミノの転倒の単一ステップを計算するためにプログラムで使用されるDCG(確定句文法)ルールを定義します。PrologのDCGは、右側が文字列に一致するルールの最初のケースを見つけ、そのプロセスを通して左側のルールの引数を決定することで機能します。ケースが一致しなかった場合、バックトラックして後のケースを試行します。

+[]-->[].

この行は、+ルールの基本ケースを表します。現在、ドミノが存在しない場合、次のステップではドミノは存在しないと単純に述べています。

+[47,124,92|T]-->"/|\\",+T.

このプログラムは、文字コードのリストを独占的に扱っているので、それは注意することが重要であることのための文字コード/\および|47、92、および124はそれぞれ。この+ルールの場合は、/|\文字列を処理します。

+[47,47|T]-->"/|",+T.

このケースは、右のドミノを倒す右落下ドミノを処理します。取り扱いのケースの後に来るので/|\、その可能性のために使用されません。

+[92,92|T]-->"|\\",+T.

左下がりのドミノがその左のドミノを倒すためのケースを処理します。

+[X|T]-->[X],+T.

これはワイルドカードの場合です。上記の説明以外に変更はないため、入力文字列にテキストが残っている限り、上記のいずれにも一致しない限り、出力にコピーされます。

述語

X+Y:- +(N,X,[]),!,(X=N,Y=N;N+Y).

メインの述部は2つの引数を取ります。最初の引数は初期のドミノのセットアップ、2番目の引数は解決済みのドミノです。これはPrologであるため、2番目は未定であり、プログラムはそれを計算します。述語自体は非常に単純+(N,X,[])で、DCGを呼び出して、それを格納するドミノの次のステップを計算しNます。(X=N,Y=N;N+Y)チェックドミノの次のステップは、現在と同じであり、それがある場合には、設定した場合Yドミノが定住している必要がありますので、それまでとそうでない場合には、ドミノの次のステップと同じ述語を呼び出し、再帰Nの代わりにX



1

、166バイト

\|/,cm_/o>AvI[IIcP/+PP|m_/m*/Sl*Im1/11:~-_I|'|?_1-_P|?_1`I-III_|+II|'I.C:1-_I|?_C'|-_P|?_C_|'I-_I|`I?_!'I.C:!'|'|-III+II|'I:C_|-PPP+PPI'I?I~_I-PPP+PP|-**1?*~Sl*Iw*I*>

入力をコマンドライン引数として受け取り、STDOUTに出力します。これは、コミット86494f6以降でのみ機能します。そのコミットのバグ修正のためです。

美学に包まれた:

\|/,cm_/o>AvI[IIcP/+PP|m_/m*/Sl*Im1/11:~-_I|'|?_1-_P|?_1`I
-III_|+II|'I.C:1-_I|?_C'|-_P|?_C_|'I-_I|`I?_!'I.C:!'|'|-III
+II|'I:C_|-PPP+PPI'I?I~_I-PPP+PP|-**1?*~Sl*Iw*I*>

ungolfed /コメント:

\|/,cm_/o>              ( setup )

AvI[II                  ( store input into I )
cP/+PP|m_/              ( store 92, ascii for \, into P, meaning prev char )
m*/Sl*Im1/11            ( store length of input into counter variable * )

( main loop: )
:~

    -_I|'|?_1           ( branch to 1 if the character is not \ )
    -_P|?_1             ( also branch to 1 if the previous character wasn't | )
    `I-III_|+II|'I      ( we have a sequence |\ so prev needs to be toppled )
    .C                  ( jump to C, the "continue" label at end of loop )

    :1
    -_I|?_C             ( branch to C if the character is not | )
    '|-_P|?_C           ( also branch to C if the previous character wasn't / )
    _|'I-_I|`I?_!       ( branch to ! if the next character isn't \ )
    'I.C:!              ( otherwise, skip the next \ and branch to continue )
    '|'|-III+II|'I      ( if all conditions hold we have /|| or /|/ so topple )

    :C
    _|                  ( reset pointer to source )
    -PPP+PPI            ( update prev variable )
    'I                  ( step through data )

?I~

_I-PPP+PP|-**1          ( reset input/prev and decrement counter )
?*~                     ( repeat main loop as many times as there are chars )

Sl*Iw*I*>               ( output final string to stdout )

ここには、いくつかの余分なバイトを削るいくつかの微妙なトリックがあります。

  • 変数の命名| および/、ASCII値は、コードの後半でイントロスペクションを介してアクセスされます

  • '|設定するために、第2行に代わりの存在と呼ばれるメインループの最初の行に| メインループの2番目のセクションで使用するポインター


1

Perl 5、52 + 1(-p)= 53バイト

mikのおかげで-6バイト

おそらくPerlにとって最良の方法ではありませんが、それは私が思いつくものです。

0while(s/(?<!\/)\|(?=(\\))|(?<=(\/))\|(?!\\)/$1$2/g)

説明

while(
  s/
    (?<!\/)\|(?=(//)) # If there's a | that precedes a \ but doesn't follow a /, capture /
      | # Or
    (?<=(\/))\|(?!//)/ # If there's a | that follows a / doesn't precede a \, capture /
  /$1$2/ # Replace all | with capture group 1 or 2, as one of the two will always be empty
  g # Repeat as much as possible for this string
)

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


-p代わりの-aために必要な排除print;whileダミー式のサフィックスとして使用すると(例0
mik

@mik、ありがとう、私はそれらのトリックを知りませんでした。また、いくつかのバイトを節約するために、正規表現を他の何かで区切ることができることも理解しています。後でそれに到達するかもしれません。
ジェフリーH.



0

ルビー、83バイト

技術的にチート可能9.times、またはそれだけで999.timesなく、私は安くなる気がしない:)

まだ大きなゴルフの可能性があります。(注:y while undoneははるかに長いx.size.times

->x{x.size.times{x.gsub! /\/\|\\?|\|\\/,'/|\\'=>'/|\\','/|'=>'//','|\\'=>'\\\\'}
x}

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



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