自验证三角棋盘程序


10

棋盘程序是一个程序,其中每个字符的序数值从偶数到奇数交替,不包括行终止符(可以是任何标准行尾)。

三角程序是这样的程序,其中每行比前一行具有一个附加字符,而第一行具有一个字符。您不需要处理空输入。

您的任务是构建一个程序,以验证给定的输入符合那些条件,并在程序符合条件时输出/返回真值,否则返回虚假值。

您的程序还必须满足这些条件。

有效程序的示例

G
`e
@u^
5r{B

^
cB
+$C
VA01

规则

  • 只要字符的奇偶性交替,您的程序就可以以奇数或偶数字节开头。
  • 您的程序必须验证以奇数或偶数字符开头的程序。
  • 对于Unicode字符,基础字节值必须具有交替的奇偶校验。
  • 您可以假定输入仅包含可打印字符。如果您的程序包含不可打印的内容,则它仍然应该能够进行自我验证。
  • 您的程序可能包含一个尾随换行符,验证不需要这样做,因为您可以假定在验证之前已将其删除。
  • 禁止出现标准漏洞。
  • 每种语言中以字节为单位的最短代码获胜。

@MartinEnder感谢您的输入!希望现在已经清楚了。与此相关,我是否应该将其留在沙箱中更长的时间?
Dom Hastings

1
偶数/奇数水平和垂直交替吗?我认为“棋盘格”中的内容是肯定的,但我看不到你在哪里这么说。
Ton Hospel '18

@DomHastings一周似乎还不错。如果几天后仍未收到任何反馈,则可以在聊天中询问是否还有其他评论。
马丁·恩德

1
@TonHospel我原来的例子做了这一点,但它与我的描述相矛盾,所以对于此实现,不,应该是:E\nOE\nOEO。希望有帮助!
Dom Hastings

2
我的意见:让答案假设输入的内容不是以换行符开头或结尾。
林恩

Answers:


3

Stax,26 个字节

L
Y$
i:-
 {2%
*OFyF
%vi =*

在线运行测试用例

我不得不介绍3个垃圾字符。i在所有循环构造之外时,是空操作。 一直是无人值守。 O在堆栈的顶部下方填充1,但该值未在程序中使用。

LY      move input lines into a list and store in Y register
$       flatten
i       no-op
:-      get pairwise differences
{2%*OF  foreach delta, mod by 2, and multiply, then tuck a 1 under the top of stack
yF      foreach line in original input do...
  %v    subtract 1 from length of line
  i=    is equal to iteration index?
  *     multiply

运行这个


嘿,我希望这不会对您的代码造成太大干扰,但是您可以删除领先的换行验证。
Dom Hastings

8

C(gcc),189个字节

j
;l
;b;
d;f␉
(char
␉*␉t) 
{b=*␉t%
2;for␉(␉
j=d=0;j=j
+ 1,␉l=j+ 
1,␉*␉t; ) {
for␉(;l=l- 1
 ;t=t+ 1 )b= 
!b␉,␉d=d+ !(␉*
␉t␉*␉(␉*␉t- 10)
*␉(␉*␉t%2-b) ) ;
d␉|=*␉t- 10;t=t+ 
1 ; }b= !d; } ␉ ␉ 

在线尝试!

代表制表符(对不起)。请注意,有几个尾随空格/制表符(对不起)。带有标签的原件最好在vim中用:set tabstop=1(语言无法表达对我的遗憾)来查看。

这是一个函数(称为f,乍一看并不明显),该函数将字符串作为参数并返回01

可以减少这一行至少一行,也可以减少两行或更多行,但是请注意,到最后它变得越来越混乱,工作量越来越少,这主要是因为编写如此糟糕的代码(即使按照PPCG标准)也让我感到自己像个坏人我想尽快停下来

这里的基本思路是,以避免结构是必然打破格式(+++=return等)。奇迹般地,像forchar和这样的重要关键字while(我最终没有使用)恰好适合交替的奇偶校验规则。然后,我使用空格(偶数奇偶校验)和制表符(奇数奇偶校验)作为填充,以使其余部分符合规则。


1
我没想到会在C中看到解决方案!
Dom Hastings '18

如果通过在“页眉”和“页脚”部分中放置其他内容来隔离TIO中程序的解决方案部分,则使人们更容易验证字节数。
Jakob

4

Haskell1080 1033字节

;
f=
 g 
ij=f
a =hi
hi = g
hij= ij
g ' ' =0
g '"' =0;
 g '$' =0;
 g '&' =0-0
g '(' =0-0-0
g '*' =0-0-0;
 g ',' =0-0-0;
 g '.' =0-0-0-0
g '0' =0-0-0-0-0
g '2' =0-0-0-0-0;
 g '4' =0-0-0-0-0;
 g '6' =0; g '8' =0
g ':' =0; g '<' =0-0
g '>' =0; g '@' =0-0;
 g 'B' =0; g 'D' =0-0;
 g 'F' =0; g 'H' =0-0-0
g 'J' =0; g 'L' =0-0-0-0
g 'N' =0; g 'P' =0-0-0-0;
 g 'R' =0; g 'T' =0-0-0-0;
 g 'V' =0; g 'X' =0-0-0-0-0
g 'Z' =0; g '^' =0; g '`' =0
g 'b' =0; g 'd' =0; g 'f' =0;
 g 'h' =0; g 'j' =0; g 'l' =0;
 g 'n' =0; g 'p' =0; g 'r' =0-0
