JavaScript, longueur de ligne 1, 960 956 928 octets
[
t
,
r
,
u
,
e
,
f
,
a
,
l
,
s
]
=
!
0
+
[
!
1
]
;
[
,
n
,
d
,
,
q
,
i
]
=
t
.
a
+
t
V
=
[
]
[
f
+
i
+
n
+
d
]
;
[
,
,
,
c
,
,
,
o
,
,
_
,
,
,
,
,
y
,
z
]
=
V
+
0
F
=
V
[
E
=
c
+
o
+
n
+
s
+
t
+
r
+
u
+
c
+
t
+
o
+
r
]
P
=
(
1
+
e
+
2
+
3
-
4
+
t
)
[
2
]
f
=
F
(
r
+
e
+
t
+
u
+
r
+
n
+
_
+
a
+
t
+
o
+
(
0
+
{
}
)
[
3
]
)
(
)
(
3
*
4
+
[
]
[
E
]
[
n
+
a
+
(
0
[
E
]
+
0
)
[
9
+
2
]
+
e
]
)
[
1
]
F
(
a
,
a
+
l
+
e
+
r
+
t
+
y
+
a
+
P
+
q
+
P
+
a
+
P
+
q
+
z
)
`
[
t
,
r
,
u
,
e
,
f
,
a
,
l
,
s
]
=
!
0
+
[
!
1
]
;
[
,
n
,
d
,
,
q
,
i
]
=
t
.
a
+
t
V
=
[
]
[
f
+
i
+
n
+
d
]
;
[
,
,
,
c
,
,
,
o
,
,
_
,
,
,
,
,
y
,
z
]
=
V
+
0
F
=
V
[
E
=
c
+
o
+
n
+
s
+
t
+
r
+
u
+
c
+
t
+
o
+
r
]
P
=
(
1
+
e
+
2
+
3
-
4
+
t
)
[
2
]
f
=
F
(
r
+
e
+
t
+
u
+
r
+
n
+
_
+
a
+
t
+
o
+
(
0
+
{
}
)
[
3
]
)
(
)
(
3
*
4
+
[
]
[
E
]
[
n
+
a
+
(
0
[
E
]
+
0
)
[
9
+
2
]
+
e
]
)
[
1
]
F
(
a
,
a
+
l
+
e
+
r
+
t
+
y
+
a
+
P
+
q
+
P
+
a
+
P
+
q
+
z
)
`
Version plus lisible qui s'avère également être une quine (les nouvelles lignes superflues ont été supprimées):
[t,r,u,e,f,a,l,s]=!0+[!1];[,n,d,,q,i]=t.a+t
V=[][f+i+n+d];[,,,c,,,o,,_,,,,,y,z]=V+0
F=V[E=c+o+n+s+t+r+u+c+t+o+r]
P=(1+e+2+3-4+t)[2]
f=F(r+e+t+u+r+n+_+a+t+o+(0+{})[3])()(3*4+[][E][n+a+(0[E]+0)[9+2]+e])[1]
F(a,a+l+e+r+t+y+a+P+q+P+a+P+q+z)`
[t,r,u,e,f,a,l,s]=!0+[!1];[,n,d,,q,i]=t.a+t
V=[][f+i+n+d];[,,,c,,,o,,_,,,,,y,z]=V+0
F=V[E=c+o+n+s+t+r+u+c+t+o+r]
P=(1+e+2+3-4+t)[2]
f=F(r+e+t+u+r+n+_+a+t+o+(0+{})[3])()(3*4+[][E][n+a+(0[E]+0)[9+2]+e])[1]
F(a,a+l+e+r+t+y+a+P+q+P+a+P+q+z)`
Explication
Ouf. Installez-vous pour une balade ici, parce que ça va être un voyage perfide ...
J'ai passé beaucoup de temps à essayer de comprendre comment résoudre ce défi avec la longueur 1 - pas de fonctions intégrées (directement, de toute façon), de mots clés ou même de fonctions fléchées - avant de réaliser que c'est facilement possible avec JSF *** , qui peut évaluer tout code JavaScript tout en évitant les jetons multi-octets. Mais une solution JSF aurait facilement des milliers d'octets, sinon des dizaines ou des centaines de milliers. Heureusement, nous ne sommes pas limités à seulement ()[]+!
- nous avons tout ASCII à notre disposition!
J'ai décidé de commencer par jouer au golf sur les blocs de construction essentiels de JSF - les personnages qui peuvent être construits en chaînes pour «débloquer plus de fonctionnalités», pour ainsi dire. Nous ne pouvons pas utiliser directement des chaînes pour obtenir des caractères, car cela nécessiterait des lignes de longueur 3. Ainsi, nous volons une astuce à JSF, obtenant quelques caractères des littéraux qui peuvent être construits avec des jetons à un octet:
JSF*** Used here Value Chars unlocked
!![] !0 true true
![] !1 false fals
[][[]] t.a undefined ndi
De ceux-ci, nous pouvons développer vers l'extérieur, en commençant par [].find
, qui est un objet Function. La conversion de ce à une chaîne function find() { ...
nous donne accès à c
, o
, l' espace ( _
), et les parenthèses ( y
et z
). Peut-être plus important encore , nous avons maintenant accès à son constructor
, la Function
fonction qui, inceptional que cela puisse paraître, nous donne la possibilité d'exécuter du code par la construction d' une chaîne, en passant à Function()
, puis d' appeler la fonction générée.
Je devrais probablement mentionner la méthode globale utilisée par le programme lui-même. À partir de 2015, JavaScript a cette fonctionnalité vraiment cool appelée « modèles balisés », qui permet non seulement des sauts de ligne sans échappement dans les chaînes, mais nous permet également d'appeler directement une fonction avec un littéral de chaîne (en quelque sorte; myFunc`abc`;
est à peu près équivalent à myFunc(["abc"])
). Si nous plaçons l'appel de fonction comme dernière chose dans le programme, la structure générale ressemblera à ceci:
code;func`code;func`
Il func
suffit alors de sortir son argument, suivi d'un backtick, puis de nouveau son argument, et d'un second backtick. En supposant que nous ayons l'argument a
et un backtick stockés dans f
, nous pouvons accomplir cela avec le code alert(a+f+a+f)
. Cependant, pour le moment, nous +
manquons et le backtick lui-même. +
(stocké dans P
) n'est pas difficile; nous volons une autre astuce à JSF, la construction de la chaîne 1e23
, la conversion en un nombre, puis de nouveau en une chaîne, donnant "1e+23"
.
Obtenir un backtick est un peu plus compliqué. Au début, j'ai essayé de l'obtenir String.fromCharCode
, mais trouver un C
avéré s'est avéré presque aussi difficile. Heureusement, atob
est assez facile à obtenir ( Function("return atob")()
; b
est généré à partir de 0+{}
, ce qui donne [object Object]
) et peut donner n'importe quel caractère ASCII, si une chaîne magique appropriée est trouvée. Un court script m'a donné 12A
comme l'une des options, qui peut être facilement trouvée dans 12Array
(un peu plus court à générer, grâce à [].constructor[n+a+m+e]
; m
se trouve dans 0 .constructor+0
:) "function Number() { ..."
.
Enfin, nous collons tout ensemble. Nous attribuons le backtick à la variable f
, mais comme nous ne pouvons pas l'utiliser directement dans la chaîne de fonction, nous définissons plutôt la variable q
sur la lettre f
et nous l'utilisons à la place. Cela rend notre chaîne finale a+l+e+r+t+y+a+P+q+P+a+P+q+z
, ou "alert(a+f+a+f)"
. Nous alimentons ensuite ceci Function()
, alimentons notre code fini au résultat, et le tour est joué, nous avons un quine JavaScript avec pas plus d'un caractère par ligne!
Ma tête est horrible pour le moment, alors s'il vous plaît, renseignez-vous sur les erreurs que j'ai faites ou les choses que j'ai manquées dans cette explication, et je vous répondrai après un peu de repos ...