简单的猫程序


84

最常见的标准任务之一(尤其是在展示深奥的编程语言时)是实现“猫程序”:读取所有STDIN并将其打印到STDOUT。尽管这是用Unix shell实用程序命名的,但cat它的功能当然不如真实功能强大,后者通常用于打印(和连接)从磁盘读取的多个文件。

任务

您应该编写一个完整的程序,该程序读取标准输入流的内容并将它们逐字写入标准输出流。当且仅当您的语言不支持标准输入和/或输出流(大多数语言都理解)时,您才可以使用这些术语来表示它们在您的语言中最接近的等效词(例如JavaScript promptalert)。这些是唯一允许的I / O形式,因为任何其他接口都将在很大程度上改变任务的性质,并使答案的可比性大大降低。

输出应该完全包含输入,而没有其他内容。此规则的唯一例外是您的语言解释器不断输出的内容,例如问候语,ANSI颜色代码或缩进​​,这些输出不能被禁止。这也适用于尾随换行符。如果输入不包含尾随换行符,则输出也不应包含任何换行符!(唯一的例外是,如果您的语言在执行后绝对总是打印尾随换行符。)

只要标准输出流包含预期的输出,就会忽略标准错误流的输出。特别是,这意味着您的程序在达到流(EOF)的末尾时可能会以错误终止,前提是该操作不会污染标准输出流。如果这样做,我建议您也将无错误的版本添加到您的答案中(以供参考)。

由于这是在每种语言中而不是在每种语言之间的挑战,因此有一些特定于语言的规则:

  • 如果您的语言完全有可能将标准输入流中的空字节与EOF区分开,则您的程序必须像其他任何字节一样支持空字节(也就是说,它们也必须写入标准输出流中)。
  • 如果您的语言完全有可能支持任意无限的输入流(即,如果您可以在输入中遇到EOF之前开始将字节打印到输出中),则在这种情况下,程序必须正常工作。作为示例,yes | tr -d \\n | ./my_cat应打印ys 的无限流。由您决定打印和刷新标准输出流的频率,但是必须确保它在有限的时间后发生,而不管该流如何(特别是,您不能等待特定字符,例如打印前换行)。

请在您的答案中添加一条注释,说明有关空字节,无限流和无关输出的确切行为。

附加规则

  • 这并不是要找到具有最短解决方案的语言(有些地方空程序会解决问题),而不仅仅是找到每种语言的最短解决方案。因此,没有答案将被标记为已接受。

  • 大多数语言的提交都将以适当的预先存在的编码(通常(但不一定)为UTF-8)以字节计分。

    某些语言(例如Folders)很难评分。如有疑问,请在Meta上提问。

  • 随意使用一种语言(或语言版本),即使它比此挑战要新。专门针对此挑战提交0字节答案的语言是公平的游戏,但并不是特别有趣。

    请注意,必须有一个解释器,以便可以测试提交。允许(甚至鼓励)自己为以前未实现的语言编写此解释器。

    还要注意,语言必须符合我们平时的标准编程语言

  • 如果您选择的语言是已经有答案的另一种(可能是更流行的)语言的琐碎变体(请考虑使用BASIC或SQL方言,Unix shell或琐碎的Brainfuck派生词,例如Headsecks或Unary),请考虑在现有答案中添加注释在其他语言中,相同或非常相似的解决方案也是最短的。

  • 除非之前已否决它们,否则所有标准的规则都适用,包括http://meta.codegolf.stackexchange.com/q/1061

附带说明一下,请不要在无聊的语言中打扰无聊(但有效)的答案;这些对于这个问题仍然很有用,因为它试图编译尽可能完整的目录。但是,主要是使用作者实际上必须努力打出代码的语言来提高答案的准确性。

目录

这篇文章底部的Stack Snippet会根据答案a)生成目录,a)作为每种语言最短解决方案的列表,b)作为整体排行榜。

为确保您的答案显示出来,请使用以下Markdown模板以标题开头。

## Language Name, N bytes

N您提交的文件大小在哪里。如果您提高了分数,则可以通过打败旧分数保持标题。例如:

## Ruby, <s>104</s> <s>101</s> 96 bytes

如果要在标头中包含多个数字(例如,因为您的分数是两个文件的总和,或者您想单独列出解释器标志罚分),请确保实际分数是标头中的最后一个数字:

## Perl, 43 + 2 (-p flag) = 45 bytes

您还可以将语言名称设置为链接,然后该链接将显示在代码段中:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


52
Bash,3个字节cat
TheDoctor 2015年

3
@TheDoctor我猜这会落入“不要使用完全满足需要的内置函数”规则。
圣保罗Ebermann