g 't' =0; g 'v' =0; g 'x' =0-0-0
g 'z' =0; g '\92' =0-0; g '|' =0;
 g '~' =0; g y = 1 ;z=0; i(-0)z=z;
 i m('\10':y ) ="y"; ; ; ; ; ; ; ; 
i m(mnmnmnmnm:y ) = i(m - 1 ) y ; ; 
i k m ="y"; ; k i [ ] =01<1010101010;
 k m('\10':y ) = k(m + 1 )(i m y ) ; ;
 k m y =01>10; m o = k 1$'\10':o ; ; ; 
o i('\10':y ) = o i y ; ; ; ; ; ; ; ; ; 
o i(k:y )|g k<i = o(1 - i ) y ; ; ; ; ; ;
 o i(k:y )|g k>i = o(1 - i ) y ; ; ; ; ; ;
 o i [ ] =01<10; o i y =01>10;v=01>10101010
s y|o 1 y = m y|o(-0) y = m y ; s y =v; ; ; 

在线尝试!

说明

对于Haskell来说,这是非常有趣的任务。

平价

首先,我们需要某种确定字符是否具有偶数或奇数代码点的方法。这样做的通常方法是获取代码点并将其修改为2。但是,正如人们可能知道的那样,获取字符的代码点需要导入,由于源代码的限制,它不能被导入。用过的。经验更丰富的Haskeller会考虑使用递归。 CharEnum类型类的一部分,因此我们可以获取它们的前任和后继。但是predsucc它们也不可用,因为它们不交替字节奇偶校验。

因此,这使我们陷入困境,我们几乎无法对char进行任何操作。解决方案是对所有内容进行硬编码。我们可以将(大多数)偶数字符表示为文字,我们遇到的'奇数是麻烦的,因为它是奇数,因此它不能与char本身相邻,从而使文字无法表达大多数奇数字符。因此,我们对所有偶数字节进行硬编码,然后在最后添加所有奇数字节的catch。

问题字节

您可能会注意到,有些偶数字节无法通过将其用单引号引起来来产生字面量。它们是不可打印的内容,换行符和\。我们不需要担心不可打印的东西,因为只要我们不使用任何不需要打印的东西就可以进行验证。实际上,我们仍然可以使用奇数不可打印的东西,例如制表符,我只是最终不需要这样做。可以明智地忽略换行符,因为无论如何都会从程序中删除换行符。(我们可以包括换行符,因为它的代码点相当方便,但我们不需要这样做)。这留下了\,现在\有代码点92,它方便地是一个奇数后跟一个偶数,因此\92在偶数和奇数之间交替,因此文字'\92'是完全有效的。稍后,当我们确实需要代表换行符时,我们会注意到它很幸运具有相同的属性'\10'

