一个“作弊”的奎因


56

长期潜伏,第一次海报。所以去。

quine的Wikipedia页面上,它说:“如果查看自己的源代码,quine被认为是“欺骗”。您的任务是使这些“作弊的家伙”之一读取自己的源代码。

这是,因此以字节为单位的每种语言中的最短代码为准。这意味着5字节的Pyth脚本不会胜过21字节的Python脚本-但15字节的Python脚本会胜过。

您必须使用文件I / O来读取源代码,因此以下来自官方Wikipedia页面的JavaScript代码无效:

function a() {
    document.write(a, "a()");
}
a()

它必须访问磁盘上文件的源代码。

不允许您指定文件名。您必须使其检测文件名本身。

大家都清楚吗?走!


1
原始文件中不存在尾随换行符吗?
isaacg 2015年

3
@isaacg恕我直言,这不是代码,因为它不是源代码。
mınxomaτ

3
您应该声明一个要求,即它确定实际的文件名,而不是为源位置假设一个硬编码的字符串。
feersum

3
我同意@feersum的观点,即要求使用特定的文件名会使这种挑战变得微不足道。
mınxomaτ

1
我们是否可以假定(对于已编译的语言)源代码位于同一文件夹中(即,我们可以仅在arg [0]上添加“ .cpp”或“ .hs”以获取源代码)。
HEGX64

Answers:


60

Zsh,4个字节

<$0

Z shell具有内置的猫功能。第四个字符是换行符。

在线尝试!

代码不以任何方式取决于文件名。即使文件名包含特殊字符(例如空格或换行符),它也可以工作。

测试运行

$ cat "my quine.sh"
<$0
$ zsh "my quine.sh" 
<$0
$ diff -s <(zsh "my quine.sh") <(cat "my quine.sh")
Files /dev/fd/63 and /dev/fd/62 are identical

28
feline functionalities:)
theB 2015年


32

UNIX可执行加载程序,10字节

#!/bin/cat

如果您不关心标准错误的垃圾邮件,可以将其缩短一个字节:

#!/bin/dd

7
我喜欢这个。但是,不确定是否将其视为“语言”。
凯文

也许有点作弊,但是您不能重命名bin文件夹和cat程序来缩短路径吗?
James Webster

3
我不建议你这样做。我建议您可以
James Webster

3
@Kevin“语言”(即解释器)为cat。我猜想如果您想非常具体,cat程序会自行打印,并且与现有的每种文件格式兼容:)
l0b0

1
@JamesWebster sudo install /bin/cat /c。您知道,以防万一/bin不在根文件系统上。必须cat在单用户中拥有该功能……
Blacklight闪耀



12

Perl,15个字节

open 0;print<0>

由于@ ThisSuitIsBlackNot而节省了3个字节!


2
您可以使用open 0;print<0>
ThisSuitIsBlackNot15年

@ThisSuitIsBlackNot我不确定这样做有更短的方法,但是我无法一辈子都完成……使用0假设$0呢?
唐·黑斯廷斯

3
是的 请参阅perldoc -f open:“作为一种捷径,一个单参数调用从与文件句柄同名的全局标量变量中获取文件名:$ARTICLE = 100; open(ARTICLE) or die "Can't find article $ARTICLE: $!\n";
ThisSuitIsBlackNot15年

11

Perl 6,20位元组

print slurp $?FILE

我使用Perl 6的时间很长,因此我不确定是否有任何技巧可以使它更短。


2
您可以删除第二个空格吗?
伊芙

3
@Eevee nope,它很生气
热键

11

osascript(命令行中的AppleScript),40 33 32字节

(阅读我的路径)第1段

在名为的文件中执行with osascript a

获取文件的第一段(行),并使用尾随换行符将其打印到STDOUT,因此在代码中换行。


1
请参阅我对OP的编辑
TheInitializer 2015年

正在努力使其正常工作。
艾迪生·克伦普

