验证水平ASCII宠物蛇


22

最近出现了一些ASCII宠物蛇挑战(例如,此处

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

这个挑战是要随机产生一条水平宠物蛇(高度为5行,长度为30),并验证:

  • 每列只有一个 0
  • 每个0都“连接”到它的0前后(仅以0或1行垂直间隔)

最终的输出可以是true1如果蛇是有效的,或者false或者0如果蛇是无效的

编辑-澄清

假设输入:

  • 是一个字符串
  • 仅包含“”,“ 0”和“ \ n”
  • 每行恰好有30个字符
  • 正好有5行

即验证蛇是否已连接,并且没有杂散字符。无需验证印有蛇的“画布”。


4
嗨,欢迎来到PPCG :)这是第一篇文章的挑战,但是您可能想添加更多测试用例,以捕获特殊的蛇。您可能还需要确定蛇是否必须用零表示或可以是任何字符。将来,请考虑使用沙箱。祝您好运:)
FryAmTheEggman '18

5
这被当作刺?还是可以将其输入为二维数组?
JSchiff

6
我们是否保证输入由0和空格组成?每行的长度为30吗?那有5条线吗?
xnor

9
由于这是一个决策问题,truthy/falsey而不是true/false
乔纳森·艾伦'18

3
@JSchiff我确定是蛇字节吗?
MarioDS '18

Answers:


14

JavaScript(ES2018), 62 54字节

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

输入是单个字符串:

  • 没有尾随新行
  • 仅包含空格,“ 0”和“ \ n”
  • 每行30个字符,共5行,共154个字符

标志s表示点匹配任何内容(包括“ \ n”)。Chrome 63 +,Opera 50 +,Safari 11.1+当前基于compat-table支持此功能。您可以使用这些受支持的浏览器测试此功能。如果您的浏览器不支持此功能,则在加载页面时会出现异常。

怎么运行的:

  • 没有列,没有0
    • 不符合 /( .{30}){4} /
  • 0一列中没有两个:
    • 不符合 /0.{30}(.{31})*0/
  • 没有0没有连接到它的邻居:
    • 不匹配/0.{60}(.{31})*0//0.{62}(.{31})*0/

合并所有这些正则表达式,您将最终获得此正则表达式。

感谢Martin Ender指出,一个!操作员可以节省8个字节。


8

SnakeEx,51个字节

这显然是完成任务的正确语言。:^ D

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

如果是有效的蛇,则匹配整个输入;如果不匹配,则无法匹配。在这里尝试!

说明

SnakeEx是2D模式匹配语言。一个程序由“蛇”的定义列表组成,这些定义围绕输入的匹配字符爬行,改变方向并生成其他蛇。在我们的程序中,我们定义了两条蛇,sc

我们首先开始,c因为它更简单。它的定义是0 *$,如果您知道regex,则应该很容易理解:match 0,后跟零个或多个空格,后跟网格边缘。这里的主要要点:这种匹配可以在任何方向进行。我们将使用c从蛇的上方和下方来验证0每列中没有多余的。

现在,对于主要蛇,s。它采用的形式(...)%{30},这意味着“将括号的内容匹配30次”- 0对蛇中的每一个都一次。到目前为止,一切都很好。括号内有什么?

{c<L>}

这会产生一条新c蛇,向左转90度。方向相对于s蛇的方向,因此新蛇移向网格顶部(主蛇移向右侧)。该c蛇检查当前栅格单元是一个0和它上面的每个小区是一个空间。如果失败,则整个匹配失败。如果成功,我们继续

{c<R>}

它执行相同的操作,只是向右转(朝向网格底部)。

请注意,这些生成不会影响匹配指针在主蛇中的位置。它们有点像正则表达式中的前瞻。(也许在这里我们可以称它们为“ lookbesides”?)因此,在确认我们指向a 0且该列的其余部分仅包含空格之后,我们需要实际匹配0

0

现在,匹配指针位于右侧的字符上0。我们需要检查三个不同的选项:蛇形角度向下,蛇形角度向上或蛇形笔直。为此,我们可以使用OR表达式:

[...]

在我们的OR中,我们有三种可能性:

(<R> <L>)

向右转,匹配一个空格,然后再次向左转(蛇形角度向下)。

(<L> <R>)

向左转,匹配一个空格,然后再次向右转(蛇形角度向上)。

_?

匹配零或一个下划线。由于输入中没有下划线,因此这将始终是空匹配(蛇直接输入)。

匹配以上三个选项之一后,匹配指针应指向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)所有列正好包含一个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。


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],第二列提取为s[1::31],并检查其有效性。我们递归s删除第一个字符,从而检查连续的列对。