间距问题

现在,为了开始编写实际代码,我们需要能够在一行上放置大量字符。为了做到这一点,我写了上限:

;
f=
 g 
ij=f
a =hi
hi = g
hij= ij

除有效的Haskell外,封顶不会执行任何操作。最初,我曾希望做出一些定义,以在以后的代码中为我们提供帮助,但事实并非如此。还有一些更简单的方法来制作上限,例如,空格和分号,但是它们不会以这种方式保存字节,因此我不必费心去更改它。

硬编码器

因此,现在我在一行上有足够的空间,我开始对值进行硬编码。这通常很无聊,但是有一些有趣的事情。一旦行开始变得更长,我们就可以;在一行上放置多个声明,这可以为我们节省大量的字节。

第二个原因是,由于我们不能总是g如此频繁地开始一行,因此我们不得不稍微缩进一行。现在,Haskell真的很关心缩进,因此它将对此抱怨。但是,如果缩进行之前的最后一行以分号结尾,则将允许它。为什么?我没有最微弱的人,但是可以。因此,我们只需要记住将分号放在行尾。

功能构建块

硬编码器完成后,就可以顺利运行到程序结尾。我们需要构建一些简单的功能。首先,我建立一个drop名为的版本iidrop我们的不同之处在于,如果我们尝试删除字符串的末尾,它只会返回"y"i与drop的不同之处还在于,如果尝试删除换行符,它将返回"y",这将很有用,因为稍后当我们验证程序是三角形时,这将允许我们False在最后一行未完成时或在一条线早点结束。

kkñssTrueñkñ+1个False

然后k,我们为命名mm仅仅是k1在第一个参数,和一个换行前置到第二个参数。

接下来我们有oo需要一个数字和一个字符串。它确定字符串字节(忽略换行符)是否g以输入数字开头的奇偶校验(使用)交替出现。

最后,我们有s它运行o10,如果成功,要么推迟它来m。如果两者均失败,则仅返回False。这是我们想要的功能。它确定输入是三角形且交替的。


1
三角形字符串以1个字符的行开头,而不是空行。
Jakob

@Jakob我认为这很愚蠢,但这很容易解决。
Ad Hoc Garf Hunter

3

05AB1E34 26字节

