Istnieje 95 znaków ASCII do wydrukowania :
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
W czcionce Consolas (domyślnie blok kodu Stack Exchange) niektóre znaki mają odbicia lustrzane wokół pionowej osi symetrii:
- Te pary znaków są wzajemnie zwierciadłami:
()
[]
{}
<>
/\
- Te postacie są zwierciadłami samych siebie:
! "'*+-.8:=AHIMOTUVWXY^_ovwx|
(Zwróć uwagę, że spacja to jeden). - Nie mają kopii lustrzanych:
#$%&,012345679;?@BCDEFGJKLNPQRSZ`abcdefghijklmnpqrstuyz~
( i
, l
, 0
, #
, I prawdopodobnie inne znaki są ich własne lusterka w niektórych czcionek, ale będziemy trzymać się kształtów Consolas).
Mówi się, że łańcuch jest zwierciadłem samym w sobie, jeśli składa się tylko z 39 znaków zwierciadlanych , ułożonych w taki sposób, że łańcuch ma środkową pionową linię symetrii. Tak samo ](A--A)[
jest zwierciadłem, ale nim ](A--A(]
nie jest.
Napisz jednoliniowy program o parzystej długości, który jest zwierciadłem samego siebie. Kiedy N kopii jego lewej połowy zostało do niego dołączonych, a N kopii jego prawej połowy zostało do niego dołączonych, powinno wyprowadzać N + 1. N jest nieujemną liczbą całkowitą.
Na przykład, jeśli program był ](A--A)[
(lewa połowa:, ](A-
prawa połowa:) -A)[
, to:
- Uruchomienie
](A--A)[
powinno dać wynik1
. (N = 0) - Uruchomienie
](A-](A--A)[-A)[
powinno dać wynik2
. (N = 1) - Uruchomienie
](A-](A-](A--A)[-A)[-A)[
powinno dać wynik3
. (N = 2) - Uruchomienie
](A-](A-](A-](A--A)[-A)[-A)[-A)[
powinno dać wynik4
. (N = 3) - . . .
- Uruchomienie
](A-](A-](A-](A-](A-](A-](A-](A-](A-](A--A)[-A)[-A)[-A)[-A)[-A)[-A)[-A)[-A)[-A)[
powinno dać wynik10
. (N = 9) - itp.
Zasady
- Wyjście na standardowe wyjście lub najbliższą alternatywę dla twojego języka. Może występować opcjonalny znak nowej linii. Nie należy pobierać żadnych danych wejściowych.
- Proces powinien teoretycznie działać dla N do 2 15 -1 lub więcej, biorąc pod uwagę wystarczającą pamięć i moc obliczeniową.
- Wymagany jest pełny program, a nie tylko polecenie REPL .
Najkrótszy program początkowy (przypadek N = 0) w bajtach wygrywa.
źródło
#
jest to również jego własna relacja, ale masz rację, nie w konsolach.Odpowiedzi:
Pip,
1284 bajtówTeraz z 66% mniej bajtów!
x
jest zmienną, zainicjalizowaną do""
. W kontekście numerycznym staje się to0
.+
, wyraża formęx+x+...+x
. To prawidłowe stwierdzenie, które nic nie robi.+
z pierwszej połowy, stanowi wyraz formy++x+x+...+x
.++x
Przyrostyx
się1
, a resztę dodaje go do siebie n razy. Ponieważ wyrażenia są oceniane od lewej do prawej w Pip, przyrost jest gwarantowany jako pierwszy, a wynik jest równy liczbie poziomów lustrzanych.Niestety, Pip nie radzi sobie dobrze z przetwarzaniem dużych wyrażeń: to rozwiązanie powoduje
maximum recursion depth exceeded
błąd dla N powyżej około 500. Oto poprzednie rozwiązanie, które nie obejmuje 8 bajtów :Więcej na Pip
źródło
Fatal error: maximum recursion depth exceeded while calling a Python object
.x+x+...+x
generuje głębokość rekurencji O (N). Może to unieważnia tę odpowiedź. Dodam notatkę.GolfScript, 10 bajtów
Wypróbuj online z Web Golfscript: N = 0 , N = 1 , N = 2 , N = 3 , N = 41
Web GolfScript ma limit 1024 znaków, ale interpreter języka Ruby doskonale radzi sobie z N = 32767 :
Jak to działa
Bez żadnych danych GolfScript początkowo ma pusty ciąg znaków na stosie.
W pierwszej lewej połowie dzieje się tak:
!
stosuje logiczne NIE do pustego ciągu. To popycha1
.:{
zapisuje liczbę całkowitą na stosie w zmiennej{
.Tak, jest to prawidłowy identyfikator, chociaż nie ma możliwości odzyskania zapisanej wartości.
)
zwiększa liczbę całkowitą na stosie.:
jest niepełną instrukcją.Kolejne lewe połowy następują:
:!
(gdzie:
jest pozostałość po wcześniejszym) zapisuje liczbę całkowitą na stosie w zmiennej!
.Tak, to także prawidłowy identyfikator. To łamie
!
polecenie, ale już go nie używamy.:{
,)
A:
praca jak wcześniej.W pierwszej prawej połowie następują:
::
(gdzie:
jest pozostałość po wcześniejszym) zapisuje liczbę całkowitą na stosie w zmiennej:
.Tak, nawet to jest prawidłowy identyfikator. Podobnie jak w przypadku
{
, nie ma możliwości odzyskania zapisanej wartości.(
zmniejsza liczbę całkowitą na stosie, uzyskując liczbę lewych połówek.}
, ponieważ nie ma sobie równych i natychmiast kończy wykonywanie.Jest to funkcja nieudokumentowana. Nazywam je przesądami .
Pozostały kod jest po prostu ignorowany.
źródło
}
w drugiej połowie kodu w konkursie lustrzanym."\""/"
czwartym podwójnym cudzysłowie również byłby nieporównywalny, ponieważ drugi uciekł.Kod maszynowy Z80,
86 bajtów *<8ww8>
* Przyjmuje określone warunki, wchodząc z Amstrad BASICA
początkowo wynosi 0 po wprowadzeniu z BASIC. PrzyrostyA
n razy, a następnie zapisuje n razy do tej samej lokalizacji w pamięci (która jest ustawiona przez BASIC na nieco losową lokalizację)! OperacjaJR
Jump Relative nigdy nie robi nic, ponieważC
flaga jest zawsze rozbrojona, dlatego służy do „komentowania” następującego bajtu! Ta wersja nieco oszukuje, zakładając pewne warunki wejścia, a mianowicie wejście z gwarancji BASIC, któraA
zawsze wynosi 0. Lokalizacja(HL)
nie jest gwarantowana jako bezpieczna, aw rzeczywistości jest to prawdopodobnie niebezpieczne miejsce. Poniższy kod jest znacznie bardziej niezawodny, dlatego jest o wiele dłuższy.Kod maszynowy Z80, 30 bajtów
Jako ASCII:
o!.ww.!>A=o>{))((}<o=A<!.ww.!o
Zasadniczo pierwsza połowa gwarantuje utworzenie wartości zerowej, a druga połowa zwiększa ją i zapisuje w pamięci. W rozszerzonej wersji poniżej
##
oznacza kod, który nie służy żadnemu celowi w jego połowie lustra.Podział dozwolonych instrukcji:
Spośród 39 dozwolonych instrukcji 28 to operacje ładowania (blok od 0x40 do 0x7F to
LD
instrukcje jednobajtowe ), z których większość tutaj nie pomaga! Jedyne dozwolone ładowanie do pamięci jest nadal dozwolone,LD (HL), A
co oznacza, że muszę zapisać wartość wA
. PonieważA
jest to jedyny rejestr z dozwolonąINC
instrukcją, jest to całkiem przydatne!Nie mogę załadować
A
z 0x00, ponieważ ASCII 0x00 nie jest dozwolonym znakiem! Wszystkie dostępne wartości są dalekie od 0, a wszystkie instrukcje matematyczne i logiczne zostały niedozwolone! Z wyjątkiem ... Nadal mogęADD HL, HL
, dodaj 16-bitHL
do siebie! Oprócz bezpośredniego ładowania wartości (tutaj nie ma zastosowania!), INKrementacjiA
i DECrementacjiA
,L
lubHL
to jest jedyny sposób na zmianę wartości rejestru! W rzeczywistości jest jedna specjalistyczna instrukcja, która może być pomocna w pierwszej połowie, ale kłopot z obejściem w drugiej połowie, i instrukcja uzupełniająca, która jest prawie bezużyteczna tutaj i zajmuje tylko miejsce.Znalazłem więc najbliższą wartość 0, którą mogłem: 0x41. Jak to jest bliskie zeru? W systemie binarnym jest to 0x01000001. Więc zmniejszam, ładuję
L
i robięADD HL, HL
dwa razy!L
ma teraz zero, do którego ładuję ponownieA
! Niestety kod ASCII dlaADD HL, HL
jest,)
więc muszę teraz użyć(
dwa razy. Na szczęście(
jestJR Z, e
, gdziee
jest następny bajt. Więc pożera drugi bajt i muszę tylko upewnić się, że nic nie zrobi, uważając naZ
flagę! Ostatnią instrukcją, która wpłynęła naZ
flagę, byłaDEC A
(sprzeczna z intuicją,ADD HL, HL
nie zmienia jej), a ponieważ wiem, żeA
w tym momencie była to 0x40, jest pewna, żeZ
nie jest ustawiona.Pierwsza instrukcja w drugiej połowie
JR Z, #28
nic nie zrobi przez pierwsze 255 razy, ponieważ flagę Z można ustawić tylko wtedy, gdy A przepełniło się z 255 do 0. Następnie dane wyjściowe będą błędne, jednak ponieważ i tak zapisuje tylko wartości 8-bitowe nie powinno mieć znaczenia. Kod nie powinien być rozszerzany więcej niż 255 razy.Kod musi zostać wykonany jako fragment kodu, ponieważ wszystkie dostępne sposoby czystego powrotu zostały niedozwolone. Wszystkie instrukcje RETurn są powyżej 0x80, a kilka dozwolonych operacji Jump może przeskoczyć tylko do dodatniego przesunięcia, ponieważ wszystkie 8-bitowe wartości ujemne zostały również niedozwolone!
źródło
A
Rejestr jest zawsze 8 bitów, w przeciwnym razie nie byłoby procesor kompatybilny z Z80. Powiedziałbym, że biorąc pod uwagę wystarczającą pamięć i moc obliczeniową , zostało to tutaj pokryte!A
rejestru innego niż 8 bitów? Zmiana na 16-bitową złamałaby kod polegający na przykład na 255 + 1 = 0. Trzeba wymyślić procesor, nazwijmy go Z160, który używa domyślnego rejestru 16-bitowego, ale nadal używa tego samego zestawu instrukcji 8-bitowych z Z80. Dziwne!J,
1614 bajtówZastosowania:
Wyjaśnienie:
J ocenia od prawej do lewej.
(_=_)
jestinf equals inf
prawdą, ma wartość1
, więc wyrażenie staje się1+]...[+1
. ((8=8)
również by działało, ale wygląda to fajniej. :))[
i]
zwracają odpowiednio lewy i prawy argument, jeśli mają 2 argumenty. Jeśli otrzymają tylko 1, zwracają to.+
dodaje 2 argumenty. Jeśli otrzyma tylko 1, zwraca to.Teraz oceńmy wyrażenie poziomu 3 (od prawej do lewej):
Jak widzimy, dodaje się prawą połowę z nich
1
, a lewą stronę z nich1
pomija się, co daje pożądaną liczbę całkowitąN
, poziom lustra.Wypróbuj online tutaj.
źródło
Haskell, 42 bajty
Na szczęście komentarz liniowy w Haskell (->
--
) jest dublowany, a połowa (->-
) jest prawidłową funkcją. Reszta to trochę matematyki, aby uzyskać liczby0
i1
. Zasadniczo mamy(0)-(-1)
komentarzN=0
i dopisujemy(0)-(-1)-
na każdym etapie.W przypadku liczb zmiennoprzecinkowych są dopuszczone do produkcji, możemy budować
1
od8/8
i dostać się z 26 bajtów:Haskell, 26 bajtów
Wyjścia
1.0
,2.0
itpźródło
program.hs
a następnie uruchomić$ runhaskell program.hs
z wiersza poleceń i zobaczyć wynik. Nie znam Haskella, więc nie mogę powiedzieć dokładnie, co należy zmienić.runhaskell
to skrypt powłoki, który konfiguruje środowisko i wreszcie wywołujeghc
kompilator Haskell. Można uruchomić bezpośrednio z mojego kodughc
:ghc -e "(8-8)-(-8/8)--(8\8-)-(8-8)"
. Uruchamia się,ghc
które ocenia kod podany jako argument, drukuje wynik i kończy działanie. Bez REPL, bez interakcji. Oczywiście dodałoby to +1 do liczby bajtów dla-e
.-e
w tym przypadku nie wpływa na wynik. Nie liczymy bajtówperl -E
anigcc -std=c99
żadnego z nich.CJam, 14 bajtów
Wypróbuj online w interpretatorze CJam: N = 0 , N = 1 , N = 2 , N = 3 , N = 41
Pamiętaj, że ten kod kończy się komunikatem o błędzie. Za pomocą interpretera Java ten komunikat o błędzie można ukryć, zamykając lub przekierowując STDERR. 1
Jak to działa
W lewej połowie dzieje się:
]
otacza cały stos w tablicę.X
dołącza się1
do tej tablicy.:+
oblicza sumę wszystkich elementów tablicy.Oo
wypisuje zawartość pustej tablicy (tzn. nic).W pierwszej prawej połowie następują:
o
wypisuje liczbę całkowitą na stosie, która jest pożądanym wyjściem.O+
próbuje dołączyć pustą tablicę do najwyższego elementu stosu.Jednak stos był pusty przed wypchnięciem
O
. To kończy się niepowodzeniem i kończy działanie programu.Pozostały kod jest po prostu ignorowany.
1 Według meta-ankiety Czy należy zezwolić na przesyłanie zgłoszeń z błędem? jest to dozwolone.
źródło