水平ASCIIペットヘビの検証


22

最近、ASCIIペットのヘビの挑戦がいくつかありました(例えば、こちら

            0 0               
  0        0 0 000            
00 0     00       000 0      0
    000 0            0 0   00 
       0                000   

この課題は、ランダムに生成された水平ペットスネーク(高さ5行、長さ30)を取得し、それを検証することです。

  • 各列には1つしかありません 0
  • それぞれ00前後に「接続」されています(垂直方向に0または1行だけ間隔が空いています)

最終的な出力が可能true1蛇が有効である場合、またはfalseまたは0ヘビが無効な場合

編集-明確化

入力を想定します。

  • 文字列です
  • 「」、「0」、および「\ n」のみが含まれます
  • 各行に正確に30文字あります
  • 正確に5行あります

すなわち、ヘビが接続されているかどうか、および浮遊チャーがないことを確認します。ヘビが印刷されている「キャンバス」を検証する必要はありません。


4
こんにちは、PPCGへようこそ:)これは最初の投稿にとっては良い挑戦ですが、おそらく例外的なヘビを捕まえるテストケースをさらに追加する必要があります。また、ヘビをゼロで表現する必要があるのか​​、それとも任意のキャラクターにすることができるのかを判断する必要があります。将来的には、サンドボックスの使用を検討してください。幸運:)
FryAmTheEggman

5
これはスティングと見なされますか?または、2D配列として入力できますか?
JSchiff

6
入力が0とスペースで構成されていることが保証されていますか?すべての行の長さは30ですか?5行あること?
xnor

9
これは、意思決定の問題は方法についてあるのでtruthy/falseyではなくtrue/false
ジョナサンアラン

3
@JSchiff確かにスネークバイト?
マリオDS

回答:


14

JavaScript(ES2018)、 62 54バイト

s=>!/0(.{30}|.{60,62}(.{31})*)0|( .{30}){4} /s.test(s)

入力は単一の文字列です。

  • 末尾の改行なし
  • スペース、「0」、および「\ n」のみを含む
  • 各行30文字、5行、合計154文字

フラグsは、ドットがすべてに一致することを意味します(「\ n」を含む)。この機能は、compat-tableに基づいて、Chrome 63以降、Opera 50以降、Safari 11.1以降で現在サポートされています。これらのサポートされているブラウザでこの機能をテストできます。ブラウザがこの機能をサポートしていない場合、ページの読み込み時に例外が発生します。

使い方:

  • なしの列はありません0
    • 一致しない /( .{30}){4} /
  • 01つの列に2つはありません:
    • 一致しない /0.{30}(.{31})*0/
  • ノー0隣国に接続できません。
    • 一致しない/0.{60}(.{31})*0//0.{62}(.{31})*0/

これらすべての正規表現をマージすると、最終的にこの正規表現が得られます。

Martin Enderのおかげで、1人の!オペレーターで8バイト節約できると指摘しています。


8

SnakeEx、51バイト

これは明らかにタスクに適した言語です。:^ D

s:({c<L>}{c<R>}0[(<R> <L>)(<L> <R>)_?])%{30}
c:0 *$

有効なスネークである場合、入力全体に一致します。一致しない場合、一致しません。ここで試してみてください!

説明

SnakeExは2次元パターンマッチング言語です。プログラムは、「蛇」の定義のリストで構成されます。「蛇」は、一致する入力文字を巡回し、方向を変え、他の蛇を産み出します。私たちのプログラムでは、我々は2匹のヘビを定義し、sそしてc

cシンプルだから始めましょう。その定義は0 *$であり、regex:matchの0後に0個以上のスペースが続き、その後にグリッドの端が続く場合、非常に読みやすいはずです。ここでの主要なキャッチ:このマッチングは、どの方向にも進むことができます。各列にc余分な0s がないことを確認するために、蛇から上向きと下向きの両方を使用します。

