Starry to zabawny ezoteryczny język programowania, w którym kod składa się tylko z tego, +*.,`'
gdzie rzeczywiste polecenie reprezentowane przez każdy z tych znaków jest określone przez liczbę spacji przed nim. To sprawia, że jest to trudne nawet dla golfowych wyzwań o stałym wyjściu, ponieważ różne polecenia mogą uwzględniać bardzo różną liczbę bajtów. W szczególności literały liczbowe mają jednoznaczną reprezentację, co powoduje, że konieczne jest budowanie większych liczb, operując na mniejszych.
Dlatego wyzwanie polega na napisaniu programu, który może zagrać w golfa w takich programach Starry.
Jak działa Starry?
(Kilka szczegółów pozostało nieokreślonych w esolangach, więc idę z zachowaniem interpretera Ruby .)
Starry to język oparty na stosie, z pojedynczym stosem liczb całkowitych o dowolnej dokładności (który początkowo jest pusty).
Jedynymi znaczącymi postaciami są:
+*.,`'
i spacje. Wszystkie pozostałe znaki są ignorowane. Każda sekwencja spacji, po której następuje jeden z tych spacji, reprezentuje pojedynczą instrukcję. Rodzaj instrukcji zależy od znaku spacji i liczby spacji.
Instrukcje są następujące:
Spaces Symbol Meaning
0 + Invalid opcode.
1 + Duplicate top of stack.
2 + Swap top 2 stack elements.
3 + Rotate top 3 stack elements. That is, send the top stack element
two positions down. [... 1 2 3] becomes [... 3 1 2].
4 + Pop and discard top of stack.
n ≥ 5 + Push n − 5 to stack.
0 mod 5 * Pop y, pop x, push x + y.
1 mod 5 * Pop y, pop x, push x − y.
2 mod 5 * Pop y, pop x, push x * y.
3 mod 5 * Pop y, pop x, push x / y, rounded towards -∞.
4 mod 5 * Pop y, pop x, push x % y. The sign of the result matches the sign of y.
0 mod 2 . Pop a value and print it as a decimal number.
1 mod 2 . Pop a value and print it as an ASCII character. This throws an error
if the value is not in the range [0, 255].
n ` Mark label n.
n ' Pop a value; if non-zero, jump to label n.
Zauważ, że interpreter skanuje kod źródłowy w celu znalezienia etykiet przed rozpoczęciem wykonywania, więc można przeskakiwać zarówno do przodu, jak i do tyłu.
Oczywiście Starry ma również komendy wejściowe (przy użyciu ,
analogicznej metody .
), ale są one nieistotne dla tego wyzwania.
Wyzwanie
Biorąc pod uwagę ciąg, wygeneruj program Starry, który nie pobiera danych wejściowych i drukuje dokładnie ten ciąg do STDOUT.
Możesz napisać program lub funkcję, pobierając dane wejściowe przez STDIN (lub najbliższą alternatywę), argument wiersza poleceń lub argument funkcji i wypisując wynik przez STDOUT (lub najbliższą alternatywę), wartość zwracaną funkcji lub parametr funkcji (wyjściowej).
Możesz założyć, że łańcuch nie ma więcej niż 128 znaków i że będzie się składał tylko z drukowalnych znaków ASCII (punkty kodowe od 0x20 do 0x7E).
Twoje rozwiązanie powinno przetworzyć takie dane w mniej niż 5 minut na rozsądnej maszynie stacjonarnej (istnieje pewna swoboda; jeśli zajmie to jeszcze kilka minut na moim laptopie, nie mam nic przeciwko, ale jeśli zajmie to 15, zdyskwalifikuję to).
Twoje rozwiązanie zostanie przetestowane na kilku różnych ciągach wymienionych poniżej. Twój wynik to całkowita liczba bajtów odpowiednich programów Starry. W przypadku remisu wygrywa najkrótszy metagolfer. Oznacza to, że nie zawracaj sobie głowy graniem własnym kodem, chyba że jest remis (co, jak sądzę, nastąpi tylko w przypadku, gdy możliwe jest optymalne rozwiązanie).
Nie wolno optymalizować kodu pod kątem konkretnych przypadków testowych wymienionych poniżej. W szczególności nie powinieneś tworzyć dla nich ręcznie opracowanych rozwiązań. Optymalizacja w kierunku klas ciągów, których struktura jest podobna do danej ciągów, jest w porządku. Jeśli podejrzewam kogokolwiek o rozwiązania na sztywno, zastrzegam sobie prawo do zastąpienia niektórych lub wszystkich przypadków testowych (ciągami porównywalnych struktur).
Przypadki testowe
Każda linia to osobny przypadek testowy:
Hello, World!
pneumonoultramicroscopicsilicovolcanoconiosis
.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.
Hickory, dickory, dock. The mouse ran up the clock. The clock struck 1. The mouse ran down. Hickory, dickory, dock.
36912059868043514648560046917066768694455682545071266675083273015450033938555319356951628735735013250100789433961153496780296165
bVZ48121347GLtpYnt76CZSxTpMDs6791EJE808077eySXldY162424ddTB90707UupwlWGb63618542VhA252989453TXrWgqGm85899uHOAY2oAKE198GOVUttvW63
7MYxoWBNt180CDHS5xBGvU70HHVB17bh8jYzIIiU6n6g98Rose1nOe8Svcg56nax20q30kT3Ttb2jHl5q2Iuf1vPbjPxm9cyKXwxc0OUK8pr13b2n7U9Y7RwQTc26A1I
n9}unwxVa}[rj+5em6K#-H@= p^X/:DS]b*Jv/_x4.a5vT/So2R`yKy=in7-15B=g _BD`Bw=Z`Br;UwwF[{q]cS|&i;Gn4)q=`!G]8"eFP`Mn:zt-#mfCV2AL2^fL"A
Kredyty za drugi przypadek testowy trafiają do Dennisa . Kredyty za czwarty przypadek testowy trafiają do Sp3000.
Rozwiązanie referencyjne
Oto naprawdę podstawowe rozwiązanie referencyjne w CJam:
q{S5*\iS*'+S'.}%
Możesz uruchomić go tutaj dla całego zestawu testów. Wyniki są następujące:
1233
5240
4223
11110
7735
10497
11524
11392
Total: 62954
Jest to najprostsze możliwe podejście: przesuń punkt kodowy każdego znaku dosłownie, a następnie wydrukuj go. Nie wykorzystuje małych różnic między kolejnymi znakami, drukowania liczb całkowitych, powtarzających się części łańcucha itp. Zostawię to wam.
Uważam, że jest wiele miejsca na ulepszenia. Dla porównania, najkrótszy ręcznie „Witaj, świecie!” ma tylko 169 bajtów.
JavaScript,
2515823778Teraz kompatybilny z ES5!
Wyniki:
Moim zdaniem dobry początek, ale oczywiście nie skończony. Zamiast tworzyć każdy znak osobno, dodaje lub odejmuje poprzedni kod znaków. Dodam pełne wyjaśnienie, kiedy skończę grać w golfa.
źródło
charCodeAt
.