JavaScript, długość linii 1, 960 956 928 bajtów
[
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
)
`
Bardziej czytelna wersja, która również jest quine (usunięto zbędne znaki nowej linii):
[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)`
Wyjaśnienie
Uff Wybierz się tutaj na przejażdżkę, ponieważ będzie to zdradziecka podróż ...
Spędziłem dużo czasu próbując dowiedzieć się, jak rozwiązać to wyzwanie z długością 1 - bez wbudowanych (bezpośrednio, w każdym razie), słów kluczowych, a nawet funkcji strzałek - zanim zdałem sobie sprawę, że jest to możliwe z JSF *** , który może oceń dowolny kod JavaScript, unikając jednocześnie tokenów wielobajtowych. Ale rozwiązanie JSF z łatwością miałoby tysiące bajtów, jeśli nie dziesiątki lub setki tysięcy. Na szczęście nie ograniczamy się tylko do - ()[]+!
mamy do dyspozycji wszystkie ASCII!
Postanowiłem zacząć od gry w golfa w podstawowe elementy JSF - postaci, które można zbudować z ciągów znaków, aby „odblokować więcej funkcji”. Nie możemy używać ciągów bezpośrednio do pobierania znaków, ponieważ wymagałoby to wierszy o długości 3. Zamiast tego kradniemy sztuczkę z JSF, uzyskując kilka znaków z literałów, które można zbudować za pomocą tokenów jednobajtowych:
JSF*** Used here Value Chars unlocked
!![] !0 true true
![] !1 false fals
[][[]] t.a undefined ndi
Z nich możemy rozwinąć na zewnątrz, zaczynając od [].find
, który jest obiektem funkcji. Konwersja to ciąg function find() { ...
daje nam dostęp do c
, o
przestrzeń ( _
) i nawiasy ( y
i z
). Co ważniejsze, mamy teraz dostęp do swojego constructor
, z Function
funkcją-które inceptional jak się może wydawać, daje nam możliwość wykonywania kodu budując łańcuch, mijając go Function()
, a następnie wywołaniu funkcji generowane.
Powinienem chyba wspomnieć o ogólnej metodzie stosowanej przez sam program. Począwszy od 2015 r. JavaScript ma tę naprawdę fajną funkcję zwaną „ szablonami otagowanymi ”, która nie tylko pozwala na nieoznaczone znaki nowej linii w ciągach, ale także pozwala nam wywoływać funkcję z dosłownym ciągiem znaków (w pewnym sensie; myFunc`abc`;
jest mniej więcej równoważna myFunc(["abc"])
). Jeśli umieścimy wywołanie funkcji jako ostatnią rzecz w programie, ogólna struktura będzie wyglądać następująco:
code;func`code;func`
Wszystko, func
co należy zrobić, to wypisanie argumentu, następnie kliknięcie wstecz, następnie argument ponownie i drugi zwrot. Zakładając, że mamy argument a
i zapisany backtick f
, możemy to zrobić za pomocą kodu alert(a+f+a+f)
. Jednak w tej chwili brakuje, +
a sam backtick. +
(przechowywane w P
) nie jest trudne; kradniemy kolejną sztuczkę z JSF, budując ciąg 1e23
, konwertując na liczbę, a następnie z powrotem na ciąg, dając "1e+23"
.
Użycie backticka jest nieco bardziej skomplikowane. Na początku próbowałem uzyskać String.fromCharCode
, ale znalezienie C
okazało się prawie tak samo trudne. Na szczęście atob
jest łatwy do uzyskania ( Function("return atob")()
; b
jest generowany z 0+{}
, co daje [object Object]
) i może dać dowolny znak ASCII, jeśli zostanie znaleziony odpowiedni ciąg magiczny. Krótki skrypt dał mi 12A
jako jedną z opcji, które można łatwo znaleźć w 12Array
(nieco krótszy wygenerować dzięki [].constructor[n+a+m+e]
; m
znajduje się w 0 .constructor+0
: "function Number() { ..."
).
Wreszcie, wszystko trzymamy razem. Przypisujemy strzałkę wsteczną do zmiennej f
, ale ponieważ nie możemy jej użyć bezpośrednio w ciągu funkcji, zamiast tego ustawiamy zmienną q
na literę f
i używamy jej zamiast tego. To czyni nasz ostatni ciąg a+l+e+r+t+y+a+P+q+P+a+P+q+z
, lub "alert(a+f+a+f)"
. Następnie Function()
podajemy to do, podajemy gotowy kod do wyniku i voila, mamy skrypt JavaScript z nie więcej niż jednym znakiem w wierszu!
W tej chwili czuję się okropnie, więc proszę pytać o błędy, które popełniłem lub rzeczy, które mi umknęły w tym wyjaśnieniu, a wrócę do ciebie po odpoczynku ...