¶
¡D
©€g
´ā´Q
´sJÇÈ
¥Ä{´нP

在线尝试!

将输入作为多行字符串(““”之间的输入)。稍后将进行说明。


1
除非我误解了规则,否则程序还需要能够以换行符开头的输入来验证输入。
Emigna '18

@Emigna我认为您的程序只有在以换行符开头时,才必须能够验证换行符。
Ton Hospel

我不知道这是否正确(我不擅长阅读规格):在线尝试!
魔术章鱼缸

@MagicOctopusUrn您的回答对我来说似乎不错,但我想知道输入内容:是否允许将其作为数组?在您的链接中,您的第一个输入是一个空格,而不是换行符。
Kaldo

1
嘿,我希望这不会对您的代码造成太大干扰,但是您可以删除领先的换行验证。
Dom Hastings

1

Java 10,209个字节

一个空lambda,它采用的可迭代或数组byte。通过正常返回表示true,通过抛出运行时异常表示false。程序期望最后一行正确终止,即以换行符结束。程序的最后一行类似地终止。

一切都在UTF-8下完成,其解释是“字符”是指Unicode代码点。

在此视图中,制表符替换为空格。

d
->
{  
long
f= 1,
 h=0 ,
c = - 1
,e ;for 
( byte a:
 d) {var b
=(e = a^10)
<1&e>- 1 ;f=
b?( h ^ f)> 0
?0/0 : f+ 1: f
;h=b?0 :a>-65 ?
h+ 1: h; c =b? c
:c>=0 & ( (c^a )&
1 )<1 ?0/0 :a ; } 
/*1010101010101*/ }

在线试用

十六进制转储

xxd -p -r在Unix上还原。

640a2d3e0a7b20090a6c6f6e670a663d20312c0a09683d30092c0a63203d
202d20310a2c65203b666f72090a28096279746520613a0a096429207b76
617209620a3d2865203d20615e3130290a3c3126653e2d2031203b663d0a
623f280968095e0966293e09300a3f302f30093a09662b20313a09660a3b
683d623f30093a613e2d3635203f0a682b20313a09683b2063203d623f20
630a3a633e3d30092609280928635e612029260a3120293c31203f302f30
093a61203b207d200a2f2a313031303130313031303130312a2f207d0a

不打高尔夫球

d -> {
    long f = 1, h = 0, c = ~h, e;
    for (byte a : d) {
        var b = (e = a^10) < 1 & e > -1;
        f = b ?
            (h^f) > 0 ? 0/0 : f + 1
            : f
        ;
        h = b ? 0 :
            a > -65 ? h + 1 : h
        ;
        c = b ? c :
            c >= 0 & ((c^a) & 1) < 1 ? 0/0 : a
        ;
    }
}

f是当前行上预期的字符数,h是当前行上到目前为止已看到的字符数,c是已看到的最后一个字节,b是否a为换行符。

条件a > -65测试a字符是否为第一个字节。之所以有效,是因为单字节(ASCII)字符在8位二进制补码中为非负数,较长字符的第一个字节为二进制形式11xxxxxx(在二进制补码中至少为-64),并且这些字符中的非前导字节为形式10xxxxxx,最多为-65,以两位数补码。(资料来源

当字符违反三角形或棋盘格图案(即换行符出现在早期或晚期或出现错误的奇偶校验字节)时,相应三元数的左分支(分配给fc)被激活,并且该方法引发算术异常。


0

Python 3(3.4?),350字节

对于像Python 3这样的特定于空格的语言来说,这是一个棘手的挑战。提交的内容会打印0或打印1出来,并导致某些输入崩溃。程序期望最后一行正确终止,即以换行符结束。程序的最后一行类似地终止。UTF-8用于检查字节奇偶校验。

在此视图中,制表符替换为空格。

0
i\
= 1
t=(#
 '0'*
 0) ;(
g,) =(#
 open (1
, "w"),) 
k = eval (
'p' + 'rin'
 + 't' ) #01
for  a in (#0
open ( 0) ):#0
#01010101010101
 a = a [:- 1 ] #
 if ( len (a )<i\
or len (a )>i ):[\
k('0' ),1 /0] #0101
 i, t= -~i, t+ a #01
(k( 2-len ({(c^i )&1\
 for  i,c in  eval (#0
 "enu"+"m"+"erate")(#01
 eval ( " byte"+"s")( t#
,' u8' ) ) } ) ) ) #01010

适用于Python 3.4.2;在TIO上的任何Python 3上均不起作用。在我看来,这是TIO解释器中的错误。

十六进制转储

还原为 xxd -p -r在Unix上。

300a695c0a3d20310a743d28230a202730272a0a093029203b280a672c29
203d28230a206f70656e0928310a2c09227722292c29200a6b203d206576
616c09280a277027202b202772696e270a202b202774272029202330310a
666f7209206120696e092823300a6f70656e092809302920293a23300a23
30313031303130313031303130310a2061203d2061205b3a2d2031205d20
230a2069660928096c656e09286120293c695c0a6f72096c656e09286120
293e6920293a5b5c0a6b2827302720292c31202f305d2023303130310a20
692c09743d202d7e692c09742b2061202330310a286b2809322d6c656e09
287b28635e69202926315c0a09666f720920692c6320696e09206576616c
092823300a0922656e75222b226d222b2265726174652222229282330310a20
6576616c092809220962797465222b22732229280974230a2c2720753827
20292029207d202920292029202202330313031300a
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.