打印程序的程序


13

挑战

您的目标是编写一个可以打印另一个程序的程序。该打印的程序应打印另一个程序,而新程序应打印另一个程序,直到结束。

规则

  1. 每个程序必须少于256个字节。(如果需要更改,请发表评论)
  2. 最后一个程序必须为空程序。
  3. 必须有有限数量的程序,因此程序不能是程序。
  4. 程序必须全部以相同的语言运行。
  5. 不允许输入。
  6. 获胜程序是打印尽可能多的程序的程序,它会自动计数。

祝好运!


最高分数为2^20483.2317e616
orlp 2015年

为了便于比较大分数,请a*10^b1<=a<10b为自然数的形式中包含分数的近似值。
瑕疵的

2
实际上,我之前的计算是错误的。假设程序必须以字节为单位,则最大可能的得分是<注释的数字太长>1.2673e614
orlp 2015年

Answers:


20

CJam,4.56×10个526程序

2D#2b{"\256b_(256b:c'\s`_:(er`":T~{;38'ÿ*`{:T~{;63'ÿ*`{:T~{;88'ÿ*`{:T~{;114'ÿ*`{:T~{;140'ÿ*`{:T~{;166'ÿ*`{:T~{;192'ÿ*`{:T~{;219'ÿ*`{Q?\"_~"}s(\T}?\"_~"}s(\T`}?\"_~"}s(\T`}?\"_~"}s(\T`}?\"_~"}s(\T`}?\"_~"}s(\T`}?\"_~"}s(\T`}?\"_~"}s(\T`}?\"_~"}_~

确切得分:254 219 + 254 192 + 254 166 + 254 140 + 254 114 + 254 88 + 254 63 + 254 38 + 254 13 + 3

为了符合文件大小限制,必须使用ISO-8859-1编码保存所有程序。

感谢@ChrisDrost指出了一个错误并提出了嵌套方法。

CJam解释器中在线尝试。

254 219 + 2≈4.56×10 526程序

分数的线份额可以通过以下更简单的程序1来实现。

"ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ"
{\256b_(256b:c'\s`_:(er`Q?\"_~"}_~

运行该程序将生成程序

"ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ"
{\256b_(256b:c'\s`_:(er`Q?\"_~"}_~

和后254次219 - 1更多的迭代,则程序

{\256b_(256b:c'\s`_:(er`Q?\"_~"}_~

最后一个非空程序退出,错误2,不打印任何内容(空程序)。

怎么运行的

假设字符串已经在堆栈中。

{      e# Push a code block.
  \    e# Swap the string on top of the code block.
       e# This will cause a runtime error if there is no string on the stack.
  256b e# Convert the string (treated as a base-256 number) to integer (I).
  _(   e# Copy the integer and decrement the copy.
  256b e# Convert the integer into the array of its base-256 digits.
  :c   e# Cast each base-256 digit to character. Converts from array to string.
  '\s  e# Push a string that contains a single backslash.
  `    e# Push its string representation, i.e., the array ['" '\ '\ '"].
  _:(  e# Push a copy and decrement each character. Pushes ['! '[ '[ '!].
  er   e# Perform transliteration to replace "s with !s and \s with [s.
       e# This skips characters that require escaping.
  `    e# Push its string representation, i.e., surround it with double quotes.
  Q    e# Push an empty string.
  ?    e# Select the first string if I is non-zero, the empty string otherwise.
  \    e# Swap the selected string with the code block.
  "_~" e# Push that string on the stack.
}      e#
_~     e# Push a copy of the code block and execute it.
       e# The stack now contains the modified string, the original code block
       e# and the string "_~", producing an almost exact copy of the source.

254个192 ≈5.35×10 461多个程序

这是事情变得有些疯狂的地方。

第一个程序是高度可压缩的。通过编写类似的程序,而不是空程序,最终产生上述部分的第一个程序,我们可以将分数提高254192 程序3

该程序

"ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ"
{"\256b_(256b:c'\s`_:(er`":T~{;219'ÿ*`{Q?\"_~"}s(\T}?\"_~"}_~

与上一节的第一个程序类似,运行前一个程序并对其输出进行254 192次迭代会生成后者。

假设字符串已经在堆栈中:

{                           e# Push a code block.
  "\256b_(256b:c'\s`_:(er`" e# Push that string on the stack.
                            e# The characters inside it behave exactly as
                            e# they did in the previous section.
  :T~                       e# Save the string in T and evaluate it.
  {                         e# If the integer I is non-zero, keep the generated
                            e# string; else:
    ;                       e#   Pop the code block from the stack.
    219'ÿ*`                 e#   Push a string of 219 ÿ's (with double quotes).
    {Q?\"_~"}               e#   Push that block on the stack.
    s                       e#   Push its string representation.
    (\                      e#   Shift out the { and swap it with the tail.
    T                       e#   Push T.
  }?                        e#
  \                         e# Swap the selected string with the code block
                            e# or T with the tail of the code block.
  "_~"                      e# Push that string on the stack.
}                           e#
_~                          e# Push a copy of the code block and execute it.

磨牙程序

上一节的第一个程序仍然是高度可压缩的,因此我们可以应用类似的方法并编写一个程序,该程序在经过254 166次迭代后,会产生上述程序。

再次重复该技术过去,直到我们打255字节的限制,我们可以共添加254 166 + 254 140 + 254 114 + 254 88个 + 254 63个 + 254 38个 + 254 13 + 1≈1.59×10 399程序来前几节的内容。


添加了1个换行符以使内容更加清晰。
2 根据对Meta的共识,默认情况下是允许的。
3 或0.0000000000000000000000000000000000000000000000000000000000000000000000000012 12%



5

JavaScript,1000个程序

x=999;
q=";alert(x=999?`q=${JSON.stringify(q)+q}`.split(x).join(x-1):``)";
alert(
    x ? `x=999;q=${JSON.stringify(q)+q}`.split(x).join(x-1) // basically .replaceAll(x, x-1)
      : ``
)

这是否有效取决于准确地理解第三条规则。


技术上讲,它不是一个信号线,因为它会打印出自己的源代码的修改版本,而不是相同的副本。显然,它确实使用了类似于quine的技术。我认为我们需要@TheTurtle进行说明。
JohnE 2015年

5
@JohnE和Ypnypn这是我所设想的。这可行。
乌龟

6
您仍然远低于代码长度限制。为什么不将999更改为更大的值?
DankMemes

4

Ruby,1.628×10 ^ 237个程序

a=0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;_="a=%#x-1;_=%p;puts _%%[a,_]if a";puts _%[a,_]if a

与我的Perl回答相同的方法,但是因为Ruby已经处理大整数,所以更容易以十六进制形式存储。


Ruby,9.277×10 ^ 90个程序

a=0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;b=0xf;(b<1)&&(a-=1)&&b=eval('0x'+'f'*(74-("%x"%a).length));_="a=%#x;b=%#x;(b<1)&&(a-=1)&&b=eval('0x'+'f'*(74-('%%x'%%a).length));_=%p;puts _%%[a,b-1,_]if a";puts _%[a,b-1,_]if a

因此,这种尝试与先前的类似quine的方式略有不同,但是由于所有额外的功能,我无法将数字提高到与另一个相似的高度……尽管尝试另一种方法很有趣!


4

Python 2,9.7 * 10 ^ 229程序

O=0
if len(hex(O))<191:print"O=0x%x"%(O+1)+open(__file__).read()[-68:]

很好,没想到字符串重复!
Dom Hastings 2015年

2

C,2.2 * 10 ^ 177个程序

#define S(s)char*q=#s,n[]="#####################################################################################################";i;s
S(main(){while(n[i]==91)n[i++]=35;i==101?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})

它不是完美的,但还不错。我的意思是它正好是255字节长,并生成相同长度的程序。您可能会拨弄一些更多的东西来获得更多的程序,但是我将暂时保留它。

该程序基于一个简单的C quine。此外,还有一种非常简单的计数算法,可以计算char数组的所有可能值n。我们拥有与字符串排列一样多的程序n

字符范围限制为#(= 35)到[=(91)。那是因为我不需要任何"\在字符串中,因为它们需要被转义。

当char数组n中的所有值均为时,程序生成结束[。然后,它输出一个简单的伪程序main(){},该伪程序本身什么也不输出。

#define  S(s) char *q = #s; /* have the source as a string */ \
char n[] = "#####################################################################################################"; \ 
int i; \
s /* the source itself */
S(main() {
    while(n[i]=='[') /* clear out highest value, so next array element be incremented */
        n[i++]='#'; 
    i==101 /* end of array reached? output dummy program */
        ? q = "main(){}"
        : n[i]++; /* count one up in the whole array */
    printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)", n, q);
})

为了演示它应该工作,我只是更改了限制,因此仅使用ASCII码35和之间的字符,36并且仅使用4个数组元素。

结果程序是

% echo > delim; find -iname 'program_*.c' | xargs -n1 cat delim

#define S(s)char*q=#s,n[]="####";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="$###";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="#$##";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="$$##";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="##$#";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="$#$#";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="#$$#";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="$$$#";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="###$";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="$##$";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="#$#$";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="$$#$";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="##$$";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="$#$$";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="#$$$";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="$$$$";i;s
S(main(){while(n[i]==36)n[i++]=35;i==4?q="main(){}":n[i]++;printf("#define S(s)char*q=#s,n[]=\"%s\";i;s\nS(%s)",n,q);})
#define S(s)char*q=#s,n[]="####";i;s
S(main(){})

这将输出2^4 + 1 = 17不同的程序。

因此上面的程序输出((91-35)+1)^101 + 1 = 57^101 + 1 ~= 2.2 * 10^177不同的程序。我不确定这是否很重要,或者我的计算是否正确


1
能否请您说明一下 2.2 * 10^177(对于那些想要比较的人)?
瑕疵的

不知道如何计算这一数值,但我将其包括在内;-)
MarcDefiant 2015年


1

Perl,1×10 ^ 163

否则,这是一个非常基本的奎因,缩小到尽可能少的字符,仅在计数器不运行时运行0

use bigint;$i=9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999||die;$_=<<'e';eval
print"use bigint;\$i=$i-1||die;\$_=<<'e';eval
${_}e
"
e

1

普通Lisp 10113 -1

(LET ((X
       99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999))
  (WHEN #1=(PLUSP X)
    #2=(SETF *PRINT-CIRCLE* T)
    #3=(PRINT (LIST 'LET `((X ,(1- X))) (LIST 'WHEN '#1# '#2# '#3#)))))
  • 有113个9。
  • 下一个程序有112个9,其后是8
  • 下一个程序有112个9,之后是7
  • ...

考虑到打印机引入的空间,9的数目受最大代码256的限制。


1

Perl,1.4 * 10 ^ 225

use bignum;open$F,__FILE__;$_=<$F>;s/0x\w+/($&-1)->as_hex/e;0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff&&print

与python类似的方法;同样的结果!


0

> <>,65534(?)程序

我尚未在65533旁边添加一个问号,因为我尚未验证它是否可以打印65533(尽管我有理由相信它应该可以打印)。一旦有更多时间,我将想出一种测试方法。

":?!;1-r00gol?!;a0.�

您可以在这里在线尝试。

该程序的要点是,它会在最后更改字符的输出,然后在打印之前减小其数值。我有65534个程序,因为该代码末尾的字符的ascii值为65533,所以算第一个程序就有65534(我想如果您算空程序65535)。最后一个程序“返回”什么都没有;它只是在字符值为0时结束。

我非常确定它能够在所有迭代中打印一个字符:我找不到确切的来源,可以打印多少个字符<<>,但是在数字上直接位于65533以下的字符。

让我知道此实现是否存在任何问题;我对我输入的有效性不确定。


说明

我无耻地窃取了使用单引号从> <> Wiki和我一次在这里看到的评论创建伪quine的想法。

":?!;1-r00gol?!;a0.�
"                     begins string parsing
 :?!;                 terminates program if final character is 0, numerically
     1-               decrements final character by 1
       r              reverses stack
        00g           grabs quotation mark (fancy way of putting " ")
           ol?!;      prints and terminates if stack is empty
                a0.   jumps back to o to loop 

它的作用是将引号后的所有内容解析为字符,然后递减最后一个。从那里,它只是反转堆栈(以便以正确的顺序打印),将引号推到堆栈上,然后打印直到堆栈为空。


0

Python,1×10 ^ 194个程序

n=99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
if n:print open(__file__).read().replace(str(n),str(n-1))

这必须从文件而不是交互式repl运行。这不是奎因。

感谢@The Turtle帮助我节省了3个字节,这比9的空间更大!
感谢@poke帮助我节省了2个字节,这比9的空间更大!


@芝士情人这if n!=0是多余的。你可以写if n
乌龟

您也可以删除两个空格;在参数if n:之间和之间replace

0

Bash,52个程序

完全没有灵感,(希望)牢牢地排在最后。

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