Wskazówki dotyczące gry w golfa w Japt

18

Teraz, kiedy jestem całkowicie uzależniony od Code Golf, prawdopodobnie nadszedł czas, aby spróbować wybrać kilka języków golfowych.

Biorąc pod uwagę, że gram prawie wyłącznie w JavaScript, Japt wydaje się logicznym językiem na początek. Zagłębię się w dokumentację przy następnej okazji, ale w międzyczasie proszę zamieścić wszelkie wskazówki dla Japt w odpowiedziach poniżej.

Jako że jestem początkującym w językach Japt i ogólnie w golfa, gdybyś mógł „przetłumaczyć” swoje wskazówki na JavaScript, tam gdzie to możliwe, byłoby to bardzo pomocne w pomaganiu mi w opanowaniu różnych rzeczy.

Kudłaty
źródło
Heh, dzięki za opublikowanie tego. Nie chciałem tego robić, ponieważ w pewnym momencie chciałbym przeprojektować Japt, ale to się wkrótce nie wydarzy i prawdopodobnie i tak nie zepsuje wielu wskazówek. Wskazówka dla siebie: napisz samouczek: P
ETHprodukcje
Nie zapomnij odwiedzić czatu Japt :)
Oliver

Odpowiedzi:

11

Przejście z JavaScript do Japt

