Haskell,3 quines,1119字节
Quine 1,51个字节
IO
直接打印到标准输出的匿名操作。
putStr`mappend`print`id`"putStr`mappend`print`id`"
在线尝试!
Quine 2,265字节
该函数f
接受一个虚拟参数并返回一个字符串。
f c=[b=<<g]!!0++show g;b c=[[[show 9!!0,show 1!!0..]!!6..]!!c];g=[93,0,90,52,82,89,52,51,51,94,84,24,24,39,34,34,106,95,102,110,0,94,50,89,0,90,52,82,82,82,106,95,102,110,0,48,24,24,39,35,106,95,102,110,0,40,24,24,39,37,37,84,24,24,45,37,37,84,24,24,90,84,50,94,52]
在线尝试!
Quine 3,803个字节
LANGUAGE
编译后的所有内容都是一个带有虚参数并返回字符串的函数。
{-#LANGUAGE CPP#-}(\q(_:_:_:_:_:_:_:_:z)y(#)_->(y(\k x->'&':q:k:q:x)#y(\k x->'%':q:'\\':k:q:x)$y(:)#y(:)$ \x->x)z)'\''__TIME__(\(?)v k x->v$k?x)$ \(&)(%)v->v&'{'&'-'&'#'&'L'&'A'&'N'&'G'&'U'&'A'&'G'&'E'&' '&'C'&'P'&'P'&'#'&'-'&'}'&'('%'\\'&'q'&'('&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'z'&')'&'y'&'('&'#'&')'&'_'&'-'&'>'&'('&'y'&'('%'\\'&'k'&' '&'x'&'-'&'>'%'\''&'&'%'\''&':'&'q'&':'&'k'&':'&'q'&':'&'x'&')'&'#'&'y'&'('%'\\'&'k'&' '&'x'&'-'&'>'%'\''&'%'%'\''&':'&'q'&':'%'\''%'\\'%'\\'%'\''&':'&'k'&':'&'q'&':'&'x'&')'&'$'&'y'&'('&':'&')'&'#'&'y'&'('&':'&')'&'$'&' '%'\\'&'x'&'-'&'>'&'x'&')'&'z'&')'%'\''%'\\'%'\''%'\''&'_'&'_'&'T'&'I'&'M'&'E'&'_'&'_'&'('%'\\'&'('&'?'&')'&'v'&' '&'k'&' '&'x'&'-'&'>'&'v'&'$'&'k'&'?'&'x'&')'&'$'&' '%'\\'&'('&'&'&')'&'('&'%'&')'&'v'&'-'&'>'&'v'
在线尝试!
性格
Quine 1:
"S`adeimnprtu
Quine 2:
!+,.0123456789;<=[]bcfghosw
Quine 3:
#$%&'()-:>?ACEGILMNPTU\_kqvxyz{}
怎么运行的
Quine 1
putStr`mappend`print`id`"putStr`mappend`print`id`"
Quine 1是我最近的Golf you quine答案的修改版(H.PWiz进行了改进):
- 由于不需要完整的程序,因此
main=
已被删除。
<>
并$
已由它们的近义词mappend
和代替id
。
这样可以释放重要角色,=<>
并释放$
其他藜的有用操作者。
奎因2
f c=[b=<<g]!!0++show g;b c=[[[show 9!!0,show 1!!0..]!!6..]!!c];g=[93,0,......]
Quine 2使用了与我最近的Mutually Exclusive Quines答案的程序2相似的方法,但是适应于直接本身,特别是避免使用Quine 3 所需的字符文字。这两种方法都是在show
函数,幸好目前还没有使用过任何字符。
这种方法使用制表符代替空格,但是为了便于阅读,我在下面使用空格。
g
是quine数据,作为代码末尾的整数列表。每个数字代表其余代码中的一个字符。
- 数字被移位
9
,因此制表符为0
。通过使函数和变量名的小写字母适合两位数,可以使编码稍微短一些。
b c=[[[show 9!!0,show 1!!0..]!!6..]!!c]
是将数字转换为字符(实际上是一个字符的字符串)的函数。
[[show 9!!0,show 1!!0..]!!6..]
是一个以制表符开头的字符范围,该制表符以索引!!c
。
- 制表符本身是通过索引到另一个范围而产生的
[show 9!!0,show 1!!0..]
,从数字字符开始'9'
,'1'
然后以8的步长向下跳。
- 数字字符是通过索引到
show
相应数字的字符串中而产生的。
f c=[b=<<g]!!0++show g
是主要功能。c
是一个伪参数。
b=<<g
用于=<<
将每个数字转换g
为其字符。(使用=<<
而不是例如map
,为什么b
需要将其返回的字符包装在列表中。)
show g
给出g
的列表的字符串表示形式,并且++
连接字符串。
- 由于
=<<
优先级低于++
,因此需要一些包围。为了避免使用()
(保留给quine 3),请[...]!!0
使用一个元素将其索引到列表中。
Quine 3
通过设计其他quines,quine 3仍可以访问括号,lambda表达式,字符文字和字符串/列表构造函数:
。这足以构造一个将 quine代码附加到字符串的函数。
不幸的是,y
已使用了所有小写的元音(有时除外),没有留下有用的字母数字内置函数。也[]""
消失了。这就没有任何正常的方法来构造一个空字符串来开始伪装代码。
但是,几乎所有大写字母仍然可用,因此可以使用LANGUAGE
杂凑来获得语言扩展。再次幸运的是,CPP
(启用C预处理程序)是唯一仅使用大写字母命名的语言扩展。CPP宏通常具有大写名称。
因此,要获取必需的空字符串,quine enables会CPP
使用__TIME__
宏使用以下形式的字符串常量"??:??:??"
(方便地保证始终具有相同的长度),并在其上进行模式匹配。
{-#LANGUAGE CPP#-}(\q(_:_:_:_:_:_:_:_:z)y(#)_->(y(\k x->'&':q:k:q:x)#y(\k x->'%':q:'\\':k:q:x)$y(:)#y(:)$ \x->x)z)'\''__TIME__(\(?)v k x->v$k?x)$ \(&)(%)v->v&'{'&'-'&......
语言编译后,该信息包含一个lambda表达式,将其参数绑定到这四个参数(保留最终的虚拟参数_
供以后使用):
q
绑定到'\''
,给出一个单引号字符;
_:_:_:_:_:_:_:_:z
绑定到__TIME__
,也就是类似的字符串"??:??:??"
,从而生成z
一个空字符串;
y
绑定到(\(?)v k x->v$k?x)
一个lambda组合器,该组合器用于帮助将quine数据从左侧关联(“ foldl”)转换为右侧关联(“ foldr”)形式;
- 运算符
(#)
绑定到\(&)(%)v->v&'{'&'-'&...
quine数据本身。
quine数据以Church编码的形式给出,它是带有参数的lambda表达式(&)(%)v
。
- 通过将表达式应用于特定值以实例化
(&)
,(%)
并且v
,该编码既可以用于构建喹的核心代码或重建喹数据表示本身。
- 通过Haskell的默认固定性规则,
&
并%
成为lambda内的左关联运算符。因此,字符参数与初始v
从左开始。
- 对于大多数字符
k
,有一个对应的&'k'
。
- 当
k
is '
或\
需要在字符文字中转义时,编码改为%'\k'
。
由于数据编码是左关联的,但是字符串是以右关联的方式构建的,因此y = (\(?)v k x->v$k?x)
引入了组合器来弥合失配。
更一般而言,何时(#)
是quine数据函数,并且f1,f2
是将字符与字符串组合的函数:
(y(f1)#y(f2)$v) x
= (...(y(f1)(y(f1)v '{') '-')...) x
= v(f1 '{' (f1 '-' (... x)))
将quine数据函数与(&)=y(f1)
和一起使用(%)=y(f2)
,这将使用规定的f1
和f2
将quine数据的字符与组合x
,然后将结果字符串传递给v
。
主要lambda表达式的主体将所有内容组合在一起:
(y(\k x->'&':q:k:q:x)#y(\k x->'%':q:'\\':k:q:x)$y(:)#y(:)$ \x->x)z
'&':q:k:q:x
对于字符串k
前面&'k'
的字符x
,而'%':q:'\\':k:q:x
前面的字符则%'\k'
是其原始quine数据形式。
- 因此
y(\k x->'&':q:k:q:x)#y(\k x->'%':q:'\\':k:q:x
,正确的参数是用于重建quine数据表示形式的,前置到最后一个z
(空字符串)然后传递给以下函数的参数。
y(:)#y(:)
是将quine的核心代码添加到字符串之前的正确参数,而无需进行其他修改。
- 最终
\x->x
,返回的与构造的quine无关。