5
@PaŭloEbermann没有此类规则,并且不再接受相应的标准漏洞。(实际上,已经有一个sh使用的答案,cat其中也包含一个使用的更短解决方案dd。)
Martin Ender

1
如果仅使用输入和输出的标准方法:///,0 bytes
SparklePony同志

1
@SparklePony除了,您必须转义斜杠和反斜杠。
Martin Ender

Answers:


73

sed,0


sed程序完全符合此处的要求:

$ printf "abc\ndef" | sed ''
abc
def$ 

3
如果有人写yes | tr -d \\n | sed ''怎么办?
BenGoldberg '17

@BenGoldberg默认情况下,sed是按行工作的,因此在这种情况下,它将继续将yeses吸入一个模式缓冲区,直到用尽内存。我想做个警告...
Digital Trauma

POSIX要求模式空间的大小必须至少为8192字节,即IIRC。我知道GNU实现具有动态模式空间,仅受可用内存的限制,因此您在那方面相当安全。
Toby Speight,

59

Ziim222个 201 196 185 182字节

    ↓ ↓

 ↓ ↓     ↓
 ↗ ↗↙↔↘↖ ↖
 ↓↓⤡⤢  ⤢↙
↘ ↖⤡ ↖
  ↙
  ↕↘ ↑ ↙
→↘↖↑ ↙ ↑
→↖   ↑
→↖↘ ↙
  ↑↓↑

   ⤡

这可能无法在您的浏览器中正确显示,因此下面是代码图:

在此处输入图片说明

我想不出一种更简单的结构来解决Ziim中的问题,但是我敢肯定实际的代码还是可以使用的。

Ziim无法处理无限流,因为只能在程序末尾打印任何内容。

说明

由于Ziim具有一个非常独特的声明式控制流模型,因此命令式伪代码算法不会在这里删除它。取而代之的是,我将解释Ziim的基础知识,并以ASCII艺术形式介绍上述代码的整理结构(以类似的图形方式)。

Ziim中的控制流无处不在:每个未被另一个箭头指向的箭头都会初始化一个“线程”,该线程独立于其他箭头进行处理(不是真正地并行执行,但是不能保证它们以哪个顺序处理,除非您通过串联将其同步)。每个此类线程均包含一个以开头的二进制数字列表{0}。现在,代码中的每个箭头都是某种命令,具有一个或两个输入和一个或两个输出。确切的命令取决于从哪个方向指向多少箭头。

这是命令列表,其中m -> n指示该命令接受m输入并产生n输出。

  • 1 -> 1no-op:仅重定向线程。
  • 1 -> 1invert:否定线程中的每个位(并重定向)。
  • 1 -> 1读取:将线程的值替换为STDIN 的下一位,如果我们已经达到EOF,则替换为空列表。
  • 2 -> 1并置:这是同步线程的唯一方法。当一根线碰到箭头的一侧时,它将被挂起,直到另一根线碰到另一侧。到那时,它们将被连接到一个线程中并继续执行。
  • 2 -> 1label:这是联接不同执行路径的唯一方法。这只是一个无操作,有两个可能的输入。因此,通过任一路由进入“标签”的线程将被简单地重定向到同一方向。
  • 1 -> 2split:采用一个线程,并向不同方向发送两个副本。
  • 1 -> 1,是零?:消耗线程的第一位,并根据该位是0还是1沿两个方向之一发送线程。
  • 1 -> 1,是空吗?:消耗整个列表(即用一个空列表替换它),并根据列表是否已经为空而向两个方向之一发送线程。

因此,考虑到这一点,我们可以找出一个总体策略。使用连接,我们希望将新的位重复添加到代表整个输入的字符串中。我们可以简单地通过将连接的输出循环回其输入之一来执行此操作(然后通过{0}使用isEmpty?清除a ,将其初始化为一个空列表)。问题是我们如何终止这一过程。

除了附加当前位之外,我们还将在前面添加 0或1,以指示是否已达到EOF。如果我们通过isZero发送字符串,它将再次删除该位,但是让我们区分流的末尾,在这种情况下,我们只需让线程离开网格的边缘即可(这会使Ziim将线程的内容打印到STDOUT并终止程序) 。

可以通过使用isEmpty确定是否达到EOF 输入的副本上。

这是我承诺的图表:

              +----------------------------+   {0} --> isEmpty --> label <--+
              |                            |                    n    |      |
              v                            |                         v      |
    {0} --> label --> read --> split --> split ------------------> concat   |
                                 |                                   |      |
                           n     v     y                             |      |
 inv --> label --> concat <-- isEmpty --> concat <-- label <-- {0}   |      |
  ^        ^          |                     |          ^             |      |
  |        |          v                     v          |             |      |
 {0}       +------- split ---> label <--- split -------+             |      |
                                 |                                   |      |
                                 +-------------> concat <------------+      |
                                                   |                        |
                                              y    v                        |
                         print and terminate <-- isZero --------------------+