今メインヘビのため、s。これは、(...)%{30}「括弧の内容を30回一致させる」ことを意味する形式を取ります。これは0、蛇の中でそれぞれ1回です。ここまでは順調ですね。括弧の中には何が入りますか?

{c<L>}

これによりc、左に90度回転した新しい蛇が生まれます。方向はsヘビの方向を基準にしているため、新しいヘビはグリッドの上部に向かって移動します(メインヘビは右に向かって移動しています)。c現在のグリッドセルであること蛇チェック0とその上のすべてのセルが空白です。失敗した場合、一致全体が失敗します。成功した場合、続行します

{c<R>}

これは同じことを行い、右にのみ(グリッドの下部に向かって)曲がります。

これらのスポーンは、メインスネークのマッチポインターの位置に影響を与えないことに注意してください。それらは正規表現の先読みのようなものです。(ここで「lookbesides」と呼ぶこともできますか?)ですから、a 0を指し、残りの列にスペースしか含まれていないことを確認した後、実際に一致させる必要があります0

0

これで、マッチポインターはの右側の文字にあり0ます。3つの異なるオプションをチェックする必要があります。スネークアングルが下向き、スネークアングルが上向き、またはスネークが直進します。このために、OR式を使用できます。

[...]

OR内では、3つの可能性があります。

(<R> <L>)

右に曲がり、スペースを合わせて、再び左に曲がります(蛇角を下げます)。

(<L> <R>)

左に曲がり、スペースを合わせて、再び右に曲がります(蛇の角度が上)。

_?

0個または1個の下線に一致します。入力にアンダースコアがないため、これは常に空の一致になります(ヘビはまっすぐになります)。

上記の3つのオプションのいずれかと一致した後、一致ポインターは0次の列を指し、括弧で囲まれた式と再度一致する準備ができているはずです。


2

CJam35 34バイト

{z_{'0e=1=}%:*\'0f#2ew::-[W0X]-!*}

オンラインでお試しください!入力は、文字の配列の長方形の配列です。入力にとのみが含まれる と仮定します0

説明:

{z_{'0e=1=}%:*\'0f#2ew::-[W0X]-!*}   Function taking a character matrix:
 z                                      Transpose.
   {      }%                            Consider whether each row
      e=                                  contains
        1=                                exactly one
    '0                                    of the character '0'.
            :*                            This must be true for every row.
                  #                     Next, find the position
               '0                         of the character '0'
                 f                        at every row
  _           \                           in the original input.
                       :-               Find the differences between
                      :                   each
                   2                      pair
                    ew                    of adjacent elements (in other words, compute
                                            the increments).
                                        For the snake to be valid, this array of increments
                                            must only contain {0, 1, -1}, so
                              -         Remove from this list
                         [   ]            the elements
                          W                 -1,
                           0                0,
                            X               and 1,
                               !          and then check whether the array is empty.
                                *       The previous code tested two different properties
                                          of the matrix; they both must be true for a
                                          valid snake.

2

05AB1E、18バイト

ζDε0k}¥Ä2‹sεþg}ìPΘ

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

説明

ζ                    # transpose
 D                   # duplicate
  ε  }               # for each row in the first copy (column of input)
   0k                # get the index of the first 0
      ¥Ä             # calculate absolute delta's
        2‹           # check that each is less than 2
          sε  }      # for each row in the second copy (column of input)
            þg       # calculate the length of the string with non-digits removed
               ì     # concatenate the lists
                P    # calculate product
                 Θ   # truthify (turn false values to 0)

2

、12バイト

ルールの説明に応じて、11バイトまたは13バイトになります

±Λ=;1Ẋ×≈mηfT

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

入力は、スペースと0のみを含む行のリストです。単一の文字列が必要な場合は、プログラムの先頭に追加して行に分割します。TIOリンクは、明確にするために既にこれを行っています。出力は0または1です。偽の値や真実の値に問題がなければ、±削除できます。

