INTERCAL打高尔夫球的秘诀


10

您在INTERCAL打高尔夫球有哪些一般提示?我正在寻找可用于编写高尔夫挑战赛的想法,并且至少在某种程度上特定于INTERCAL(即“删除评论”不是有用的答案)。

我知道使用外语对赢得高尔夫比赛非常有用,但是我在这里看不到太多的INTERCAL代码。您有什么建议可以帮助人们使用INTERCAL获得具有竞争力的代码大小吗?这种语言有竞争力吗?

INTERCAL未被充分利用,甚至没有标签。好难过...


大多数语言在这里没有或需要自己的标签,因为通常不鼓励针对特定语言的挑战。
Alex A.

9
从其维基百科页面上暗示这可能不是最好的高尔夫语言:Despite the language's intentionally obtuse and wordy syntax,
isaacg 2015年

Answers:


2

去除空白/“噪声”的范围可能超出您的预期

INTERCAL是对空格不敏感的语言。但是,与大多数对空格不敏感的语言不同,这种不敏感远远超出了您的预期。

例如,DO NOT是两个令牌,但是可以编写DONOT而不会引起解析器的抱怨(几乎在任何广泛使用的实现中)。(当然,您也可以编写DON'T,但这并不是什么麻烦的事。尽管它可能更容易阅读。但是PLEASEN'T,可能比起来更难阅读PLEASE NOT。)实际上,对于空白是否有任何作用,存在一些争论。至少一个INTERCAL解析器甚至允许在数值常量内使用它(这并不是打高尔夫球时非常有用的功能)。要记住的一件事是,由于存在嵌入式,因此从DO READ OUT给定中删除空格会使一些较旧的INTERCAL解析器感到困惑DOREADOUTDO(尽管他们的作者通常认为这是一个错误,因此如今它通常可以在有效的程序中运行,但不建议将这样的代码放在语法错误的附近,因为这样一来,很难将其消除歧义)。

还要记住,您可以过度打孔以节省空间。在ASCII中,您只能使用'.→ 真正实现此目的!,但这本身就是一个非常有用的技巧。(当您不使用数组时,即使您所有的分组字符都相同,也不会出现火花含糊的可能性,因此对于高尔夫球手,建议坚持使用,'除非数组下标确实需要一个"。)使用?缩写(C-INTERCAL)或Latin-1表示¥(CLC-INTERCAL)以一个字节表示,而不是INTERCAL-72所需的三个。


2

在一份声明中专注于尽可能多的工作

INTERCAL的语句标识符非常冗长;DO每个语句上有两个杂音字符,该语句的名称本身也往往很长,并且您必须PLEASE不时地抛出一个,以使解析器满意。(你能做的最好的是四的比率DO到一个PLEASE,您使用的14个字符中每5级的命令标识符的意义。)。另一方面,表达式语法相当简洁(可笑,但简洁)。这意味着,即使使用多个语句是一种更“自然”的处理方式,通常也值得将程序的一部分放入单个表达式中。

例如,如果你想分配#1.1#2.2的,而不是在明显INTERCAL-72这样做,:

DO.1<-#1DO.2<-#2

非常值得考虑重载随机变量以允许您一次分配两个变量:

DO:1<-#1$#2

:1/!1$.2'在程序中的较早位置插入该注释;请注意,此表示法将INTERCAL-72的日期推迟了很长时间,因此您需要使用现代的INTERCAL才能使其工作)。这仅仅是稍微长一点,即使你把安装进去了,如果你需要,或可安排,同时对分配变得更短.1,并.2不止一次。

不仅仅是计算此技巧起作用的命令。如果您需要存放一个变量两次,请不要这样:

DOSTASH.1DOSTASH.1

但是像这样:

DOSTASH.1+.1

(该+符号在概念上有意义的情况下适用于大多数命令。)


2

如果有必要,请对所有INTERCAL-72样式使用一个RESUME