read path to me似乎为我工作。El Cap。
Digital Trauma 2015年

没看到这个,但是这就是我最终完成的方式。:P谢谢,@DigitalTrauma。编辑:尾随新行必须要考虑的,所以添加换行,并使用段落1
艾迪克伦普

11

Python 2,32字节

文件末尾有换行符。

print open(__file__).readline()

Python 3,33个字节

文件末尾有换行符。

print(open(__file__).readline())

感谢feersum解决了问题并提供了帮助__file__Loovjo为Python 2解决方案提供了一种新方法,该方法节省了17个字节,而Skyler为该解决方案节省了另一个字节并可以在Python 2和3中使用(正在print作为Python中的函数使用) 3)!

的文档链接 readline


这也会在python3中节省2个字节,因为您可以丢弃该end参数。
斯凯勒

@Skyler你是完全正确的。
Celeo,2015年

这在需要parens的Python 3中如何工作print
门把手

Python 3后应print(open(__file__).readline())跟换行符。
斯凯勒

您的Python 3示例使用Python 2而不是Python 3
TheInitializer


10

Python 2.7,30个字节

print open(__file__).read(29)

编辑:为了清楚起见,上面的代码应该在第30个字节的末尾有一个换行符。我对markdown不够熟悉,无法弄清楚如何在代码块中显示它。

我在这里使用与C提交中相同的技巧。这将读取整个源文件(不包括尾随换行符),以说明print将附加到输出的其他换行符。


尾随换行符是否会遇到与其他提交相同的问题?
2015年

不会。应该有一个结尾的换行符,该换行符在源代码中占第30个字节,但我无法在代码块中显示它。我的提交之所以有效,是因为它读取了源代码的前29个字节,从而print不会产生多余的换行符。
xsot 2015年

4
那不是逗号。它追加一个空格而不是换行符。
xsot 2015年

2
可以使用␤来表示语义上重要的换行符
Eevee

9

Java,212 196字节(具有可疑硬编码规则的171字节)

感谢@Cruncher将它缩短了〜15个字节!

我毫不怀疑这可以打高尔夫球。

import java.nio.file.*;class A{public static void main(String[]a){new A();}A(){try{System.out.print(new String(Files.readAllBytes(Paths.get(getClass().getName()+".java"))));}catch(Exception e){}}}

或者,使用静态方法(以及类的名称)的另一种方法,我得到171个字节。不过,我不确定这是否符合硬编码要求。

import java.nio.file.*;class A{public static void main(String[]a)throws Exception{System.out.print(new String(Files.readAllBytes(Paths.get(A.class.getName()+".java"))));}}

使用构造函数通过非静态方法获取类名称。使用静态方法(A.class.getName()确实很难编码,因此我使用了“正确”的方式。使用A.class.getName(),此代码缩短为171个字节。

可读版本:

使用构造函数和this.getClass()

import java.nio.file.*;
class A{
    public static void main(String[]a) {
        new A();
    }
    A(){
        try{
            System.out.print(
                new String(
                Files.readAllBytes(
                Paths.get(
                getClass().getName()+".java"))));
        }
        catch(Exception e) {}
    }
}

使用静态方法A.class.getName()

import java.nio.file.*;
class A {
    public static void main(String[] a) throws Exception {
        System.out.print(
             new String(
                  Files.readAllBytes(
                       Paths.get(
                            A.class.getName()+".java"))));
    }
}

一次抓取文件的所有字节并将其输出到STDOUT。非常简单。


为什么只是不使用A.class.getName()
Fabio F.

3
这是CodeGolf而不是CodeReview!;)
Fabio F.

1
@FabioF。是的,但我认为这是硬编码的文件名,这违反了规则。关键是,如果您更改文件名,则必须更改类的名称(显然),但是还必须更改此行,就像硬编码的文件名一样。
Cruncher

1
您不能在构造函数内部调用print语句,从而避免设置静态变量吗?
Cruncher