有关从何处开始阅读的一些注意事项:

  • {0}在左上角是开始输入回路的初始触发。
  • {0}朝右上角立刻清零为空列表中的代表初始的字符串,我们将逐步与输入填写。
  • 另外两个{0}s被馈入一个“生产者”循环(一个倒置,一个不倒),从而为我们提供了无限多的0s和1s,我们需要在它们之前添加字符串。

29
在没有大脑爆炸成百万个小块组织的情况下,甚至如何编写这样的程序。
Ashwin Gupta 2015年

40

六边形,6字节

以前是3个字节(请参见下文),但是自该语言的最新更新以来,该版本不再起作用。由于我从未刻意介绍该版本所利用的错误,因此我决定不计算它。


一个无错误的解决方案(即与固定解释器一起使用的解决方案)变得更加棘手。我在将其压缩到2x2网格时遇到了一些麻烦,但是我现在找到了一个解决方案,尽管我需要完整的7个字节

<)@,;.(

展开后,我们得到:

在此处输入图片说明

由于初始存储边为0,因此<无条件将指令指针偏转到东北对角线,并在该对角线处缠绕到灰色路径。这.是无人值守。现在,读取一个字节,对其进行)递增,以使有效字节(包括空字节)为正,EOF为0。

因此,在EOF上,IP会绕到红色路径,从而@终止程序。但是,如果我们仍然读取一个字节,则IP换行为绿色路径,而是在(将其;打印到STDOUT 之前将边沿递减为原始值。IP现在无条件地返回灰色路径,重复此过程。


在为Truth Machine答案编写了蛮力脚本之后,我将其设置为也为cat程序找到了无错误的6字节解决方案。令人惊讶的是,它确实找到了一个-是的,在所有可能的6字节Hexagony程序中只是一个解决方案。在从真理机器获得50个解决方案之后,这真是令人惊讶。这是代码:

~/;,@~

展开:

在此处输入图片说明

使用~(一元否定)代替()有趣的是,因为a)它在零上是空操作,b)交换分支的侧面,c)在某些代码中,单个代码~可能会被使用两次来撤销自身的操作。所以这是怎么回事:

我们第一次通过(紫色路径)~是没有操作的。将/IP反射到西北对角线。灰色路径现在读取一个字符,并将其字符代码乘以-1。这会将EOF(-1)转换为真实(正)值,并将所有有效字符转换为伪(非正)值。对于EOF,IP使用红色路径,并且代码终止。在有效字符的情况下,IP采用绿色路径,在该路径上~撤消否定并;打印字符。重复。


最后,这是3字节版本,该版本曾经在原始版本的Hexagony解释器中工作。

,;&

就像迷宫的答案一样,如果输入流是有限的,则以错误终止。

展开代码后,它对应于以下十六进制网格:

在此处输入图片说明

.是空操作。执行从紫色路径开始。

,读取一个字节,;写入一个字节。然后,执行继续在鲑鱼(ish?)路径上进行。我们需要将&当前内存边沿重置为零,以便当IP击中第二行末尾的角时,它跳回到紫色行。一旦,打到EOF,它将返回-1,从而在;尝试打印它时导致错误。


Timwi的惊人的HexagonyColorer生成的图。


2
6字节版本非常非常聪明。蛮力棒极了。
ETHproductions 2016年

您是否有指向蛮力的链接?
MD XF

@MDXF我没有保留各种版本,但这始终是对该Ruby脚本的一些修改。
Martin Ender '18

36

TeaScript,0个字节

TeaScript是一种精简的高尔夫语言,已编译为JavaScript


在最近的更新中,输入被隐式添加为第一个属性。

在线尝试


或者,1个字节

x

x包含TeaScript中的输入。输出是隐式的


我正要发布此内容:)
Kritixi Lithos

5
哈哈,我以为“替代地”是一种语言名称...
Quelklef '18

28

Brian&Chuck,44个字节