説明

±Λ=;1Ẋ×≈mηfT  Implicit input: a list of lines.
           T  Transpose into list of columns.
        m     For each column,
         ηf   get list of indices of truthy elements.
              In Husk, whitespace characters are falsy and other are truthy,
              so this gets us the indices of 0s on each column.
     Ẋ        For each adjacent pair of these index lists,
      ×       for all pairs drawn from the two lists,
       ≈      give 1 if they differ by at most 1, otherwise 0.
              For each adjacent pair, this produces a list of 1s and 0s.
 Λ            Do all of these lists
  =;1         equal [1]? Return either 0 or 30 (length of the outer list + 1).
±             Signum; convert to 0 or 1.

考え方は×≈、(a)すべての列に正確に1つの0が含まれ、(b)それらの位置が最大で1だけ異なることを保証するために使用することです。例として、8列の入力を考えます

0  0  0 
 000 0  
  00   0

最初に、mηfTインデックスリストのリストに変換します

[[1],[2],[2,3],[1,2,3],[],[2],[1],[3]]

それからẊ×≈与える

[[1],[1,1],[1,1,0,1,1,1],[],[],[1],[0]]

それぞれが1最大で1だけ異なるインデックスのペアに0対応し、それぞれがそうでないペアに対応します。[1]両方のリストに1つのインデックスがあり、インデックスの差が最大1である場合、各結果は正確に等しくなります。


2

Python 2、71バイト

f=lambda s:s[1]<' 'or'0'in s[::31]in' %s '%s[1::31]in'%6s'%0*2*f(s[1:])

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

入力を複数行の文字列として受け取ります。Bubblerのテストケース。

最初の列はとして抽出されs[::31]、2番目の列はとして抽出され、s[1::31]有効性がチェックされます。s最初の文字を削除すると再帰的になり、連続する列のペアがチェックされます。

2つの列のチェックでは、Pythonの比較チェーンを使用しinて複数のチェックを組み合わせます。

  • '0'in s[::31] 最初の列に少なくとも1つの列があることを確認します 0
  • s[::31]in' %s '%s[1::31]最初の列が2つのスペースに挟まれた2番目の列の部分文字列であることを確認し0ます。
  • ' %s '%s[1::31]in'%6s'%0*22番目の列に最大1つ含まれていることを確認します0

終了*f(s[1:])は、再帰的なケースを真にすることも強制します。


今考えてみると、Pythonはこれらの「ヘビ」の挑戦にとって素晴らしい言語です。:P
MoustacheMoses

2

C(gcc)246 245 232 215 212バイト