1
@Cruncher Nah。您得到了java.io,我将坚持使用java.nio-重点不是赢,而是展示了使用不同方法极其简洁地实现它的方法。
艾迪生·克伦普

8

AutoIt,34个字节

将自身输出到剪贴板:

ClipPut(FileRead(@ScriptFullPath))


7

Go,111105字节

package main
import("io"
."os"
."runtime")
func main(){_,p,_,_:=Caller(0)
f,_:=Open(p)
io.Copy(Stdout,f)}

我在Go中的第一个代码高尔夫球-我猜想您可以在这里使用一些技巧。


Go中已经有一个答案-是否使用相同的方法?
艾迪生·克伦普

@VoteToClose:我意识到,我的确受到了另一个启发,但是在这里使用了软件包重命名(便宜的技巧)以及用于打开文件并将其管道传输到stdout的不同技术。为我节省了22个字节;-)
tomasz

方法实际上有点不同,很好!
Fabian Schmengler,2015年

7

PowerShell,39 36 31 25字节

尽我所能:

gc $MyInvocation.MyCommand.Path | oh

在大众需求的支持下,此方法已更改为:

gc $PSCommandPath|echo -n

打印到主机壳当前的标准输出。


gc $MyInvocation.MyCommand.Path足够。它将自动打印出来。
安德鲁

特别是如果脚本正在静默运行,则无法保证
Chad Baxter 2015年

哈哈,是的,我不在乎。如果没有其他人可以得到PowerShell的答案,我将发布。但是我忘记了这gc是一个别名,只是要使用cat,所以无论如何您都对我有所了解。
安德鲁

嗯,我不会那么严格。否则,每个PS答案都必须明确地传递到主机外壳,但这取决于您……
Andrew

您可以改用gc $PSCommandPath17个字节。我看到的问题是,这会吐出换行符(源代码中不存在换行符)。现在,如果尾随换行符是否正确,这是模棱两可的……根据该规则,我们可能需要做一些复杂的事情,例如gc $PSCommandPath|write-host -n31个字节。
AdmBorkBork,2015年


5

C,49个字节

s[];main(){read(open(__FILE__,0),s,48);puts(s);}

编辑:澄清一下,第49个字节是换行符。

这将读取源代码减去末尾的换行符,以说明puts将添加到输出末尾的换行符。


此代码两次调用未定义的行为。
2015年

5
好吧,这是代码高尔夫。我的代码会产生所需的输出,因此是有效的提交。
xsot

1
@xsot在这种情况下,您可能应该列出编译器版本+选项。否则,这可能无法验证。
贾斯汀

1
如果允许具有不确定的行为,只要您可以让某个编译器在月球的某个阶段在某台机器上产生所需的输出,那么我建议使用int main(void){* 0; }作为解决方案。毕竟,该标准将允许将其编译为解决问题的程序的实现。只要您指定编译器,我就可以使用依赖于实现的行为,但是对于未定义的行为,您甚至不能保证如果您连续10次在编译器上运行了十次,就不会得到十个不同的答案。同一台机器。

1
@MDXF我并没有认真建议我们编写该解决方案。我反对允许未定义的行为。甚至int main() {*0;} 可能在现有的编译器上也可以工作,因为它包含未定义的行为。同样,xsot的解决方案可能包含现有的编译器,因为它包含未定义的行为。没有人保证能解决这个问题。(尽管xsot的确更可能这样做,但它可能同样容易崩溃)。我的实际观点是,我们应该允许解决方案依赖于依赖于实现的行为或未指定的行为,而不是依赖未定义的行为。


4

Pyth,25个字节

$import sys$h'e$sys.argv

这将读取其文件名。本质上,它查找argv,打开对应于其最后一个参数的文件,并打印其第一行。


你不能做h'$__file__$吗?
kirbyfan64sos

@ kirbyfan64sos这给了我错误NameError: name '__file__' is not defined。将Pyth编译为Python,然后执行结果字符串。所以我不希望它能起作用。
2015年