#{<{,+?+}_+{-?>}<?
_}>?>+<<<{>?_}>>.<+<+{<{?

我最初是为了创建一种似乎无法使用的编程语言而创建这种语言的。事实证明,这是解决高尔夫中一些简单问题的很好的练习。

基础知识:这两行中的每一行都定义了一个类似Brainfuck的程序,该程序在另一个程序的源代码上运行-第一个程序称为Brian,第二个程序称为Chuck。只有Brian可以阅读,只有Chuck可以写作。代替Brainfuck的循环,您可以?将控制权传递给其他程序(指令指针和磁带头的角色也发生变化)。Brainfuck的附加功能是{},它在磁带上扫描第一个非零单元(或左端)。同样,_用空字节替换。

虽然我认为这不是最佳选择,但我对这种解决方案感到非常满意。我的第一个尝试是84字节,在与Sp3000进行了几次高尔夫练习之后(并从他的尝试中得到了一些启发),我设法将其每次缓慢地减小到44个字节。特别是这个绝妙的+}+把戏是他的主意(见下文)。

说明

输入被读到Chuck磁带上的第一个单元中,然后小心地复制到Brian磁带的末尾,在那里进行打印。通过将其复制到末尾,我们可以在将前一个字符设置为零时节省字节。

#只是一个占位符,因为开关控制不执行单元,我们接通。{<{确保磁带头在Chuck的第一个单元上。,从STDIN读取字节,或者-1如果我们命中EOF。因此,我们使用+来增加该值,以使EOF的值为零,否则为非零。

让我们假设目前我们还没有进入EOF。因此该单元为正,?并将控制权切换到Chuck。}>将磁带头(在Brian上)移至+_然后?将控制权交还给Brian。

{-现在减少Chuck上的第一个单元。如果还不为零,则使用再次将控制权传递给Chuck ?。这次}>将磁带头移到最后一个非零单元格右边的两个单元格上的Brian上。最初是在这里:

#{<{,+?+}_+{-?>}<?__
                   ^

但是稍后,我们已经在那里有了一些角色。例如,如果我们已经阅读并打印过abc,那么它将看起来像这样:

#{<{,+?+}_+{-?>}<?11a11b11c__
                            ^

1s为实际1字节(我们会看到这是后话)。

此单元格始终为零,因此这次? 不会更改控制。>向右移动另一个单元格并+递增该单元格。这就是为什么输入中的第一个字符在右边的三个单元格中结束的原因?(每个随后的右边三个单元格都结束了)。

<<<移回该列表中的最后一个字符(?如果是第一个字符,{>则返回),并返回+Brian磁带上的,以重复循环,从而将输入单元格缓慢转移到Brian磁带的末尾。

一旦该输入单元为空,?则以{-后将不再切换控制。然后>}<将Chuck上的磁带头移至,_并切换控制,以便执行Chuck的下半部分。

}>>移到我们现在已经写过的布莱恩磁带末尾的单元格,这是我们从STDIN读取的字节,因此我们将其打印回来.。为了}过去我们需要关闭的两个空字节的差距在磁带上这个新的角色运行,因此我们将它们递增到1<+<+(这就是为什么有实际的字符间的1个字节的最后磁带上)。最后,{<{移回Brian录音带的开头,并?从头开始一切。

您可能想知道如果我们读取的字符为空字节会发生什么情况。在那种情况下,新写入的单元格本身将为零,但是由于它位于Brian磁带的末端,并且我们不在乎末端在哪里,我们可以简单地忽略它。这意味着如果输入为ab\0de,那么Brian的磁带实际上将最终看起来像:

#{<{,+?+}_+{-?>}<?11a11b1111d11e

最终,一旦我们击中EOF,?Brian的录音带上的第一个便是空手道。至此,我们终止了程序。天真的解决方案是将移动到Chuck的磁带结尾并切换控制,以使程序终止:>}>}<?。这就是Sp3000真正聪明的想法,它节省了三个字节:

+将Chuck的第一个单元格变为1。这意味着}有一个起点,并_在Chuck的录音带中间找到。除了跳过它,我们也只需将其变为1with +来缩小差距。现在,让我们看看Brian其余代码与这个经过修改的Chuck的关系。

{像往常一样返回到Chuck的第一个单元,然后-将其返回为空字节。那意味着那?是没有操作的。但是现在>}<,通常将磁带头移到Chuck磁带的中间,然后立即移到它的上方,直到Chuck磁带的末尾,?然后将控制权交给Chuck,从而终止代码。事情解决了就很好了... :)


25

Haskell,16个字节

main=interact id

interact读取输入,将其传递给作为其参数的给定函数,并打印接收到的结果。id是标识函数,即它不变地返回其输入。感谢Haskell的懒惰interact可以使用无限的输入。



23

函数,16字节

╔═╗
╚╤╝

(使用BOM编码为UTF-16)

说明

该框返回STDIN的内容。松端输出它。


19

摩托罗拉MC14500B机器代码,1.5个字节

用十六进制写成:

18F

用二进制写成:

0001 1000 1111

说明

1   Read from I/O pin
8   Output to I/O pin
F   Loop back to start

每个操作码均为4位。


1
-1无屏幕截图,示例或“在线试用”链接:P(jk)
MD XF

