JavaScript, độ dài dòng 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
)
`
Phiên bản dễ đọc hơn cũng là một quine (loại bỏ dòng mới không liên quan):
[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)`
Giải trình
Phù Giải quyết một chuyến đi đến đây, bởi vì đây sẽ là một hành trình nguy hiểm ...
Tôi đã mất một thời gian dài để cố gắng tìm ra cách giải quyết thử thách này với độ dài 1 không có tích hợp (trực tiếp, dù sao), từ khóa hoặc thậm chí là các hàm mũi tên trước khi nhận ra rằng có thể dễ dàng với JSF *** , có thể đánh giá bất kỳ mã JavaScript nào trong khi tránh mọi mã thông báo nhiều byte. Nhưng một giải pháp JSF sẽ dễ dàng dài hàng nghìn byte, nếu không nói là hàng chục hoặc hàng trăm nghìn. Rất may, chúng tôi không giới hạn ở chỉ ()[]+!
chúng tôi có tất cả ASCII theo ý của chúng tôi!
Tôi đã quyết định bắt đầu bằng cách chơi golf các khối xây dựng thiết yếu của JSF, các nhân vật có thể được xây dựng thành chuỗi để "mở khóa nhiều tính năng hơn", có thể nói như vậy. Chúng tôi không thể sử dụng các chuỗi trực tiếp để nhận các ký tự, vì điều đó sẽ yêu cầu các dòng có độ dài 3. Vì vậy, thay vào đó, chúng tôi đánh cắp một mẹo từ JSF, nhận một vài ký tự từ các chữ có thể được xây dựng bằng các thẻ đơn byte:
JSF*** Used here Value Chars unlocked
!![] !0 true true
![] !1 false fals
[][[]] t.a undefined ndi
Từ những thứ này, chúng ta có thể mở rộng ra bên ngoài, bắt đầu với [].find
, đó là một đối tượng Function. Chuyển đổi này thành một chuỗi function find() { ...
cho chúng ta truy cập vào c
, o
không gian ( _
), và dấu ngoặc ( y
và z
). Có lẽ quan trọng hơn, giờ đây chúng ta có quyền truy cập vào hàm của nó constructor
, Function
chức năng mà nó có thể phát ra, cho chúng ta khả năng thực thi mã bằng cách xây dựng một chuỗi, chuyển nó đến Function()
và sau đó gọi hàm được tạo.
Tôi có lẽ nên đề cập đến phương pháp tổng thể được sử dụng bởi chính chương trình. Kể từ năm 2015, JavaScript có tính năng thực sự thú vị này được gọi là "các mẫu được gắn thẻ ", nó không chỉ cho phép các dòng mới không bị bỏ sót trong chuỗi, mà còn cho phép chúng ta gọi một hàm với một chuỗi bằng chữ trực tiếp (theo cách nào đó, myFunc`abc`;
tương đương với myFunc(["abc"])
). Nếu chúng ta đặt lệnh gọi là điều cuối cùng trong chương trình, cấu trúc chung sẽ trông như thế này:
code;func`code;func`
Tất cả func
phải làm sau đó là đưa ra đối số của nó, theo sau là một backtick, sau đó lại là đối số của nó và một backtick thứ hai. Giả sử chúng ta có đối số trong a
và một backtick được lưu trữ f
, chúng ta có thể thực hiện điều này với mã alert(a+f+a+f)
. Tuy nhiên, tại thời điểm này, chúng tôi đang mất tích +
và backtick chính nó. +
(được lưu trữ trong P
) không khó; chúng tôi đánh cắp một thủ thuật khác từ JSF, xây dựng chuỗi 1e23
, chuyển đổi thành số, sau đó quay lại chuỗi, đưa ra "1e+23"
.
Bắt backtick phức tạp hơn một chút. Lúc đầu, tôi đã cố gắng để có được String.fromCharCode
, nhưng việc tìm ra C
hóa ra gần như khó khăn. May mắn thay, atob
đủ dễ dàng để có được ( Function("return atob")()
; b
được tạo từ 0+{}
, cung cấp [object Object]
) và có thể cung cấp bất kỳ char ASCII nào, nếu tìm thấy một chuỗi ma thuật thích hợp. Một kịch bản ngắn đã cho tôi 12A
là một trong những lựa chọn, mà thuận tiện có thể được tìm thấy trong 12Array
(ngắn hơn một chút để tạo ra, nhờ [].constructor[n+a+m+e]
; m
được tìm thấy trong 0 .constructor+0
: "function Number() { ..."
).
Cuối cùng, chúng tôi gắn bó mọi thứ với nhau. Chúng tôi gán backtick cho biến f
, nhưng vì chúng tôi không thể sử dụng nó trực tiếp trong chuỗi chức năng, thay vào đó, chúng tôi đặt biến q
cho chữ cái f
và thay vào đó sử dụng biến đó. Điều này làm cho chuỗi cuối cùng của chúng tôi a+l+e+r+t+y+a+P+q+P+a+P+q+z
, hoặc "alert(a+f+a+f)"
. Sau đó, chúng tôi cung cấp mã này cho Function()
, cung cấp mã hoàn thành của chúng tôi cho kết quả và voila, chúng tôi có một mã JavaScript với không quá một char trên mỗi dòng!
Hiện tại đầu tôi cảm thấy rất tệ, vì vậy hãy hỏi về bất kỳ sai lầm nào tôi đã mắc phải hoặc những điều tôi đã bỏ qua trong lời giải thích này và tôi sẽ quay lại với bạn sau khi tôi nghỉ ngơi ...