两列检查使用Python的比较链来in组合多个检查:

  • '0'in s[::31] 检查第一列是否至少有一个 0
  • s[::31]in' %s '%s[1::31]检查第一列是第二列的子字符串,将其夹在两个空格之间,以确保的位置0最多移位了一个空格
  • ' %s '%s[1::31]in'%6s'%0*2检查第二列最多包含一个0

结尾*f(s[1:])也强制递归情况成立。


现在,我想一想,Python是应对这些“蛇”挑战的绝佳语言。:P
MustacheMoses

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.
}

输入的行被读入缓冲区的第一行,接下来的五行用于跟踪期望在每个当前行之后的行中哪些位置(读:必须)具有零,并且最后一行用于跟踪零是否已经存在在给定列的任何行中被读取。程序依次处理每一行。

它一点也不健壮(gets()仅仅是开头),输入必须包含所有相关的空格(例如,没有剩余的尾随空白),并且gcc会发出有关隐式声明的stdlib功能的警告和注释,等等,但是C拉维。

它还假设蛇头不必在中间行,并且有效蛇必须在每行中至少有一个零(即,在5个输入行中所有空间都没有行)。如果是后者的不是可以做短一点的要求-一切与做kl在程序可以缩减身体,或在这种情况下较少的字节代码代替。

感谢user202729的大约。保存26个字节。


欢迎来到PPCG!并且,不必担心其他语言的程序较短
user202729

您可以在#define F和之间留出)-1个字节的空格。
user202729

另外,由于输入只有\n(10),<space>(32)和0(48),因此可以==48使用>47(-1字节)进行检查。/ 如果变量是全局变量,则可以删除={0}when初始化b。同样令k全球和i一个(无类型- > int)的参数main(到位argc1)。
user202729 '18

谢谢!在我看到后面的建议之前进行了编辑;我会通过它们打勾(i就像argc天才一样)。该文件的初稿超过了400个字节。我花了足够长的时间才将其拖到我的个人目标300,然后拖到256,所以我可能错过了更多的缩减方法。
SevenStarConstellation

决定使用make kjl所有全局变量来保存单独的int声明,然后意识到默认值将使我摆脱完全关闭该类型的麻烦。再次感谢!
SevenStarConstellation

1

MATL18 17字节

32>&fun30=wd|2<vA

输入是2D char数组。蛇可以使用任何非空格字符。

在线尝试!

说明

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的线长,因此我认为您可以节省一些。
乔纳森·艾伦'18

@JonathanAllan谢谢!我un30=用来检查所有列索引是否都不同,并且30列中没有一个为空。也许我可以直接测试一下,但是我不知道如何
Luis Mendo


1

果冻,19字节

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

在线尝试!

-2个字节,感谢Xcoder先生

说明

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失败,果冻字符串表示形式发出大声笑。通过ungolfing 1个字节的固定
HyperNeutrino

1

果冻(14?*)13字节

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

一个单子链接,它包含五个字符串*的列表,每个字符串的长度为30,由空格和其他任何字符(例如0s)组成,并返回整数(如果定义为蛇,则返回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 :(
乔纳森·艾伦,

字节数虽然不错:-)
Luis Mendo '18

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字节

-8字节归功于FrownyFrog

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

在线尝试!


1
怎么样[:(-:*)2-/\,检查所有差异是否为−1、0或
1。– FrownyFrog

@FrownyFrog是的,这真是太好了!谢谢!
Galen Ivanov '18

@ FrownyFrog嗯,我没有意识到。我会尝试修复它。感谢您指出这一点。
Galen Ivanov

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

1
哦,这也有效[:($e.~[:(-:*)2-/\])@:I.'0'=|:
FrownyFrog

1

果冻,16字节

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

在线尝试!

假定输入字符串将始终仅仅包含空格和零。将输入作为字符串列表(每个字符串代表一行),如果为真,则输出1,为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

Python 2 141字节

lambda g:(lambda a:all(map(len,a)+[-2<x-y<2 for b in[sum(a,[])]for x,y in zip(b,b[1:])]))([[i for i in range(5)if"0"==r[i]]for r in zip(*g)])

在线尝试!

输入是一个字符网格。


0

的Python 2Python 3中122 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个换行符)的字符串:

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

如果头部不一定要居中

中心行头的要求是最初的挑战,但我发现这里不是这种情况(至少没有明确提及)。

的Python 2Python 3中124个 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个字节。
  • 在限制较少的版本中发现错误,并进行了修订。(幸运的是,它并不是太糟糕,因此我可以使所有版本的长度保持相似。)您可以在后两个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。返回的错误代码是否计数?
MustacheMoses

打高尔夫球12个字节。
MustacheMoses
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.