2
+1。我可以想到的进一步优化此方法的唯一方法是,将输入引脚焊接到输出引脚,然后将芯片从其插槽中取出:P
Wossname

16

莫宁顿月牙,41字节

Take Northern Line to Mornington Crescent

我不知道Mornington Crescent是否可以处理空字节,并且在程序启动之前读取所有输入,因为这是该语言的本质。


15

Brainfuck,5个字节

,[.,]

等效于伪代码:

x = getchar()
while x != EOF:
    putchar(x)
    x = getchar()

这处理无限流,但将空字节视为EOF。BF是否可以正确处理空字节因实现而异,但这是最常用的方法。


1
该死!你把我击败了5分钟!
kirbyfan64sos

如果第一个字符为NULL,则此字符将无法正确运行。所以应该是+[,.]对的吗?
谢尔瓦库2015年

6
@Shel这使用0x00作为EOF字节。如果第一个字符是EOF,则不打印任何内容,按预期方式工作。
Mego

2
哦,“伪代码”,哦,这显然只是不带括号,不带分号的C:P
MD XF 2015年

14

迷宫,2字节

,.

如果流是有限的,那么它将以错误终止,但是由错误产生的所有输出都将到达STDERR,因此标准输出流是正确的。

如在Brainfuck中一样,,读取一个字节(将其推入Labyrinth的主堆栈)并.写入一个字节(将其从Labyrinth的主堆栈中弹出)。

此循环的原因是,这两个,.是“死角”中由源代码所表示的(非常简单)的迷宫,以使得指令指针简单地转身当场并移回到其他命令。

当我们命中EOF时,会,推入-1.抛出错误,因为-1这不是有效的字符代码。将来这实际上可能会改变,但是我还没有决定。


作为参考,我们可以在6个字节内无错误地解决此问题,如下所示

,)@
.(

在这里,)我们读取的字节增加,这0等于EOF,否则为正数。如果值为0,则IP继续前进,点击@会终止程序。如果该值为正,则IP将向右转,(从而将栈顶递减回其原始值。IP现在处在拐角处,将继续保持右转,用进行打印,用.读取新的字节.,然后)再次击中分叉。


13

C,40个字节

main(i){while(i=~getchar())putchar(~i);}

main(){while(255-putchar(getchar()));}要短几个字节。
Alchymist 2015年

1
可悲的是,它在0xFF字节上过早退出,并在不包含输入的情况下将0xFF字节附加到输入中。
丹尼斯

接下来是36个字节:main(){for(;; putchar(getchar()));};
Johan du Toit

@ user2943932当它达到EOF时,getchar返回-1,因此您的代码将在(有限)输入之后输出0xFF字节的无限流。
丹尼斯

12

> <>,7个字节