4

Go,133字节

大家都清楚吗?走!

package main
import("fmt"
"io/ioutil"
"runtime")
func main(){_,f,_,_:=runtime.Caller(0)
s,_:=ioutil.ReadFile(f)
fmt.Print(string(s))}

2
这启发了我在Go中编写自己的(也是第一个)代码高尔夫球解决方案。寻找一些一般性技巧,例如,您可以通过为软件包应用单字母名称轻松地将字符减少到123个字符r"runtime"
tomasz 2015年

4

> <>,13字节

0:0go:c=?;1+!

经过在线和离线口译员的测试。该g命令是最接近能够从源文件读取的命令,如果不能解决此挑战,则将其标记为不竞争。我确实相信它通常被认为是“欺骗”奎因。

在线尝试。


4

Haskell,63个字节

为了科学!

import System.Environment
main=getProgName>>=readFile>>=putStr

仅适用于runhaskell命令。虽然很酷
HEGX64

4

> <>,31个字节

免责声明:> <>中没有文件I / O,但是我认为展示它的代码空间I / O是有趣的,它继承自Befunge,Befunge是启发> <>的一种语言。

00voa0+1;!?$~<
1+> :r:@g: ?!^o$

我前一段时间做的自读Quine,您可以在这里尝试

我只是看到有一个较短的> <>自读quine。尽管在代码高尔夫球标准中显然更好,但我想指出的是,它具有硬编码的代码长度,而我会复制其他行或代码列(只要它们不会破坏原始代码)。


我当时打算在> <>中发布,但由于以下规则,我认为> <>将是不可能的:“您必须使用文件I / O来读取源代码”
Sp3000,2015年

@ Sp3000确实赞不绝口,好像我对挑战的理解不够。我要添加免责声明
亚伦2015年

3

F#,54个字节

printf"%s"(System.IO.File.ReadAllText __SOURCE_FILE__)

用法:

fsi --exec a.fsx

3

Perl 5,15 13字节

感谢Bash解决方案的启发:

print`cat $0`

编辑:不需要分号或第一个空格。


不是纯Perl,它还需要其他一些可执行文件,即cat在文件中可以找到和找到$PATH。但是,如果存在的话,可以假定它只是可用于的命令perl,所以为什么不这样做。
Golar Ramblar

3

Node.js,66 63字节

p=process;p.stdout.write(require('fs').readFileSync(p.argv[1]))

不使用console.log,它会添加换行符。


1
您可以使用同步api节省一些字节:p=process;p.stdout.write(require('fs').readFileSync(p.argv[1]))
TehShrike 2015年

1
为什么不console.log(require('fs').readFileSync(process.argv[1]))\n使用57个字节?
Conor O'Brien

这并不总是有效。假设文件名为test.js。通过运行调用它是有效的node test,这将导致抛出错误。
Patrick Roberts


3

Haskell,49个字节

{-#LANGUAGE CPP#-}main=putStr=<<readFile __FILE__

在线尝试!

(GHC)Haskell进行了扩展,可以使用C预处理程序(通常用于版本和体系结构之间的可移植性。)希望可以自我解释。


3

带有JavaScript的HTML,115个字节(实际上不算在内)

<!DOCTYPE html><html><title>x</title><script>alert(new XMLSerializer().serializeToString(document))</script></html>

这算吗?我不介意,这很有趣:)

从技术上讲,它不会打开文件。这也是格式良好的HTML5文档。XMLSerializer是唯一也返回DOCTYPE部分的工具,但它是非标准的。不过,它可以在chrome和firefox上运行,我敢打赌其他浏览器。

作为奖励:

JavaScript,41个字节

alert(document.currentScript.textContent)

去掉 ”;” 在结束时,保存1个字节:)
ЕвгенийНовиков

1
@ЕвгенийНовиков你说得对,不确定为什么我会把它留在那时。好像我没算在内。
Domino
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.