如果需要编写等同于“ if”语句的内容,则使用INTERCAL-72代码的常规方法是NEXT两次,然后执行一次calculated RESUME。(在现代代码中,通常使用计算机COME FROM将是更好的选择,但是本文提示您假设您的代码更喜欢NEXT。)您几乎肯定要为第一个支付字节NEXT,因为它从“ if”的一个分支跳转到另一个分支。共享第二个NEXT也是不平凡的,除非您有很多“ if”语句在看到时都转到相同的位置#1。但是,RESUME可以在程序中的任何位置(因为控制将使其立即保留在任何位置)。

有两种方法可以解决此问题。如果您有很多“ if”语句,那么RESUME可能需要保证一个数字的行号,以便您的第二条NEXT语句可以尽可能短。如果可能的话,请尝试使其RESUME自然地出现在您的代码中(当然,这很困难,因为很少有人出现在代码的“正常流”中而不是被其NEXT接受);那么,唯一的成本就是行号。您必须为所有这些使用单个布尔变量NEXT;这里的普遍共识是使用.5,主要是因为它是标准库用于布尔返回值的变量。

另外,也可以使用标准库中未记录的(技术上记录不足,因为我在INTERCAL文档中放了一个提示)功能。由于a的中央位置RESUME非常有用,因此标准库在内部使用一个。INTERCAL中的行号是全局的(具有命名空间约定,但是如果您知道自己在做什么,可以将其断开),因此,NEXT如果需要,可以直接进入标准库的内部,尤其是可以NEXT到达中心RESUME位置。这在现有的INTERCAL代码中已经非常流行,以至于标准库替换往往必须实现它,以免破坏现有程序。

有问题的行是(从字面上看还是有效的,取决于实现):

(1001) DO RESUME .5

不使用它的主要原因是它的长行号。如果您需要做很多INTERCAL-72样式的if构造,最好使用您自己的方式为它提供较短的数字。

当然,您可以结合技巧,编写类似

(9)DO(1001)NEXT

仅略长于

(9)DORESUME.5

并具有布尔值变为#2和的好处#3(这很难阅读,但通常更易于生成)。实际上,甚至有必要添加额外的代码来处理,#0并且#1如果您会抱怨很多(但是COME FROM在这种情况下,除非您的要求很奇怪,否则在这种情况下,计算机可能会更好地工作)。


2

INTERCAL没有指定优先级,但是在模棱两可的优先级上也不会出错

像这样的表达

#1$#2~#3

是模棱两可的,可能意味着

'#1$#2'~#3

要么

#1$'#2~#3'

INTERCAL规范故意使其不清楚是什么意思,并且通常没有标准(尽管在较简单的情况下C-INTERCAL和CLC-INTERCAL会努力做到相互匹配)。也就是说,原件是不正确的;它是模棱两可的,我不建议在生产代码中使用它(但是,我不建议在生产代码中使用INTERCAL本身),但是它在大多数编译器中都有一定的意义。

换句话说,仅删除分组字符并希望您的程序仍然可以工作是值得的。大多数解释器将一致地解析任何给定的歧义表达式,因此对于每对分组字符,有二分之一的机会是不必要的;总共可以节省很多钱。(不幸的是,INTERCAL解析器倾向于充分混乱,没有人是完全知道什么是规则实际上,但它通常可以通过实验来确定。在最简单的情况下,运营商往往都具有相同的优先级,并具有一致的关联性。)


2

在C-INTERCAL中,请考虑使用 CREATE

CREATE语句允许您创建新的语法。这在打高尔夫球时特别有用,因为它使您可以给语句指定较短的名称。您还可以通过创建新的运算符来使用它来有效地“定义函数”(它的巨大优势是它使您可以在表达式中间调用函数)。

这里的安装成本相当高,但是如果您使用了很多结构,那么发明一个较短的语法可能是个好主意。

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.