i:0(?;o

在这里尝试。说明:

i:0(?;o
i        Take a character from input, pushing -1 if the input is empty
 :0(     Check if the input is less than 0, pushing 1 if true, 0 if false
    ?;   Pop a value of the top of the stack, ending the program if the value is non-zero
      o  Otherwise, output then loop around to the left and repeat

如果你希望它继续下去,直到你给它更多的投入,替换;!


哇,我希望发布> <>答案...:P(+1!)
El'endia Starman

1
io(2个字节)的功能相同,但是会崩溃并something smells fishy...在执行结束时写入STDERR,这是允许的。
林恩(Lynn)2015年

@Mauris在线解释器仅输出空字节,而不以错误结尾。
DanTheMan 2015年

11

X86汇编,70字节

拆卸objdump

00000000 <.data>:
   0:   66 83 ec 01             sub    sp,0x1
   4:   66 b8 03 00             mov    ax,0x3
   8:   00 00                   add    BYTE PTR [eax],al
   a:   66 31 db                xor    bx,bx
   d:   66 67 8d 4c 24          lea    cx,[si+0x24]
  12:   ff 66 ba                jmp    DWORD PTR [esi-0x46]
  15:   01 00                   add    DWORD PTR [eax],eax
  17:   00 00                   add    BYTE PTR [eax],al
  19:   cd 80                   int    0x80
  1b:   66 48                   dec    ax
  1d:   78 1c                   js     0x3b
  1f:   66 b8 04 00             mov    ax,0x4
  23:   00 00                   add    BYTE PTR [eax],al
  25:   66 bb 01 00             mov    bx,0x1
  29:   00 00                   add    BYTE PTR [eax],al
  2b:   66 67 8d 4c 24          lea    cx,[si+0x24]
  30:   ff 66 ba                jmp    DWORD PTR [esi-0x46]
  33:   01 00                   add    DWORD PTR [eax],eax
  35:   00 00                   add    BYTE PTR [eax],al
  37:   cd 80                   int    0x80
  39:   eb c9                   jmp    0x4
  3b:   66 b8 01 00             mov    ax,0x1
  3f:   00 00                   add    BYTE PTR [eax],al
  41:   66 31 db                xor    bx,bx
  44:   cd 80                   int    0x80

来源:

sub esp, 1
t:
mov eax,3
xor ebx,ebx
lea ecx,[esp-1]
mov edx,1
int 0x80
dec eax
js e
mov eax,4
mov ebx,1
lea ecx,[esp-1]
mov edx,1
int 0x80
jmp t
e:
mov eax,1
xor ebx,ebx
int 0x80

1
因此,objdump将其反汇编为32位代码,而您似乎已将其编译为16位。相信什么?既然您使用int 0x80,我想它是针对Linux的,但是为什么要编译为16位呢?
Ruslan

@Ruslan我什至没有意识到它是用16位编译的……
kirbyfan64sos 2015年

11

通用Lambda,1个字节

!

通用Lambda程序是以二进制形式对lambda项进行编码的,将其切成8位的块,用任何位填充不完整的块,转换为字节流。

这些位将转换为lambda项,如下所示:

  • 00 引入了lambda抽象。
  • 01 表示两个后续术语的应用。
  • 111..10Ñ比特的重复1,指的可变Ñ个父拉姆达; 即它是一元的De Bruijn索引

通过此转换,0010是身份函数λa.a,这意味着该格式的任何单字节程序0010xxxx都是cat程序。


1
但是,!0x21不是0x4_
wchargin

固定。--------
林恩(Lynn)

10

PowerShell,88 41 30字节

$input;write-host(read-host)-n

编辑-忘记了我可以使用$input自动变量进行管道输入 ...编辑2-不需要测试是否存在$input

是的,所以……PowerShell中的STDIN很……很奇怪。假设我们需要接受所有类型的STDIN的输入,这可能是此目录的一种答案,而且我敢肯定还有其他答案。1个

但是,PowerShell中的管道输入无法正常运行。由于PowerShell中的管道传递是语言的功能,而不是环境/ shell的功能(而且PowerShell实际上并非仅是一种语言),因此对于行为有一些怪癖。

对于初学者,并且与该条目最相关,该管道不会立即(大部分时间)进行评估。也就是说,如果我们有command1 | command2 | command3我们的外壳,command2不会采取输入或直到开始处理command1结束... 除非你封装你command1ForEach-Object...这是不同的ForEach(尽管ForEach是的别名ForEach-Object,但这是一个单独的问题,因为我说的ForEach是声明而不是别名)

这意味着类似yes | .\simple-cat-program.ps1(即使yes实际上并不存在,但无论如何)之类的东西将无法工作,因为yes它将永远无法完成。如果我们能够做到ForEach-Object -InputObject(yes) | .\simple-cat-program.ps1这一点,那么(理论上)应该可行。

在Microsoft上了解ForEach和ForEach-Object “嘿,脚本专家!” 博客。

因此,所有这些段落都在解释为什么if($input){$input}存在。如果存在管道输入,我们将采用一个特别自动创建的输入参数,测试它是否存在,如果存在,则输出它。

然后,我们(read-host)通过实质上是一个单独的STDIN流从用户那里获取输入,并write-host使用-n标记(的缩写-NoNewLine)将其返回。请注意,这不支持任意长度的输入,因为read-host只有输入换行符后才能完成输入(技术上是在用户按下“ Enter”键时,但功能上等效)。

ew

1但是还有其他选择:

例如,如果我们关心的只是管道输入,而我们并不需要一个完整的程序,你可以不喜欢| $_它只会输出无论是输入。(总的来说,这有点多余,因为PowerShell在计算后会隐式输出“遗留”的东西,但这是一个问题。)

如果我们只关注交互式用户输入,则可以使用just write-host(read-host)-n

此外,此功能具有接受命令行输入的怪异功能,例如.\simple-cat-program.ps1 "test"将填充(然后输出)$a变量。


不要忘记您的内置别名!
乍得·巴克斯特

10

Cubix6 5字节

现在处理空字节!

@_i?o

Cubix是二维的基于堆栈的esolang。Cubix与其他2D lang的不同之处在于,源代码环绕在多维数据集的外部。

在线测试!注意:迭代之间有50毫秒的延迟。

说明

解释器要做的第一件事是找出代码将适合的最小立方体。在这种情况下,边长为1。然后用无操作填充代码,.直到所有六个边都填满。在处理之前删除空格,因此此代码与上面的代码相同:

  @
_ i ? o
  .

现在运行代码。IP(指令指针)从最左边开始指向东方。

IP遇到的第一个字符是_,这是一面镜子,可以将IP面向北或向南旋转。它目前正朝东,所以什么也没做。接下来是i,它从STDIN输入一个字节。?如果最上面的项为负,则将IP左移;如果为正,则将IP右移。这里有三种可能的路径:

  • 如果输入的字节为-1(EOF),则IP向左转并点击@,从而终止程序。
  • 如果输入的字节为0(空字节),则IP会直接继续,输出带有的字节o
  • 否则,IP会右转,穿过底面并撞到镜子_。它将转过来,将其发送回?,再次将其转右并输出字节。

我认为这个程序是最佳的。在Cubix可以处理空字节(EOF为0,而不是-1)之前,此程序适用于除空字节以外的所有内容:

.i!@o

我编写了一个蛮力工具来查找所有5字节的cat程序。尽管大约需要5分钟才能完成,但最新版本已找到5个程序:

@_i?o   (works as expected)
@i?o_   (works in exactly the same way as the above)
iW?@o   (works as expected)
?i^o@   (false positive; prints U+FFFF forever on empty input)
?iWo@   (works as expected)

请不要一次编辑十几个帖子。您正在充斥头版。一次3个不是问题,但是如果您必须做的更多,请每12个小时左右进行小批量修改。
Martin Ender

@MartinEnder对不起,我注意到了。以后我会把它们隔开。
ETHproductions 2016年

9

Vitsy,2个字节

Z Z

z获取所有输入堆栈并将其推入活动程序堆栈。Z将所有活动堆栈输出到STDOUT。

替代方法:

我\ il \ O
I \重复下一个字符作为输入堆栈的长度。
  i从输入中抓取一个项目。
   l \重复下一个字符作为当前活动程序堆栈的长度。
     O将堆栈的顶部项目输出为字符。

2
^ _ ^反正+1!:)
El'endia Starman 2015年

可惜票,我的最爱!
艾迪生·克伦普

为什么要下票?这似乎是一个完全有效的条目
康纳·奥布莱恩

1
由所有规范有效。
艾迪生·克伦普

9

MarioLANG,11个字节

,<
."
>!
=#

我不确定这是否是最佳选择,但这是我发现的最短的选择。

这支持无限流,并且在到达EOF时将以错误终止(至少Ruby参考实现是这样)。

还有另一个版本可以将马里奥变成可以双跳的忍者:

,<
.^
>^
==

无论哪种情况,Mario都会从左列开始下降,在其中,读取一个字节并.写入一个字节(这会在EOF上引发错误,因为,未返回有效字符)。>确保Mario向右走(=这只是他可以继续前进的地面)。然后他向上移动,或者通过两次跳高^或通过电梯("#一对)<向上移动,然后告诉他返回左栏。


8

rs,0个字节


说真的 如果给定脚本完全为空,rs只会打印得到的所有内容。


7

GolfScript,3个字节

:n;

空程序将回显标准输入。该语言可能无法处理无限流。但是,它会附加一个换行符,如@Dennis所述。通过将整个堆栈包装在一个数组中并调用puts,定义为print n print,其中n是换行符,来实现此目的。但是,我们可以将其重新定义n为STDIN,然后清空堆栈,这正是:n;它的作用。


7

交通繁忙的半碎车,9 + 3 = 12字节

#<
o^<
 v

重型交通(HBCHT)中的半碎车将输入作为命令行参数,因此像

py -3 hbcht cat.hbc -s "candy corn"

请注意,+ 3用于-s标志,该标志输出为字符。另外,HBCHT似乎不处理NUL,因为所有零都从输出中删除(例如97 0 98,以两个char的形式输出ab)。

说明

在HBCHT中,您的汽车始于,o而您的目标是退出#^>v<指导汽车的运动,同时修改类似BF的胶带(^>v<转换为+>-<)。但是,正如语言名称所暗示的那样,您的汽车只能向右转–完全避免忽略任何向左转的尝试(包括其记忆效应)。请注意,这仅用于转弯–您的汽车完全能够向前/向后行驶。

关于HBCHT的其他有趣部分是您的汽车的初始方向是随机的,并且网格是环形的。因此,我们只需要汽车进入出口,而无需为所有四个初始方向修改胶带:

  • 上下都很简单,直接前往出口。

  • 对于左侧,我们包装并执行<并用递增^。我们不能在下一个转弯,<所以我们用包裹和递减,而忽略v了先前的增量。由于我们现在要向下移动,因此我们可以在处右转<并退出,将指针移动两次,并且不修改任何单元格值。

  • 对于右边,我们做与左边相同的事情,但是^由于我们不能向左拐所以跳过第一件事。


编辑:事实证明,HBBCT解释器确实允许您通过命令行标志仅执行单个路径,例如

py -3 hbcht -d left cat.hbc

但是,对于该特定问题,标志不仅太昂贵(至少需要5个字节" -d u"),而且似乎所有路径仍需要能够使其到达出口才能执行代码。


7

Minkolang,5个字节

od?.O

在这里尝试。

说明

o从输入中读取一个字符,并将其ASCII码压入堆栈(0如果输入为空)。d然后复制堆栈的顶部(刚刚读入的字符)。?是有条件的蹦床,它会跳到栈顶not的下一条指令0。如果输入为空,则.不会跳转并且程序停止。否则,O将堆栈的顶部作为字符输出。Minkolang的环形性质意味着它一直循环到起点。


2
!你打败我的语言!无法接受!+1
艾迪生·克兰普

7

通话 133字节

at

INTERCALL IS A ANTIGOLFING LANGUAGE
SO THIS HEADER IS HERE TO PREVENT GOLFING IN INTERCALL
THE PROGRAM STARTS HERE:
READ
PRINT
GOTO I

看来有人真的是在纯粹地反高尔夫语言打高尔夫... 133-116 = 17
Outgolfer的Erik

@EʀɪᴋᴛʜᴇGᴏʟғᴇʀ因为cat程序非常简单,所以并非所有程序都如此... codegolf.stackexchange.com/a/82748/53745
TuxCrafting

制作该语言的人打算使用罗马数字,但如果是这种情况500(不确定),那会是PRINT D吧?(不包括标头)
主场长埃里克(Erik the Outgolfer)

@EʀɪᴋᴛʜᴇGᴏʟғᴇʀ不,INTERCALL只能打印ASCII字符并使用堆栈,例如,要打印具有ascii值20的字符,代码为PUSH XX<newline>PRINTPUSH XX AND PRINT。哦,我是INTERCALL的创建者
TuxCrafting

7

V,0字节

在线尝试!

V的“记忆”概念只是一个巨大的2D字符数组。在运行任何程序之前,所有输入都将加载到此数组中(称为“缓冲区”)。然后,在任何程序结束时,将打印缓冲区中的所有文本。

换句话说,空程序猫程序。


6

雪人1.0.2,15个字符

(:vGsP10wRsp;bD

采取直接从雪人的examples目录。读取行,打印行,读取行,打印行...

注意,由于实现细节,当STDIN为空时,vg将返回与空行相同的内容。因此,一旦关闭STDIN,它将无限循环地重复打印换行符。这可能会在将来的版本中修复。

代码说明:

(        // set two variables (a and f) to active—this is all we need
:...;bD  // a "do-loop" which continues looping as long as its "return value"
         // is truthy
  vGsP   // read a line, print the line
  10wRsp // print a newline—"print" is called in nonconsuming mode; therefore,
         // that same newline will actually end up being the "return value" from
         // the do-loop, causing it to loop infinitely


5

裂变,4字节

R?J!

当您在语言自己的存储库中击败示例程序时,这不是很好吗?:)供参考,它具有7字节的解决方案

R?J0;0!

说明

因此,R从正确的原子开始控制流。?从STDIN读取一个字符到原子的质量中。只要我们正在读取字符,能量就保持为零,因此Jump是无操作的并且可以!打印字符。原子循环回到起点(R现在是无操作),并重复整个过程。

当我们按下EOF时,?会将原子的能量设置为1,因此Jump现在将跳过打印命令。但是当原子返回EOF ? 之后命中原子时,它将销毁该原子,从而终止程序。

(该语言作者的解决方案使用显式;终止程序,0否则将使用两个-portal 跳过该程序。)


5

切碎的 20字节

e )
"
 r )
 s )
 "
"

巧妙地证明,在Shtriped中,几乎所有可打印的ASCII字符串都是有效的标识符。

这个怎么运作:

e )   \ declares a variable named )
"     \ defines a function with 0 arguments named "
 r )  \ gets a line of string input, saving it to )
 s )  \ prints ) as a string
 "    \ recursively calls ", effectively looping forever
"     \ calls " from the main scope to get things started

没有检测EOF的真正方法,因此,它会像Python answer一样永远循环。

您可以很容易地在给出空行(30个字节)时使其停止:

e )
"
 r )
 d ) \ tries to decrement ), if it was the empty string, aka 0, it can't, so 0 is returned all the way up
 i ) \ increment ) to put it back to normal after possibly decrementing
 s )
 "
"

请注意,Shappeded I / O仅支持可打印的ASCII,制表符,换行符,回车,垂直制表符和换页符(总共100个字符)。这是因为在内部,字符串表示为非负的任意精度整数,并且必须有一个有限的字符字母才能编码所有字符串。

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.