Jak zapewne wiesz, Japt to po prostu skrócona, rozszerzona wersja JavaScript. Stworzyłem Japt, ponieważ miałem już dość długich nazw nieruchomości, takich jak String.fromCharCode(x)i Math.floor(x), oraz żmudności robienia takich rzeczy, jak tworzenie zasięgu. Oto absolutne minimum, które musisz wiedzieć, przechodząc z JavaScript do Japt:

  • Japt to język transpilowany ; Kod Japt jest transpilowany do JavaScript, a następnie uruchamiany jako JS. ( Wydaje mi się, że można powiedzieć , że jest skompilowany , ale transponowany brzmi bardziej hipster. Oświadczenie: Nie wiem absolutnie nic o byciu hipsterem)
  • Wszystkie wpisy są domyślnie pełnymi programami. Wejście jest niejawnie analizowany, a pierwsze sześć wejścia są umieszczone w zmiennych U, V, W, X, Y, i Z; pełna tablica jest przechowywana w N. Wynik ostatniego wyrażenia jest drukowany automatycznie.
  • Wszystkie wielkie litery są zmiennymi i pozostają bez zmian po transpozycji. Większość z nich ma ustawione wartości, które można znaleźć w części „Zmienne” w dokumentacji Japt (u tłumacza ).
  • Wszystkie małe litery są prototypowymi funkcjami lub metodami . Japt dodaje metody a- z(ià - ÿ) do liczb, ciągów i tablic. Gdy użyjesz jednej z tych liter, Japt wypełnia .i (; Ucw Japt jest równoważne z U.c(JavaScript, co może oznaczać ceil, charCodeAt lub concat, w zależności od typu U. Stąd pochodzi większość mocy Japt; Pełne listy tych metod można znaleźć w sekcjach „_____ funkcje” dokumentów Japt (u tłumacza ).
  • Spacja reprezentuje )i )reprezentuje )). Dzieje się tak, ponieważ kiedy pierwszy raz zaprojektowałem Japt, chciałem zaoszczędzić jak najwięcej bajtów, i tak po raz pierwszy pomyślałem o zrobieniu tego. (Choć Us w nwygląda lepiej niż Us)w)n), IMHO.)
  • Funkcja jest oznaczona jako ABC{...}, gdzie ABCmoże być dowolnym ciągiem zmiennych. Funkcje działają w przeważającej części tak, jak działają w JS, a główną różnicą jest automatyczne zwracanie ostatniego wyrażenia (zamiast konieczności używania returnlub wymyślania nawiasów ES6).
  • ' oznacza pojedynczy ciąg znaków (tj 'a jest taki sam jak "a") i #pobiera następny kod i staje się tą liczbą ( #ejest taki sam jak 101).
  • Wszystko między znakami dolara $ pozostaje takie samo podczas procesu transpilacji. Możesz użyć tego do implementacji forpętli, na przykład, ponieważ Japt ich nie ma, ale sugerowałbym użycie innych metod (takich jak młańcuchy i tablice lub oliczby).
  • Większość innych znaków powszechnie stosowane w JS - "", 0-9,( , +, =, itd. - pozostają takie same, gdy transpiled (w przeważającej części, w każdym razie).

I to wszystko, co musisz wiedzieć, aby napisać podstawowy kod Japt. Osiągnięcie maksymalnej mocy golfa w Japt wymaga więcej wiedzy, ale można to znaleźć w innych odpowiedziach.


Oto podstawowy przykład. Załóżmy, że chcesz pobrać ciąg znaków ASCII i zastąpić je szesnastkowym kodem znaków. Oto jak możesz to zrobić w JavaScript:

U.split("").map(x=>x.charCodeAt(0).toString(16)).join("")

Teraz przekonwertuj na Japt. .split("")w JS jest równoważne z q""Japt, a nawet krótszym, właśnie q. .join("")jest również sprawiedliwy q, z tą różnicą, że obiekt jest tablicą zamiast łańcucha. .map(jest m, .charCodeAt(jest ci .toString(jests . Więc nasz kod Japt może wyglądać następująco:

Uq mX{Xc0 s16} q 

Jednak w Japt mdziała równie dobrze na łańcuchach, jak na tablicach, więc możemy usunąć oba qs:

UmX{Xc0 s16}

Przetestuj online!Jak widać w polu „Kod JS”, ​​transponuje się to bezpośrednio do:

U.m(function(X){return X.c(0).s(16)})

Gdy nauczysz się pracować z Japt, będziesz coraz mniej koncentrować się na konwersji w tę iz powrotem z JavaScript i będziesz mógł pisać w Japt jako własnym języku. Oto wyjaśnienie, w którym całkowicie pominięto część JavaScript:

UmX{Xc0 s16}
               // Implicit: U = input string
UmX{       }   // Take U, and replace each character X with the result of this function:
    Xc0        //   Take the char-code at index 0 in X (the first and only one).
        s16    //   Convert this to a hexadecimal string.
               // Implicit: output result of last expression
ETHprodukcje
źródło
Lepiej jest pokazać kolejny krok: skróty Unicode. W takim przypadku moglibyśmy z nimi zaoszczędzić 2B. Możesz także dodać, że możesz pominąć pewne rzeczy na końcu. To oszczędziłoby kolejny bajt.
Łukasz
Doskonały podkład, dzięki, ETH. Myślę, że jest wystarczająco dużo, aby zacząć od kilku prostych wyzwań.
Kudłaty
Łącząc to z tym, co do tej pory zebrałem z README, czy miałbym rację, że powyższy przykład można dalej skrócić Um_c s16?
Kudłaty
Albo jeszcze krócej: ¡Xc s16?
Kudłaty
1
@Shaggy Masz rację! Człowieku, szybko to rozgryzłeś ;-) Dodam kilka podstawowych wskazówek golfowych Japt (takich jak skróty Unicode itp.), Prawdopodobnie jako inne odpowiedzi.
ETHprodukcje
8

Kompresowanie tablic łańcuchowych

AKTUALIZACJA: Narzędzia przedstawione w tym poradniku zostały odtąd przepisane, ulepszone i zintegrowane z moim interpreterem Japt . W celu uzyskania najlepszych rezultatów zaleca się stosowanie tej sprężarki w stosunku do któregokolwiek z poniższych łączy. Wrócę do tej wskazówki, kiedy będę miał więcej czasu, i przepiszę ją z myślą o nowej sprężarce.

Wprowadzenie

Jeśli masz tablicę ciągów w kodzie, najbardziej oczywistym sposobem na skompresowanie byłoby uruchomienie każdego z nichOc osobno. Na potrzeby tej wskazówki będziemy pracować z tablicą ["lollipop","marshmallow","nougat","oreo"], która początkowo waży 42 bajty. Uruchomienie każdego ciągu Ocdaje nam:

[`lo¥ipop`,`Ú\hÚaow`,`Í`,`eo`]

To teraz 33 bajty, przyzwoita oszczędność.


Krok 1

Ale możemy zrobić lepiej. Jeśli połączymy tablicę z ciągiem oddzielonym znakiem nowej linii, możemy pozbyć się nawiasów, przecinków i obcych znaków tylnych i podzielić się na linii nowej, aby uzyskać naszą tablicę. Zastosowanie tego do naszej przykładowej tablicy daje nam następujące możliwości:

`lo¥ipop
Ú\hÚaow
Í
eo`·

Do 26 bajtów teraz.


Krok 2

Ale możemy jeszcze lepiej! Możemy użyć małej litery do rozgraniczenia ciągów zamiast nowej linii, która może zostać uwzględniona w kompresji. znie jest używany w żadnym z naszych ciągów, więc wpuśćmy to i zobaczmy, jak sobie radzimy.

`lo¥ipopzÚ\hÚaowzÍzeo`qz

Ach, orzechy - nie ma poprawy; nasza liczba bajtów wzrosła o jeden! Nie może być inna litera można użyć, ale w zależności od strun, nie może być sporo, aby spróbować - w naszym przykładzie jest 11: b,c,d,f,j,k,q,v,x,y,z. Wypróbowanie każdego z nich byłoby dość żmudne, i tu właśnie pojawia się to przydatne narzędzie ; podaj mu ciągi rozdzielone znakiem nowej linii, a on spróbuje rozgraniczać ciągi każdą literą, która nie jest zawarta w żadnej z nich, i wypisz:

  • najkrótszy skompresowany ciąg,
  • ogranicznik, którego używa, oraz
  • jego długość.

Przeprowadzenie przez nas naszych ciągów próbek pokazuje, że bdaje najlepsze wyniki:

`lo¥ipáæqrÚaowbÍÞo`qb

I masz, mamy tylko 24 bajty.


Krok 3

Ale możemy zrobić jeszcze lepiej! Jeśli kolejność ciągów w tablicy nie ma znaczenia, być może istnieje inna permutacja w połączeniu z innym ogranicznikiem, który może działać jeszcze krócej. Jednak wypróbowanie każdej z tych możliwości będzie znacznie bardziej uciążliwe. Dzięki naszym 4 ciągom możesz wypróbować 24 różne kombinacje. Z każdą z 11 możliwych liter, które stają się 264! Właśnie wtedy to narzędzie wchodzi w grę. Ponownie podaj go jako ciągi rozdzielone znakiem nowej linii, a on wypróbuje każdą kombinację każdej permutacji i każdej litery ograniczającej, generując:

  • kolejność ciągów w najkrótszym skompresowanym ciągu,
  • skompresowany ciąg,
  • ogranicznik, którego używa, oraz
  • jego długość.

Running nasze przykładowe ciągi przez to pokazuje, że "nougat","oreo","lollipop","marshmallow"ze bjako ogranicznik daje najlepsze rezultaty, z ostatecznym rozrachunku tylko 23 bajtów z:

`ÍÞo½o¥ipáæqrÚaow`qb


Dodatkowa wskazówka: Kompresja tablic liczb całkowitych

Możesz zastosować tę samą zasadę do tablic liczb całkowitych, najpierw konwertując każdą z nich na wyższą bazę. Korzystając z tej próbki, tablica 36 bajtów:

[588181,156859,595676,475330,680474]

Możemy to zmniejszyć do 29 bajtów, najpierw konwertując go na tablicę podstawowych ciągów 32, a następnie uruchamiając przez pierwszy program do kompresji:

`huclt4p5r5ÛÊg62tkogq`qt mnH

Lub zaledwie 27 bajtów za pomocą drugiego programu:

`4p5Ïcl5ÛÊg62tkogq`qt mnH

Możesz być w stanie zapisać jeszcze jeden bajt lub 2, przenosząc konwersję liczb całkowitych na metodę, którą już uruchomiłeś na tablicy.


Notatki

  1. Nie zapomnij czynnikiem w 1 lub 2 dodatkowych bajtów q<letter>(<space>)kosztuje ponad ·. Chociaż możesz użyć jednego ze skrótów Unicode, aby odzyskać bajt, w zależności od ogranicznika ( jest taki sam, jak ql<space>na przykład).
  2. Słowo ostrzeżenia przy korzystaniu z ostatniego narzędzia: im więcej masz łańcuchów, tym więcej będzie permutacji i tym wolniej program będzie działał, aż w końcu przestanie działać. Jak wyszczególniono powyżej, z naszymi 4 przykładowymi ciągami znaków i 11 możliwymi literami do wypróbowania, istnieje 264 możliwych kombinacji, zwiększ liczbę ciągów tylko o 1 z tymi samymi 11 literami i mamy już 1320 kombinacji do wypróbowania. (Możesz użyć tego narzędzia, aby policzyć liczbę kombinacji, jeśli chcesz).

Kredyty

  • Oliver za inspirację do stworzenia narzędzi zawartych w tym poradniku.
  • Produkty ETH do korekty.
Kudłaty
źródło
6

Kompresujące struny

Japt (obecnie) używa biblioteki shoco do kompresji ciągów. Możesz skompresować dowolny ciąg znaków Oc, o ile zawiera on ciąg małych liter:

Oc"Hello, World!"

Daje to wynik HÁM, WŽld! (cóż, Žtechnicznie jest to drukowalny charakter). Możesz to zdekompresować, zawijając go w backticks:

`HÁM, WŽld!`

Przetestuj online!

Alternatywnie możesz użyć Odfunkcji do dekompresji dowolnego ciągu. Nie jest to zwykle przydatne, ale ma swoje cele ...

ETHprodukcje
źródło
Więc gdybym odpowiedział „Cześć, świecie!” wyzwanie, czy użyłbym sprawiedliwego, HÁM, WŽld!czy też musiałby być umieszczony w backticksie? Zgaduję to drugie.
Shaggy
2
@Shaggy Odpowiadając na pytanie, musisz dołączyć cały kod, aby był to `HÁM, WŽld! w tym przypadku
Martijn Vissers
6

Skracanie liczb za pomocą kodów char

W Japt możesz użyć #znaku, a następnie znaku, aby utworzyć kod znakowy. Jest to przydatne przy skracaniu dłuższych liczb.

Jak wspomniano w @ETHproductions, działa to tylko w przypadku trzycyfrowych przebiegów w zakresie 100-255, chyba że zechcesz przejść na UTF-8.

Przykłady:

123 można skrócić do #{

101 można skrócić do #e

Możesz nawet połączyć je razem:

123101 można skrócić do #{#e

Możesz użyć String.fromCharCode(123)w JavaScript lub123d Japt, aby znaleźć odpowiedni znak.

String.fromCharCode(123) zwroty {

Oliver
źródło
Dzięki, @obarakon, świetna wskazówka, aby piłka się toczyła; String.fromCharCode()jest jedną z tych (wielu!) nieprzyjemnie długich metod JS, które mogą zwiększyć liczbę bajtów. Przypuszczalnie byłyby to liczby całkowite? tzn. jeśli potrzebuję liczby całkowitej 123w rozwiązaniu, mogę użyć #{do zapisania bajtu.
Kudłaty
1
Tak, to są liczby całkowite. Jeśli dodasz -Qflagę do okna wprowadzania, możesz lepiej wyświetlić typ wyniku: cudzysłowy wokół ciągów , tablic itp.
Oliver
1
Powinieneś wspomnieć, że String.fromCharCode(123)działa w JavaScript, ale możesz to zrobić 123dw Japt, aby uzyskać ten sam wynik ;-) Ponadto działa to tylko na trzycyfrowe przebiegi w zakresie 100- 255(chyba że chcesz przejść na UTF-8)
ETHprodukcje
@ETHproductions Dobry telefon, zaktualizowano!
Oliver
5

Szybka wskazówka: pusta tablica []

Japt ma stałą dla pustego tablicy: A. Ale aby uzyskać do niego dostęp, musisz przygotować średnik ;w swoim programie, aby użyć alternatywnych stałych Japt, w przeciwnym razie Abędzie 10. Stosując tak ;Afaktycznie oferuje oszczędność na 0 bajt [], ale będzie zaoszczędzić bajtów jeśli trzeba przypisać tablicę do zmiennej (np A=[]).

Jeśli jednak (i ​​tylko wtedy) twój program nie pobiera żadnych danych wejściowych, możesz uzyskać dostęp do pustej tablicy za pomocą tylko 1 bajtu, używając Nzmiennej, która jest tablicą danych wejściowych - bez danych wejściowych byłby pusty. Wypróbuj tutaj .

Ma to również tę dodatkową zaletę, że pozwala używać domyślnych stałych wartości w programie, a w niektórych przypadkach może nadal oszczędzać bajtów, ;Anawet jeśli program pobiera dane dzięki skrótom do s1i s2.

Kudłaty
źródło
2
Wow, nie myślałem o użyciu N, fajny pomysł.
ETHprodukcje
2
Niezły, Shaggy!
Oliver
4

Ocena JavaScript

Japt pozwala na wykonanie surowego JavaScript poprzez owijanie go $...$ .

Na przykład, $alert("hello world")$

Można to skrócić, korzystając z automatycznego zamykania $i ).

$alert("hello world")$ można skrócić do $alert("hello world"

Kompresowanie JavaScript

Możesz także skompresować JavaScript za pomocą Ox.

Jeśli istnieje funkcja JavaScript, której chcesz użyć, powiedzmy screen.width, możesz skompresować ciąg "screen.width"za pomocąOc , a następnie wstawić wynik pomiędzy Ox` ... `

Zwróć uwagę, że nie potrzebujesz zamykających cudzysłowów w Japt, jeśli nie następuje po nim nic innego.

Oliver
źródło
@Shaggy Potrzebujesz Oxdo oceny ciągu. W przeciwnym razie po prostu wyślesz tekst "screen.width". Przykład
Oliver
4

Poznaj flagi

Zgodnie z najnowszym meta konsensusem (grudzień 2017 r.) Flagi wiersza polecenia nie są już liczone do bajtów. To naprawdę świetna wiadomość dla Japt, ponieważ ma wiele flag dla dodatkowego leczenia na wejściu / wyjściu.

Wszystkie dostępne flagi w Japt są opisane poniżej, w kolejności oceny . Flagi w tej samej grupie są dla siebie wyłączne. Należy zauważyć, że flagi w różnych grupach może być stosowany w skojarzeniu, w wyniku czegoś podobnego to :)

mdefæ

Cały program jest odwzorowany na pierwszy argument ( U).

Jeśli obecnych jest więcej argumentów, są one przekazywane w stanie, w jakim się znajdują (tzn. Nie są mapowane parami). W przeciwnym razie drugim argumentem jest indeks, a trzecim - podobnie jak cała tablica U.m. Jeśli Ujest liczbą, jest konwertowana na zakres; ciąg znaków jest konwertowany na tablicę znaków, a wyniki są łączone ze sobą.

  • -m: Stosuje powyższe i nic więcej.
  • -d: Zwraca, truejeśli jakiś wynik jest prawdziwy, w falseprzeciwnym razie.
  • -e: Zwraca, truejeśli wszystkie wyniki są zgodne z prawdą, w falseprzeciwnym razie.
  • -f: Zwraca tablicę elementów, Uktórych wyniki są zgodne z prawdą.
  • : Stosuje -fi zwraca swój pierwszy element.

gh

Pobiera element o określonym indeksie.

  • -g: Pobiera pierwszy element (indeks 0).
  • -gX: Pobiera element pod indeksem X(może być dowolną liczbą całkowitą dodatnią).
  • -h: Pobiera ostatni element.

Konwertuj wynik na wartość logiczną.

  • -!: Zastosuj wartość logiczną nie.
  • : Zastosuj wartość logiczną nie dwukrotnie (zwraca prawdziwość).

N

Konwertuj wynik na liczbę. Używany jest unary plus.

PRSQ

Konwertuj na ciąg znaków.

  • -P: Dołącz do tablicy za pomocą "".
  • -R: Dołącz do tablicy za pomocą "\n".
  • -S: Dołącz do tablicy za pomocą " ".
  • -Q: Zastosuj JSON.stringify(może być dowolnym obiektem, nie tylko tablicą). Przykład .

x

Stosuje funkcję xdo wyjścia. (Dosłownie xnie jest to „żadna pojedyncza funkcja małych liter”).

  • Tablica: Suma.
  • Ciąg: Przytnij z obu końców.
  • Liczba: Zaokrąglij do liczby całkowitej.
Bubbler
źródło
2
Zauważ, że użycie flag nie liczy się jako przesłanie Japt, liczy się jako przesłanie Japt-with-these-specific-flags-language.
Nit
3

Skróty Unicode

Istnieje wiele struktur powszechne w Japt które po prostu nie mogą być przechowywane w jednym ASCII char, takie jak qS , p2 , mX{, , itd. Tak więc, aby obejść ten problem, Japt ma „skrótów Unicode”, które są w zakresie znaków \xA1- \xDE( ¡- Þ), które rozszerzają się na te wspólne struktury. Pełną ich listę znajdziesz w dokumentach tłumacza .

Ponadto @oznacza XYZ{i _oznacza Z{Zpomoc w budowaniu funkcji. Zagrajmy więc w nasz przykładowy program z innej odpowiedzi :

UmX{Xc0 s16}

Po pierwsze, możemy wymienić X{Xsię _, co daje nam:

Um_c0 s16}

Wtedy możemy wymienić m_z ®oszczędności kolejny bajt:

U®c0 s16}

Albo możemy wymienić X{z @, co daje nam:

Um@Xc0 s16}

To pozwala nam użyć ¡skrótu do zapisania dwóch bajtów:

¡Xc0 s16}

Jedną z tych dwóch ścieżek można skrócić o 1 bajt więcej niż drugą. Czy możesz dowiedzieć się, który?

ETHprodukcje
źródło
1
®c s16za 6 bajtów - czy mogę wygrać ciasteczko ?!
Kudłaty
@Shaggy Możesz zaoszczędzić jeszcze 1 bajt, jeśli spojrzysz wystarczająco mocno ...;)
ETHproductions
Czy by to ®c sGbylo
Kudłaty
1
Tak! Myślę, że to tak niskie, jak tylko możesz. Dobra robota! :-)
ETHproductions
2
Niesamowite, patrząc wstecz, widząc postęp Japt w ciągu kilku krótkich miesięcy. Można to teraz osiągnąć za pomocą csG.
Shaggy
3

Skorzystaj z predefiniowanych zmiennych

Zmienne A-S są wstępnie ustawione na wspólne wartości, które reprezentują więcej niż jeden bajt w Japt:

  • A- G10-16 .
  • Hjest 32, Ijest 64, Jjest -1, Ljest100 .
  • K jest zdefiniowany jako new Date() , którym można manipulować na różne sposoby.
  • M i O są obiektami o różnych przydatnych funkcjach. Możesz dowiedzieć się więcej w dokumentacji.
  • Pjest pustym ciągiem, Qjest znakiem cudzysłowu, Rjest znakiem nowej linii iS jest spacją.
  • Tjest ustawiony na 0, więc w razie potrzeby można go użyć jako akumulatora.

Jeśli pierwszym znakiem w programie jest średnik ;, A-Lsą resetowane w następujący sposób:

  • A jest pustą tablicą [] .
  • B jest "ABCDEFGHIJKLMNOPQRSTUVWXYZ" .
  • C jest "abcdefghijklmnopqrstuvwxyz" .
  • D jest "QWERTYUIOP\nASDFGHJKL\nZXCVBNM" .
  • Ejest "[a-z]"i Fjest"[A-Za-z]" (przydatne przed dodaniem ich jako funkcji wyrażenia regularnego)
  • Gis 36, His 65i Iis 91(przydatne dla zakresów alfabetu).
  • Jjest pojedynczym przecinkiem; L, pojedynczy okres.

Obecnie tylko A, B, C, i Dz tej listy są naprawdę przydatne. Planuję dodać lepszy system, który pozwala na 256 zmiennych dwubajtowych, które zostaną ustawione na te wartości i wiele więcej.

ETHprodukcje
źródło
3

Użyj funkcji automatycznych

Najprawdopodobniej już to wiesz @i _są to odpowiednio skróty do ( XYZ{i Z{Zopisane w skrótach Unicode) odpowiedzi na ). Ale czasami możesz skrócić funkcje.

Załóżmy, że masz tablicę znaków i chcesz zamapować każdy znak na jego kod znaków. Możesz to zrobić za pomocą jednego z poniższych:

mX{Xc} 
m_c} 

Ale jest lepszy sposób. Jeśli metoda lub operator jest pierwszym elementem po innej metodzie lub a (, zostaje zamieniona na ciąg znaków. Te dwie linie są równoważne:

r'a'b  // Replace all "a"s with "b"s; transpiles to .r("a","b")
ra'b   // Does the same thing, 1 byte less; transpiles to the same thing

Ale jak to pomaga w naszych funkcjach? Cóż, większość metod, które akceptują funkcje, jeśli otrzyma ciąg reprezentujący metodę lub operator, zinterpretuje to jako funkcję. Co oznacza, że ​​możesz to również zrobić:

m_c}  // Map each item to its char code
m'c   // Does the same thing, 1 byte less
mc    // Also does the same thing, 2 bytes less

Nazywam te „funkcjami automatycznymi”. Istnieje kilka różnych odmian:

  • m@Xc}mc
  • m@Xc1}mc1
  • m@X+1}m+1
  • m@1+X}m!+1
  • m@2pX}m!p2

Mam nadzieję, że masz pomysł. Aby zamienić argumenty, po prostu prefiks metody lub operatora za pomocą !.

ETHprodukcje
źródło
Czy warto tutaj zauważyć, że korzystanie z funkcji automatycznych może także pozwolić na dalsze oszczędności dzięki zastosowaniu skrótów? np. m@2pXÃm!p2<space>m!².
Shaggy
Łał! Nie myślałem o użyciu łańcucha na mapie, nawet nie wiedziałem, że to możliwe. Być może zaoszczędzę dzięki temu kilka bajtów w przyszłości.
RedClover,
Hej @ Soaku, jakoś tęskniłem za odpowiedzią z Japtem, więc pozwólcie, że przedłużę wam spóźnione powitanie! Mam nadzieję, że podobało ci się korzystanie z niego do tej pory. Jeśli masz jakieś pytania, sugestie lub po prostu chcesz porozmawiać, dołącz do nas na czacie Japt (Github zwykle działa również przez pierwsze dwa;))
ETHproductions
3

Domniemane przypisanie zmiennej

Za każdym razem, gdy zaczynasz nową linię w Japt, wynik poprzedniej linii jest automatycznie przypisywany do jednej ze zmiennych wejściowych ( U- Z), przy czym pierwszą linią jest Udruga V, i tak dalej.

Weźmy przykład: powiedzmy, że chcesz utworzyć 2 tablice do pracy, z których jedna zawiera liczby 1-10, a druga zawiera ich kwadraty. Dalsza droga do tego byłaby taka:

U=Aõ V=Um² [do something with the arrays]

Jednak przy użyciu automatycznego przypisywania zmiennych można skrócić do:

Aõ
Um²
[do something with the arrays]

Tam zapisaliśmy 4 bajty. Ale w tym przypadku możemy zapisać jeszcze jeden bajt, ponieważ tablica 1-10 jest przypisana Ui Umoże zostać pominięta w niektórych scenariuszach :

Aõ
m²
[do something with the arrays]

Uwaga

Jedną z rzeczy, na które należy uważać, jest to, że nie zastępujesz żadnych zmiennych wejściowych, które mogą być później potrzebne w twoim programie. Można tego uniknąć, pozostawiając jedną lub więcej pustych linii na początku. W poniższym przykładzie 2 tablice zostaną przypisane do zmiennych V& Wzamiast U& V:


Aõ
Vm²
[do something with the arrays]
Kudłaty
źródło
3

Poznaj Javascript

Ponieważ każdy kod Japt działa jako transponowany JS, dobre zrozumienie operatorów JS i wbudowanych metod bardzo pomaga w golfie fragmentów kodu Japt.

Odpowiednie wskazówki JS

[]Vm@...
...
  • Zwarcie
  • Dzielenie za pomocą liczb
    • Można to uogólnić na dowolną metodę, która akceptuje łańcuchy, ale nie liczby. Liczba tam przekazana będzie domyślnie rzutowana na ciąg, często oszczędzając bajt (np. 0Nad '0)

Odpowiednie wbudowane funkcje JS

Przyjrzyj się dokładnie, jakie parametry są przekazywane do argumentów funkcji.

W przypadku metod łańcuchowych dobrze jest wiedzieć, jak różnią się zachowania między przekazywaniem łańcucha lub wyrażenia regularnego z gflagą lub bez .

Bubbler
źródło
3

W razie potrzeby użyj wielu linii

W przypadku większości niezbyt trudnych wyzwań możesz wyrazić rozwiązanie w jednej linii Japt, jako sekwencję stosowania wbudowanych funkcji. Ale bardziej złożone będą wymagać użycia zapętlonych konstrukcji, rekurencji lub ponownego użycia dużych fragmentów kodu. Tutaj pojawia się programowanie wieloliniowe.

Usuń zamykające się pareny

Zadanie : mając tablicę liczb, sparuj każdy element z kwadratem indeksu i posortuj go według sumy.

[5,1,17,9,3] => [[5,0],[1,1],[17,4],[9,9],[3,16]] => [[1,1],[5,0],[9,9],[3,16],[17,4]]

Rozwiązanie jednoliniowe jest íUm@Yp2})ñx, ale })kosztuje dwa bajty (i nie ma skrótu jednobajtowego). Możesz usunąć }), po prostu przesuwając znak końca ñxdo następnego wiersza, aby kod wyglądał następująco:

íUm@Yp2
ñx

a transponowana JS staje się:

U = U.í(U.m(function(X, Y, Z) { return Y.p(2) })); U.ñ("x")

Widać wyraźnie, że robi to to samo, co rozwiązanie jednowierszowe, po prostu przypisując wynik pośredni do U.

Powtórz z niejawnymi argumentami

Funkcja rekurencji ßprzyjmuje wszystko UVWXYZjako domyślny parametr, jeśli nie został określony. Ujest oczywiście głównym wejściem, ale możesz użyć dowolnego z nich, VWXYZaby śledzić inne potrzebne wartości. Na przykład możesz wykonać następujące czynności:

(modify input and implicit assign to U)
(modify V and implicit assign to V)
(test something and call ß without arguments; U and V are passed automatically)

Alternatywnie, jeśli wszystko, czego potrzebujesz, to zmienna tymczasowa, możesz użyć przypisania wbudowanego, takiego (T=...)jak zmiennaT (0) jest rzadko używana jako taka.

Użyj ponownie długiej funkcji

W tym celu nie wydaje mi się, żebym mógł wymyślić dobre przykładowe zadanie, dlatego odwołam się do jedynego rozwiązania, w którym zastosowano tę wskazówkę , i przedstawię kilka ogólnych pomysłów.

  • Aby ponownie użyć funkcji, musisz ją zapisać w zmiennej. Uruchomienie linii z funkcją otwieracza {, @lub _spełnia swoje zadanie. Możesz też zrobić coś takiego, jak (T=@...})osadzić przypisanie funkcji w bardziej złożonym wierszu.
  • Wywołanie zapisanej funkcji nie jest wcale tak proste. Załóżmy, że Vjest funkcją i chcemy wywołać V(U)JS. VUnie działa, ponieważ po prostu oznacza V,U. V(Uteż nie; to jest V,(U). Nawet metody funkcyjne nie są zbyt pomocne. Najlepszym sposobem, jaki znaleźliśmy, jest:
    • [U]xV (mapa i suma), jeśli wynikiem jest liczba
    • UmVif Ujest pojedynczym znakiem i Vzwraca ciąg znaków, lub
    • $V($Ulub [U]mV gogólnie.
  • Mapowanie lub zapętlanie go jest jednak dość łatwe. Aby zmapować tablicę, użyj UmV. Aby znaleźć pierwszą liczbę całkowitą, która spełnia V, użyj Va.
Bubbler
źródło
2

Zabawa z automatycznymi funkcjami

Jako kontynuacja ogólnej wskazówki ETH na temat funkcji automatycznych , ta wskazówka przedstawi kilka konkretnych przykładów sztuczek oszczędzania bajtów, które możesz z nimi osiągnąć, do których dodam, gdy będę myśleć o więcej.


Uzyskaj największą liczbę całkowitą w tablicy.

Załóżmy, że mamy tablicę [3,1,4,2]przypisaną do zmiennej Ui chcemy pobrać z niej największą liczbę. Możemy to zrobić w 4 bajtach, sortując tablicę, a następnie wstawiając ostatni element:

Un o

Minusem jest to, że zmodyfikowaliśmy oryginalną tablicę; Ujest teraz, [1,2,3]co nie zawsze może być pożądane. Na szczęście istnieje sposób, aby to zrobić bez modyfikowania tablicy, która jest także o jeden bajt krótsza:

Urw

To, co tam zrobiliśmy, zmniejsza tablicę za pomocą wmetody, która, gdy zostanie użyta na liczbie całkowitej, zwraca większą liczbę całkowitą i argument metody (np. 2w5Zwraca 5). Więc powyższe jest odpowiednikiem UrÈwYlub UrXY{XwY}. Pamiętaj jednak, że ta wskazówka nie zadziała w przypadku wszystkich liczby całkowite w tablicy będą ujemne.

Kudłaty
źródło
1
Uwaga dodatkowa: Planuję dodać funkcje, aby uzyskać minimalną i maksymalną tablicę, choć prawdopodobnie tylko w wersji 2.
ETHprodukcje
2

Gdy nie należy używaćí

í jest użytecznym wbudowanym parami (lub zip tablic lub ciągów i opcjonalnie mapuje każdą parę za pomocą funkcji. Jednak obecnie ma kilka drobnych problemów, gdy podano nierówne tablice lub ciągi:

  • Jeśli pierwsza tablica zawiera więcej elementów niż druga, nieistniejące elementy w drugiej zostaną podane jako undefined .
  • Jeśli druga tablica zawiera więcej elementów niż pierwsza, przerwie przetwarzanie na końcu pierwszej tablicy.

Może to utrudnić, powiedzmy, porównanie dwóch nierównych ciągów i pobranie znaku z wyższym punktem kodowym z każdej pary. Nawet jeśli wiesz, że Uto będzie dłuższe, nadal zajmuje wiele bajtów, aby rozwiązać to proste zadanie:

UíUç hV @[XY]n o

Zamiast tego możesz wziąć dane wejściowe jako tablicę dwóch ciągów, transponować tablicę za pomocąy , a następnie zamapować każdy wiersz na poprawny wynik:

Uy m_q n o

Ma to tę zaletę, że zawsze wypełnia krótsze sznurki spacjami, dzięki czemu bułka z masłem przechodzi przez całe oba sznurki.

Przykłady z życia: 1 , 2

ETHprodukcje
źródło
2

Wygeneruj zakres ASCII

Aktualizacja: Japt ma teraz stałą dla zakresu ASCII; alternatywna wartość dla E, dostępna za pomocą ;. Zobacz tę wskazówkę aby uzyskać więcej informacji o stałych Japt.

Chociaż Japt nie ma (jeszcze) wbudowanego zakresu ASCII, możesz wygenerować tablicę znaków w zaledwie 5 bajtach:

95odH

Spróbuj


Jak to działa

95otworzy zakres [0,95)z każdym elementem przechodzącym przez funkcję automatyczną, d która, gdy zostanie użyta na liczbie, zwraca znak w tym punkcie kodowym. Przekaż liczbę jako argument dodW tym przypadku metodyH stałą Japt dla 32, a zostanie ona dodana do pierwotnej liczby przed konwersją.

Równoważnym rozwiązaniem w JavaScript byłoby:

[...Array(95)].map((_,x)=>String.fromCharCode(x+32))

Losowe postacie

Aby uzyskać losowy znak z zakresu ASCII, użyj özamiast niego, który zwraca losową liczbę z zakresu [0,X), gdzie Xjest liczbą, na którą jest uruchamiany.

95ö dH

Lub, aby uzyskać tablicę wielu losowych znaków, podaj liczbę znaków, których potrzebujesz, jako argument ö. Poniższe zwróci 10 znaków:

95öA mdH
Kudłaty
źródło
1

Usuń niepotrzebne znaki strukturalne

Przez znaki strukturalnych, to znaczy {}, (), $, nawet "a `. Zazwyczaj możesz usunąć te znaki za każdym razem, gdy wystąpią one bezpośrednio na końcu programu (npUmX{Xc +"; "} -> UmX{Xc +"; .).

Dodatkowo możesz usuwać pareny lub spacje, ilekroć pojawiają się w następujących miejscach:

  • Przeciwko średnikowi ; (lub końcowi programu);
  • Po prawej stronie {(i przez rozszerzenie @) lub [, lub na lewo od ]lub }.

Również przecinki są bardzo rzadko potrzebne do oddzielenia argumentów. Jeśli piszesz ABna przykład Japt wie pan myśli Ai Boddzielnie. Naprawdę potrzebujesz przecinka, aby oddzielić dwa literały liczbowe, takie jakUs2,5 .

Wreszcie, jeśli nie jest to Una początku programu lub po {lub ;, a następnie wywołanie metody (mała litera lub związanych skrótów Unicode) lub dowolnego operatora binarnego bez +i -( *, &, ==, itd.), Można usunąć U, aby zaoszczędzić byte i Japt wstawią go za ciebie.

ETHprodukcje
źródło
Znalazłem kilka innych przypadków, w których Umożna je pominąć, nawet jeśli nie ma go na początku programu.
Kudłaty
@Shaggy No tak, działa również po {lub ;. Czy znasz jeszcze jakieś osoby? (Minęło trochę czasu, odkąd kodowałem tę funkcję: P)
ETHprodukcje
Nie mogę o nich myśleć z góry; Sprawdzę to ponownie, kiedy jutro wrócę do komputera.
Kudłaty
1

Zmodyfikuj ostatni element w tablicy

Czasami może być konieczne zmodyfikowanie ostatniego elementu w tablicy, więc oto wyjaśnienie krótkiego sposobu na zrobienie tego. Będziemy pracować z tablicą [2,4,8,32]przypisaną do zmiennej wejściowej Ui dzieląc ostatnią liczbę całkowitą ( 32) przez 2.

Oczywistym sposobem na osiągnięcie tego byłoby zastosowanie tego 9-bajtowego rozwiązania ( Demo ):

UhJUgJ /2
  • hnxustawia element o indeksie ndo x.
  • gnzwraca element o indeksie n.
  • Jjest stałą Japt dla -1, która dzięki wsparciu Japt dla indeksu ujemnego pozwala nam pracować z ostatnim elementem w tablicy; przydatne, gdy nie znasz rozmiaru tablicy.
  • I /2jest po prostu podzieleniem przez 2.

Więc powyższych zestawów element z indeksem -1w tablicy do elementu o indeksie -1w tablicy podzielonej przez 2. Albo w javascript: U[3]=U[3]/2. Kiedy piszesz to w ten sposób, wydaje się, że jest to zbyt długa droga. Na szczęście jest krótsza droga; moglibyśmy usunąć ostatni element z tablicy, zmodyfikować go i zepchnąć z powrotem do tablicy. Wykonanie każdej z tych operacji osobno zajęłoby więcej niż 9 bajtów, ale możemy wykonać je wszystkie jednocześnie za zaledwie 7 bajtów, co oznacza oszczędność 2 bajtów ( Demo )

UpUo /2

Przetłumaczone na JS, jest to odpowiednik:

U.push(U.pop()/2)&&U
Kudłaty
źródło