JavaScript, panjang baris 1, 960 956 928 byte
[
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
)
`
Versi yang lebih mudah dibaca yang juga merupakan quine (newlines asing dihapus):
[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)`
Penjelasan
Wah. Duduklah di sini, karena ini akan menjadi perjalanan yang berbahaya ...
Saya menghabiskan banyak waktu untuk mencari tahu bagaimana menyelesaikan tantangan ini dengan panjang 1 — tidak ada built-in (secara langsung, toh), kata kunci, atau bahkan fungsi panah — sebelum menyadari bahwa itu mungkin dengan JSF *** , yang dapat dilakukan dengan mudah. mengevaluasi kode JavaScript apa pun sambil menghindari token multi-byte. Tetapi solusi JSF akan dengan mudah panjangnya ribuan byte, jika tidak puluhan atau ratusan ribu. Untungnya, kami tidak terbatas hanya pada — ()[]+!
kami memiliki semua ASCII yang kami miliki!
Saya memutuskan untuk memulai dengan bermain-main blok bangunan penting JSF — karakter yang dapat dibangun menjadi string untuk "membuka lebih banyak fitur," jadi untuk berbicara. Kami tidak dapat menggunakan string secara langsung untuk mendapatkan karakter, karena itu membutuhkan garis panjang 3. Jadi, kami mencuri trik dari JSF, mendapatkan beberapa karakter dari literal yang dapat dibangun dengan token byte tunggal:
JSF*** Used here Value Chars unlocked
!![] !0 true true
![] !1 false fals
[][[]] t.a undefined ndi
Dari ini kita dapat memperluas ke luar, dimulai dengan [].find
, yang merupakan objek Function. Konversi ini untuk string function find() { ...
memberi kita akses ke c
, o
, ruang ( _
), dan tanda kurung ( y
dan z
). Mungkin yang lebih penting, kami sekarang memiliki akses ke nya constructor
, yang Function
fungsi-yang, inceptional kedengarannya, memberikan kita kemampuan untuk mengeksekusi kode dengan membangun string, lewat ke Function()
, dan kemudian memanggil fungsi yang dihasilkan.
Saya mungkin harus menyebutkan metode keseluruhan yang digunakan oleh program itu sendiri. Pada 2015, JavaScript memiliki fitur yang sangat keren ini disebut " tagged templates ," yang tidak hanya memungkinkan baris baru yang tidak terhapus dalam string, tetapi juga memungkinkan kita memanggil fungsi dengan string literal secara langsung (dengan cara; myFunc`abc`;
kira-kira setara dengan myFunc(["abc"])
). Jika kita menempatkan pemanggilan fungsi sebagai hal terakhir dalam program, struktur umum akan terlihat seperti ini:
code;func`code;func`
Yang func
harus dilakukan adalah mengeluarkan argumennya, diikuti backtick, lalu argumennya lagi, dan backtick kedua. Dengan asumsi kita memiliki argumen a
dan backtick tersimpan f
, kita dapat menyelesaikan ini dengan kode alert(a+f+a+f)
. Namun, saat ini, kami hilang +
dan backtick itu sendiri. +
(disimpan dalam P
) tidak sulit; kami mencuri trik lain dari JSF, membuat string 1e23
, mengonversi ke angka, lalu kembali ke string, memberi "1e+23"
.
Mendapatkan backtick sedikit lebih rumit. Pada awalnya, saya mencoba mendapatkan String.fromCharCode
, tetapi C
ternyata ternyata hampir sama sulitnya. Untungnya, atob
cukup mudah untuk memperoleh ( Function("return atob")()
; b
dihasilkan dari 0+{}
, yang memberi [object Object]
) dan dapat memberikan arang ASCII, jika string sihir yang tepat ditemukan. Sebuah script singkat memberi saya 12A
sebagai salah satu pilihan, yang dapat mudah ditemukan di 12Array
(a bit lebih pendek untuk menghasilkan, berkat [].constructor[n+a+m+e]
; m
ditemukan dalam 0 .constructor+0
: "function Number() { ..."
).
Akhirnya, kami menggabungkan semuanya. Kami menetapkan backtick ke variabel f
, tetapi karena kami tidak dapat menggunakannya secara langsung dalam string fungsi, kami malah mengatur variabel q
ke huruf f
dan menggunakannya. Ini membuat string terakhir kita a+l+e+r+t+y+a+P+q+P+a+P+q+z
, atau "alert(a+f+a+f)"
. Kami kemudian mengumpankan ini ke Function()
, memberi makan kode jadi kami ke hasilnya, dan voila, kami memiliki quine JavaScript dengan tidak lebih dari satu char per baris!
Kepalaku merasa tidak enak saat ini, jadi tolong tanyakan tentang kesalahan yang telah saya buat atau hal-hal yang saya lewatkan dalam penjelasan ini, dan saya akan menghubungi Anda setelah saya beristirahat ...