#define F)exit(1);
#define L for(i=l=0;i<30;i++)
#define X b[7][i]
char b[8][31];k,j,l;main(i){for(;j++<5;){gets(b);L{if(i[*b]>47){if(X++F memset(b[j+1]+i-1,l=1,3);}else if(!X&b[j][i]F}k+=!!l;}if(k<5 F L if(!X F}

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

私はこれに自分の好きな言語を取り入れると思いました(他の多くの小さなエントリからわかるように、おそらくこの種のチャレンジには理想からはほど遠いでしょう)。この問題に対するプログラムのアプローチは比較的単純で、多くのペニーピンチがあります。stdinの蛇を受け取り、その結果をmainの戻り値で返します(したがって、終了コード。問題で要求されたように、0は無効なヘビを示し、1は奇妙な終了コードであっても有効です終了コードの典型的な例として、0は有効なヘビであり、1は無効なヘビです。マクロを展開し、いくつかの素敵な空白を追加すると、次のようになります。

char b[8][31];l,j,k;                           //Declares a buffer to work in, initialized all to 0; l j and k default to int and as globals are init to 0
main(i) {                                      //This is run no-args, so argc is 1 and the undeclared type defaults to int.
  for (; j++ < 5;) {                           //Iterating over each row, 1-indexed for convenience accessing the buffer
    gets(b);                                   //Reads into b[0] because of stack array decl layout
    for (i = l = 0; i < 30; i++) {             //j and l both init each time we begin this overall loop
      if (i[*b] > 47) {                        //Did we read a zero?
        if(b[7][i]++) exit(1);                 //If the snake already had a zero in this column, fail out
        memset(b[j+1] + i-1, l = 1, 3);        //Expect them on the next row in the columns left and right of this one (also set l)
      } else if (!b[7][i] & b[j][i]) exit(1);  //If we didn't read a zero, and we had reason to expect one this row, and there wasn't already a zero in this column, fail out
    }
    k+=!!l;                                    //Adds 1 to k iff l is nonzero 
  } if (k < 5) exit(1);                        //If less than 5 rows had zeroes in them, fail out
  for(i = l = 0 ; i < 30; i++) {               //l isn't relevant in this loop but saves some bytes when sharing a macro with the other horizontal loop
    if(!b[7][i]) exit(1);                      //If any columns didn't have zeroes, fail out
  }                                            //Else, snake is valid. main default returns 0.
}

入力行はバッファの最初の行に読み込まれ、次の5つは現在の各行の後に行にゼロがあると予想される場所(読み取り:必須)を追跡するためのものであり、最後はゼロが既にあるかどうかを追跡するためのものです任意の行の特定の列で読み取られた。プログラムは各行を順番に処理します。

まったく堅牢ではありません(gets()はなく始まりにすぎません)、入力には関連するすべてのスペース(たとえば、残りの末尾の空白がない)を含める必要があり、gccは暗黙的に宣言されたままになったstdlib機能に関する警告とメモを吐き出しますが、Cラヴィ。

また、スネークヘッドが中央の行にある必要はなく、有効なスネークはすべての行に少なくとも1つのゼロが必要である(つまり、5つの入力行にすべてのスペースの行がない)と想定しています。後者が要件でない場合は、少し短くすることができます-に関係するすべてklその場合は、プログラム内プログラム内の切り詰めるか、またはより少ないコードのバイトで置き換えることができます。

約のuser202729に感謝します。26バイトが保存されました。



#define F)-1バイトの間のスペースを省くことができます。
user202729

また、入力には\n(10)、<space>(32)、および0(48)しか含まれていないため、==48>47(-1バイト)で。/ 変数がグローバルである場合、={0}初期化時に削除できbます。同様に行いk、グローバルおよびi- (>型なしintのパラメータ)main(の代わりにargcあります1)。
user202729

ありがとうございました!後者の提案を見る前に編集しました。私は(というそれらを介して自分の道にチェックを入れますiとしてはargc天才です)。この最初のドラフトは400バイトを大きく超えていました。私の目標である300から256に引き下げるのに十分な時間を要したので、見逃したスリム化の方法が他にもあるかもしれません。
SevenStarConstellation

作ることを決めたkjl別々の持つ節約するすべてのグローバルintデフォルト値を実現し、その後、宣言は、私は完全にオフタイプを残して逃げる聞かせ。再度、感謝します!
SevenStarConstellation

1

MATL18 17バイト

32>&fun30=wd|2<vA

入力は2D文字配列です。ヘビにはスペース以外の文字を使用できます。

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

説明

32>      % Implicit input. Transform non-space into 1, space into 0
&f       % Push vector of row indices and vector of column indices of nonzeros
u        % Unique: vector of deduplicated entries
n        % Length
30=      % Does it equal 30? (*)
w        % Swap. Moves vector of row indices to top
d|       % Absolute consecutive differences
2<       % Is each value less than 2? (**)
v        % Concatenate results (*) and (**) vertically
A        % All: true if all entries are nonzero. Implicit display

1
仕様では、行の長さが30であることが保証されているので、数個節約できると思います。
ジョナサンアラン

@JonathanAllanありがとう!un30=すべての列インデックスが異なっており、30の列が空ではないことを確認するために使用しています。もっと直接テストできるかもしれませんが、どうすればいいかわかりません
ルイスメンドー


1

ゼリー、19バイト

Zn⁶T€L€=1$$;FIỊ$$$Ạ

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

Mr. Xcoderのおかげで-2バイト

説明

Zn⁶T€L€=1$$;FIỊ$$$Ạ  Main Link
Z                    Transpose the matrix of characters
                         (string -> list of chars in Jelly)
 n⁶                  != " " (vectorizing)
   T€                For each column, get (row) indices of snake parts
     L€=1$$          For each index list, is its length 1? (that is, exactly one snake part per column)
           ;     $   Append (helper part)
            FIỊ$$    helper part:
            F        flatten index list
             I       get increments/forward differences
              Ị      are the values insignificant? (|z| <= 1)
                  Ạ  Are these all true?

入力は文字列のリストとして


@ Mr.Xcoder失敗、ジェリーの文字列表現の問題 1バイトをアンゴルフすることで修正
HyperNeutrino

1

ゼリー、(14?*)13バイト

Zn⁶T€z-IỊ0-¦Ȧ

それぞれ長さ30のスペースと他の文字(0sなど)で構成される5つの文字列*のリストを受け取り、整数(スネークが定義されている場合は1、そうでない場合は0)を返すモナドリンク

*入力が単一の文字列(文字のリスト)でなければならない場合、改行で文字列を分割するためにa を追加します。

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

どうやって?

Zn⁶T€z-IỊ0-¦Ȧ - Link: list of lists of characters, Lines
Z             - transpose the lines -> columns
  ⁶           - literal space character
 n            - not equal? -> 0 where there were spaces and 1 where there were "0"s
   T€         - truthy indices for each -> e.g. [0,0,1,0,0] -> [3] or [0,1,1,0,0] -> [2,3]
              -                           note: [0,0,0,0,0] -> []
      -       - literal minus one
     z        - transpose with filler (-1) -> {valid: a single list of heights {top:1,...,bottom:5}
              -                              invalid: list of >1 lists, some of which contain -1
              -                                       ...OR an empty list (no 0s in the input at all)}
       I      - differences -> {up:-1; down:1; flat:0; invalid:-6,-5,...,-2,2,...4}
        Ị     - insignificant (abs(z)<=1) -? {up/down/flat:1; invalid:0}
           ¦  - sparse application///
         0    - ...action: literal zero
          -   - ...to indices: [-1] -> make penultimate list into a zero (when one exists)
            Ȧ - any & all -> when flattened:{empty or contains a 0:0; otherwise:1}

ああ、ヘッズアップのおかげで、私はすべてのエッジケースを試したと思った。後で対処する必要があります。
ジョナサンアラン

@LuisMendoへえと、それを修正して3つ節約したので、もう一度ありがとう!
ジョナサンアラン

...ええと、しかし、私は別のものを導入しました。別の3のために修正:(
ジョナサンアラン

悪いバイト数ではありませんが:-)
ルイスメンドー

1

スタックス、20 バイトCP437

Å┴m▐◘5)ît╢V¼≥+╝╜►º½ê

展開すると24バイト、

LM{'0|Ic%vChm:-{Jh!f%29=

オンラインで実行してデバッグします!

最高のゴルフではないかもしれませんが、この方法は斬新で面白いと思います。

説明

LM                          Load the input string as a 2d array of characters, and transpose it

  {         m               Map array with block
   '0|I                     Get all indices of substring "0"
       c%vC                 Map to nothing if the indices are not unique
           h                Otherwise map to the unique index

             :-             Take pairwise difference

               {   f        Filter array with block
                Jh!         Only keep 0, 1 and -1

                    %29=    Check whether the final array has exactly 29 elements

1

J38、37 30バイト

FrownyFrogのおかげで-8バイト

[:($e.~[:(-:*)2-/\])@:I.'0'=|:

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


1
どうですか[:(-:*)2-/\、すべての違いが-1、0、または1であるかどうかを確認してください。
FrownyFrog

@FrownyFrogはい、それはずっとベターです!ありがとうございました!
ガレンイワノフ

@ FrownyFrogうーん、私はそれを知りませんでした。私はそれを修正しようとします。ご指摘いただきありがとうございます。
ガレンイワノフ

1
[:(#@{.=[:(-:*)2-/\])@:I.'0'=|:
FrownyFrog

1
ああ、これも動作します[:($e.~[:(-:*)2-/\])@:I.'0'=|:
-FrownyFrog

1

ゼリー、16バイト

Zµi€”0IỊ;ċ€⁶=4ƊẠ

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

入力文字列には常にスペースとゼロのみが含まれると仮定します。(各ラインを表す)文字列のリストとして入力を受け取り、出力1を truthy場合、0そうでなければます。

説明

Zµi€”0IỊ;ċ€⁶=4ƊẠ | Monadic full program.
Z                | Transpose.
 µ               | Start a new monadic chain.
  i€”0           | Retrieve the first index of 0 in each column.
      IỊ         | Check whether their increments are insignificant (element-wise).
        ;     Ɗ  | Append the result of the following:
         ċ€⁶     | In each list of characters, count the occurrences of a space.
            =4   | Check whether they equal 4 (returns a boolean array).
               Ạ | All. Check whether all the elements are truthy.


0

パイソン2及びパイソン3122 120 119のバイト

lambda s:s.count('0')<31and all(s[i-31*(i>30):31*(i<124)-~i:31].strip(' ')for i,x in enumerate(s,1)if' '<x)and' '<s[62]

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

入力形式は、長さ154(5 x 30文字、4つの改行)の1つの文字列です。

'''
            0 0               
  0        0 0 000            
00 0     00       000 0      0
    000 0            0 0   00 
       0                000   '''[1:] # to exclude starting newline

頭が中央の列である必要がない場合

中央の行頭の要件は元の課題にありましたが、ここではそうではないことがわかりました(少なくとも明示的に言及されていません)。

パイソン2及びパイソン3124の 123バイト

lambda s:s.count('0')<31and all(s[i-31*(i>30):31*(i<124)-~i:31].strip(' ')for i,x in enumerate(s,1)if' '<x)and'0'in s[::31]

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


編集:

  • equals(を変更して2バイトを削減==)を各コードの不等式に。
  • 制限の少ないバージョンで間違いを見つけ、修正しました。(幸いなことに、それほどひどくないので、すべてのバージョンの長さを同じにしておくことができます。)後の2つのTIOリンクで追加のテストケースを見ることができます。
  • Py2ソリューションで宙ぶらりんのバイトを見つけ、all()Py3でこのトリックを無意味にし、両方のバージョンをマージしました。

0

Excel(VBA)、68バイト

Cell[A6]出力としてイミディエイトウィンドウを使用します。

[A1:AD5]="=CHOOSE(ROUND(RAND()+1,),0,"""")":[A6]="=COUNT(A1:AD5)=30"





0

Python 3 197の 185バイト

コマンドプロンプトで行うverify.py<snake.txtか、bashで行うcat snake.txt | python verify.pysnake.txt確認するヘビを含むファイルはどこにありますか。

ヘビが正しい場合、何も出力されません。正しくない場合、Pythonはインデックスエラーを発生させます。

import sys
s=sys.stdin.read().split("\n")
x=0
exec('t,y="",0\nwhile y<5:t+=s[y][x];y+=1\ns+=[t];x+=1;'*30)
s=list(map(lambda l:len(l.rstrip()),s))
while y<35:"ee"[abs(s[y]-s[y+1])];y+=2

ああ、出力がtrueまたはfalseでなければならないことに気づきませんでした。返されたエラーコードはカウントされますか?
口ひげ

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