Jednym z najczęstszych standardowych zadań (szczególnie podczas prezentacji ezoterycznych języków programowania) jest wdrożenie „programu cat” : odczytanie całego STDIN i wydrukowanie go do STDOUT. Chociaż nazwa pochodzi od narzędzia powłoki Unix cat
, jest oczywiście znacznie mniej wydajna niż rzeczywista, która zwykle służy do drukowania (i łączenia) kilku plików odczytanych z dysku.
Zadanie
Powinieneś napisać pełny program, który odczytuje zawartość standardowego strumienia wejściowego i zapisuje je dosłownie do standardowego strumienia wyjściowego. Jeśli i tylko wtedy, gdy Twój język nie obsługuje standardowych strumieni wejściowych i / lub wyjściowych (jak rozumie się je w większości języków), możesz zamiast tego uznać te terminy za ich najbliższe odpowiedniki w twoim języku (np. JavaScript prompt
i alert
). Są to jedyne dopuszczalne formy We / Wy, ponieważ każdy inny interfejs w dużym stopniu zmieni charakter zadania i sprawi, że odpowiedzi będą znacznie mniej porównywalne.
Dane wyjściowe powinny zawierać dokładnie dane wejściowe i nic więcej . Jedynym wyjątkiem od tej reguły jest stałe wyjście interpretera twojego języka, którego nie można stłumić, takie jak powitanie, kody kolorów ANSI lub wcięcia. Dotyczy to również końcowych znaków nowej linii. Jeśli dane wejściowe nie zawierają końcowego nowego wiersza, dane wyjściowe również nie powinny zawierać jednego! (Jedynym wyjątkiem jest sytuacja, gdy Twój język absolutnie zawsze drukuje końcowy znak nowej linii po wykonaniu).
Dane wyjściowe do standardowego strumienia błędów są ignorowane, o ile standardowy strumień wyjściowy zawiera oczekiwane dane wyjściowe. W szczególności oznacza to, że Twój program może zakończyć się z błędem po uderzeniu w koniec strumienia (EOF), pod warunkiem, że nie zanieczyszcza standardowego strumienia wyjściowego. Jeśli to zrobisz, zachęcam do dodania wersji bezbłędnej do odpowiedzi (w celach informacyjnych).
Ponieważ jest to wyzwanie w ramach każdego języka, a nie między językami, istnieje kilka zasad specyficznych dla języka:
- Jeśli w twoim języku jest w ogóle możliwe rozróżnienie bajtów pustych w standardowym strumieniu wejściowym od EOF, twój program musi obsługiwać bajty zerowe, jak wszystkie inne bajty (to znaczy, że muszą być również zapisane w standardowym strumieniu wyjściowym).
- Jeśli w Twoim języku jest w ogóle możliwe obsługiwanie dowolnego, nieskończonego strumienia wejściowego (tj. Jeśli możesz rozpocząć drukowanie bajtów na wyjściu, zanim trafisz EOF na wejściu), twój program musi w tym przypadku działać poprawnie. Jako przykład
yes | tr -d \\n | ./my_cat
należy wydrukować nieskończony strumieńy
s. Od Ciebie zależy, jak często drukujesz i opróżniasz standardowy strumień wyjściowy, ale musisz zagwarantować, że stanie się to po upływie określonego czasu, niezależnie od strumienia (oznacza to w szczególności, że nie możesz czekać na określony znak, taki jak wysuw linii przed drukowaniem).
Dodaj notatkę do swojej odpowiedzi na temat dokładnego zachowania w odniesieniu do bajtów zerowych, nieskończonych strumieni i zewnętrznych danych wyjściowych.
Dodatkowe zasady
Nie chodzi o znalezienie języka z najkrótszym rozwiązaniem tego problemu (są takie, w których pusty program rozwiązuje problem) - chodzi o znalezienie najkrótszego rozwiązania w każdym języku. Dlatego żadna odpowiedź nie zostanie oznaczona jako zaakceptowana.
Zgłoszenia w większości języków będą oceniane w bajtach w odpowiednim wcześniej istniejącym kodowaniu, zwykle (ale niekoniecznie) UTF-8.
Niektóre języki, takie jak Foldery , są trudne do zdobycia. W razie wątpliwości proszę pytać na Meta .
Możesz swobodnie korzystać z języka (lub wersji językowej), nawet jeśli jest on nowszy niż to wyzwanie. Języki napisane specjalnie w celu przesłania 0-bajtowej odpowiedzi na to wyzwanie są uczciwą grą, ale nie są szczególnie interesujące.
Pamiętaj, że musi być tłumacz, aby można było przetestować zgłoszenie. Dozwolone jest (a nawet zachęcane) samodzielne pisanie tego tłumacza dla wcześniej niewdrożonego języka.
Należy również pamiętać, że języki nie muszą spełniać nasze zwykłe kryteria dla języków programowania .
Jeśli twój wybrany język jest trywialną odmianą innego (potencjalnie bardziej popularnego) języka, który ma już odpowiedź (pomyśl dialekty BASIC lub SQL, powłoki Unix lub trywialne pochodne Brainfuck, takie jak Headsecks lub Unary), rozważ dodanie uwagi do istniejącej odpowiedzi, która: to samo lub bardzo podobne rozwiązanie jest również najkrótsze w innym języku.
O ile nie zostały one wcześniej anulowane, obowiązują wszystkie standardowe zasady gry w golfa , w tym http://meta.codegolf.stackexchange.com/q/1061 .
Na marginesie, proszę nie głosować nudnych (ale ważnych) odpowiedzi w językach, w których nie ma wiele do golfa; są one nadal przydatne w tym pytaniu, ponieważ próbuje skompilować katalog tak kompletny, jak to możliwe. Jednak przede wszystkim oceniaj odpowiedzi w językach, w których autor musiał włożyć wysiłek w golfa kodu.
Katalog
Fragment kodu na dole tego postu generuje katalog na podstawie odpowiedzi a) jako listy najkrótszych rozwiązań według języka oraz b) jako ogólnej tabeli wyników.
Aby upewnić się, że twoja odpowiedź się pojawi, zacznij od nagłówka, korzystając z następującego szablonu Markdown:
## Language Name, N bytes
gdzie N
jest rozmiar twojego zgłoszenia. Jeśli poprawić swój wynik, to może zachować stare porachunki w nagłówku, uderzając je przez. Na przykład:
## Ruby, <s>104</s> <s>101</s> 96 bytes
Jeśli chcesz umieścić w nagłówku wiele liczb (np. Ponieważ twój wynik jest sumą dwóch plików lub chcesz osobno wymienić kary za flagi tłumacza), upewnij się, że rzeczywisty wynik jest ostatnią liczbą w nagłówku:
## Perl, 43 + 2 (-p flag) = 45 bytes
Możesz także ustawić nazwę języka jako link, który pojawi się we fragmencie:
## [><>](http://esolangs.org/wiki/Fish), 121 bytes
cat
sh
odpowiedź przy użyciu,cat
która zawiera również krótsze rozwiązanie przy użyciudd
.)Odpowiedzi:
sed, 0
Pusty
sed
program wykonuje dokładnie to, co jest wymagane tutaj:źródło
yes | tr -d \\n | sed ''
?yes
nad jednym buforem wzorca, aż zabraknie pamięci. Zastrzeżenie, jak sądzę ...Ziim ,
222201196185182 bajtówPrawdopodobnie nie wyświetli się to poprawnie w przeglądarce, więc oto schemat kodu:
Nie mogę wymyślić prostszej struktury, która rozwiązałaby problem w Ziim, ale jestem pewien, że rzeczywisty kod jest wciąż grywalny.
Ziim nie jest w stanie obsługiwać nieskończonych strumieni, ponieważ możliwe jest wydrukowanie czegokolwiek na końcu programu.
Wyjaśnienie
Ponieważ Ziim ma raczej unikalny, deklaratywny model przepływu sterowania, algorytm imperatywnego pseudokodu nie będzie go tutaj wycinał. Zamiast tego wyjaśnię podstawy Ziim i przedstawię uporządkowaną strukturę powyższego kodu (w podobny sposób graficzny) jak w sztuce ASCII.
Przepływ sterowania w Ziim odbywa się wszędzie: każda strzałka, na którą nie wskazuje inna strzałka, inicjuje „wątek”, który jest przetwarzany niezależnie od innych (nie tak naprawdę równolegle, ale nie ma gwarancji, w jakiej kolejności są przetwarzane , chyba że zsynchronizujesz je poprzez konkatenację). Każdy taki wątek zawiera listę cyfr binarnych, zaczynając od
{0}
. Teraz każda strzałka w kodzie jest rodzajem polecenia, które ma jedno lub dwa wejścia i jedno lub dwa wyjścia. Dokładne polecenie zależy od tego, ile strzałek wskazuje na którą orientację.Oto lista poleceń, gdzie
m -> n
wskazuje, że polecenie pobieram
dane wejściowe i generuje danen
wyjściowe.1 -> 1
, no-op : po prostu przekierowuje wątek.1 -> 1
, invert : neguje każdy bit w wątku (a także przekierowuje go).1 -> 1
, czytaj : zamienia wartość wątku na następny bit ze STDIN lub na pustą listę, jeśli trafiliśmy EOF.2 -> 1
, concatenate : jest to jedyny sposób synchronizacji wątków. Gdy nić trafi w jedną stronę strzałki, zostanie zawieszona, aż inny nić trafi w drugą stronę. W tym momencie zostaną one połączone w jeden wątek i będą kontynuowane wykonywanie.2 -> 1
, etykieta : jest to jedyny sposób łączenia różnych ścieżek wykonania. Jest to po prostu brak możliwości, który ma dwa możliwe wejścia. Tak więc wątki wpisujące się na „etykietę” dowolną drogą zostaną po prostu przekierowane w tym samym kierunku.1 -> 2
, split : pobiera pojedynczy wątek i wysyła dwie kopie w różnych kierunkach.1 -> 1
, isZero? : zużywa pierwszy bit wątku i wysyła wątek w jednym z dwóch kierunków, w zależności od tego, czy bit miał wartość 0 czy 1.1 -> 1
, jest pusty? : zużywa całą listę (tj. zastępuje ją pustą listą) i wysyła wątek w jednym z dwóch kierunków, w zależności od tego, czy lista była już pusta, czy nie.Mając to na uwadze, możemy opracować ogólną strategię. Za pomocą konkatenatu chcemy wielokrotnie dołączać nowe bity do łańcucha reprezentującego całe wejście. Możemy to po prostu zrobić, zapętlając wyjście konkatenatu z powrotem do jednego z jego danych wejściowych (i inicjujemy to do pustej listy, usuwając za
{0}
pomocą isEmpty? ). Pytanie brzmi, jak możemy zakończyć ten proces.Oprócz dołączenie aktualnego trochę będziemy również poprzedzić 0 lub 1, ze wskazaniem, czy dotarliśmy EOF. Jeśli wyślemy nasz ciąg przez isZero? , ponownie pozbędzie się tego bitu, ale wyróżnijmy koniec strumienia, w którym to przypadku po prostu pozwalamy, aby wątek opuścił krawędź siatki (co powoduje, że Ziim drukuje zawartość wątku do STDOUT i kończy działanie programu) .
Czy osiągnęliśmy EOF, czy nie, można ustalić za pomocą isEmpty? na kopii danych wejściowych.
Oto schemat, który obiecałem:
Kilka uwag o tym, od czego zacząć czytanie:
{0}
lewym górnym rogu znajduje się początkowy wyzwalacz, który rozpoczyna pętlę wejściową.{0}
prawym górnym rogu jest natychmiast usuwane do pustej listy i reprezentuje początkowy ciąg, który będziemy stopniowo wypełniać dane wejściowe.{0}
są wprowadzane do pętli „producenta” (jedna odwrócona, druga nie), aby zapewnić nam nieograniczoną podaż0
si i1
s, które musimy przyłożyć do łańcucha.źródło
Sześciokąt , 6 bajtów
Kiedyś były to 3 bajty (patrz poniżej), ale ta wersja nie działa już od ostatniej aktualizacji języka. Ponieważ nigdy celowo nie wprowadziłem błędu, z którego korzystała wersja, postanowiłem go nie liczyć.
Rozwiązanie bezbłędne (tj. Działające ze stałym interpreterem) okazuje się znacznie trudniejsze. Mam problem z wciśnięciem go w siatkę 2x2, ale teraz znalazłem jedno rozwiązanie, chociaż potrzebuję pełnych 7 bajtów :
Po rozłożeniu otrzymujemy:
Ponieważ początkowa krawędź pamięci wynosi 0,
<
bezwarunkowo odchyla wskaźnik instrukcji do przekątnej północno-wschodniej, gdzie opada na szarą ścieżkę. To.
jest brak op. Teraz,
odczytuje bajt,)
zwiększa go tak, aby prawidłowe bajty (w tym bajty puste) były dodatnie, a EOF wynosi 0.Tak więc w EOF adres IP jest zawijany na czerwoną ścieżkę, gdzie
@
kończy program. Ale jeśli nadal czytamy bajt, IP zawija się na zielonej ścieżce, a zamiast tego(
zmniejsza krawędź do pierwotnej wartości, zanim;
drukuje ją do STDOUT. Adres IP teraz bezwarunkowo wraca do szarej ścieżki, powtarzając ten proces.Po napisaniu skryptu brute force dla mojej odpowiedzi Truth Machine, ustawiłem go tak, aby znalazł bezbłędne 6-bajtowe rozwiązanie dla programu cat. O dziwo, znalazło jedno - tak, dokładnie jedno rozwiązanie we wszystkich możliwych 6-bajtowych programach Hexagony. Po 50 rozwiązaniach z maszyny prawdy było to dość zaskakujące. Oto kod:
Rozkładanie:
Zastosowanie
~
(unarnej negacji) zamiast()
jest interesujące, ponieważ a) jest to zero na zero, b) zamienia boki gałęzi, c) w niektórych kodach jeden~
może być użyty dwukrotnie, aby cofnąć operację z samym sobą . Oto, co się dzieje:Za pierwszym razem (fioletowa ścieżka), przez którą przechodzimy,
~
nie można tego zrobić./
Odzwierciedla IP w północno-zachodniej przekątnej. Szara ścieżka odczytuje teraz znak i mnoży jego kod przez-1
. To zmienia EOF (-1
) w prawdziwą (dodatnią) wartość, a wszystkie prawidłowe znaki w fałszywe (nie dodatnie) wartości. W przypadku EOF adres IP przyjmuje czerwoną ścieżkę i kod kończy się. W przypadku prawidłowego znaku adres IP podąża zieloną ścieżką, gdzie~
cofa negację i;
drukuje znak. Powtarzać.Wreszcie, tutaj jest 3-bajtowa wersja, która działała w oryginalnej wersji interpretera heksagonii.
Podobnie jak odpowiedź Labiryntu, kończy się to błędem, jeśli strumień wejściowy jest skończony.
Po rozłożeniu kod odpowiada następującej siatce heksadecymalnej:
Nie
.
ma operacji. Egzekucja rozpoczyna się na fioletowej ścieżce.,
czyta bajt,;
pisze bajt. Następnie realizacja jest kontynuowana na ścieżce łososia (ish?). Musimy&
zresetować bieżącą krawędź pamięci do zera, tak aby IP wskoczył z powrotem do fioletowego rzędu po uderzeniu w róg na końcu drugiego rzędu. Raz,
trafiony EOF powróci-1
, co powoduje błąd przy;
próbie jego wydrukowania.Plik wygenerowany z Timwi „s niesamowite HexagonyColorer .
źródło
TeaScript , 0 bajtów
TeaScript to zwięzły język golfa skompilowany w JavaScript
W ostatniej aktualizacji dane wejściowe są domyślnie dodane jako pierwsza właściwość.
Wypróbuj online
Alternatywnie 1 bajt
x
zawiera dane wejściowe w TeaScript. Wynik jest niejawnyźródło
Brian & Chuck , 44 bajty
Pierwotnie stworzyłem ten język dla Utwórz język programowania, który wydaje się być bezużyteczny . Okazuje się, że jest to bardzo fajne ćwiczenie do gry w proste problemy z golfem.
Podstawy: Każdy z dwóch wierszy definiuje program podobny do Brainfuck, który działa na kodzie źródłowym drugiego programu - pierwszy program nazywa się Brian, a drugi nazywa się Chuck. Tylko Brian potrafi czytać i tylko Chuck potrafi pisać. Zamiast pętli Brainfuck masz
?
kontrolę, która przekazuje kontrolę innemu programowi (a także rolę wskaźnika instrukcji i zmiany głowy taśmy). Dodatkiem do Brainfuck jest{
i}
który skanuje taśmę w poszukiwaniu pierwszej niezerowej komórki (lub lewego końca). Ponadto_
są zastępowane bajtami zerowymi.Chociaż nie sądzę, aby było to jeszcze optymalne, jestem całkiem zadowolony z tego rozwiązania. Moja pierwsza próba miała 84 bajty, a po kilku sesjach gry w golfa ze Sp3000 (i czerpiąc inspirację z jego prób) udało mi się powoli obniżyć do 44, kilka bajtów na raz. Szczególnie genialną
+}+
sztuczką był jego pomysł (patrz poniżej).Wyjaśnienie
Dane wejściowe są odczytywane w pierwszej komórce na taśmie Chucka, a następnie starannie kopiowane na koniec taśmy Briana, gdzie są drukowane. Kopiując go do końca, możemy zaoszczędzić bajty po ustawieniu poprzedniego znaku na zero.
Jest
#
to tylko symbol zastępczy, ponieważ kontrola przełączania nie wykonuje komórki, którą włączyliśmy.{<{
zapewnia, że głowica taśmy znajduje się w pierwszej celi Chucka.,
czyta bajt ze STDIN lub-1
jeśli trafimy EOF. Zwiększamy więc to,+
aby było zerowe dla EOF i niezerowe w przeciwnym razie.Załóżmy na razie, że nie jesteśmy jeszcze w EOF. Komórka jest więc dodatnia i
?
przełączy kontrolę na Chucka.}>
przemieszcza się głowicę na taśmę (Brian) do i przekazuje sterowanie z powrotem do Brian.+
_
?
{-
teraz zmniejsza pierwszą komórkę Chucka. Jeśli nie jest jeszcze zero, ponownie przekazujemy kontrolę Chuckowi za pomocą?
. Tym razem}>
przesuwa głowicę taśmy na dwie komórki Briana po prawej stronie ostatniej niezerowej komórki. Początkowo to tutaj:Ale później będziemy już mieli tam kilka postaci. Na przykład, jeśli już czytaliśmy i drukowaliśmy
abc
, wyglądałoby to tak:Gdzie
1
s są w rzeczywistości 1-bajtowymi (zobaczymy o tym później).Ta komórka zawsze będzie wynosić zero, więc tym razem
?
nie zmieni kontroli.>
przesuwa kolejną komórkę w prawo i+
zwiększa tę komórkę. Dlatego pierwszy znak na wejściu kończy trzy komórki po prawej stronie?
(i każda kolejna trzy komórki dalej w prawo).<<<
przesuwa się z powrotem do ostatniego znaku na tej liście (lub?
jeśli jest to pierwszy znak) i{>
wraca do+
taśmy Briana, aby powtórzyć pętlę, która powoli przenosi komórkę wejściową na koniec taśmy Briana.Gdy komórka wejściowa będzie pusta,
?
po{-
nie będzie już przełączać kontroli. Następnie>}<
przesuwa głowicę taśmy na Chucku do_
i przełącza sterowanie tak, że zamiast tego wykonywana jest druga połowa Chucka.}>>
przenosi się do komórki, którą teraz napisaliśmy, poza koniec taśmy Briana, który jest bajtem, który odczytaliśmy ze STDIN, więc wypisujemy go z powrotem.
. Aby}
minąć ten nowy znak na taśmie, musimy zamknąć odstęp dwóch pustych bajtów, więc zwiększamy je za1
pomocą<+<+
(dlatego właśnie na końcowej taśmie znajdują się 1 bajty). Wreszcie{<{
wraca na początek taśmy Briana i?
zaczyna wszystko od początku.Możesz się zastanawiać, co się stanie, jeśli znak, który czytamy, będzie pusty. W takim przypadku nowo napisana komórka sama wynosiłaby zero, ale ponieważ znajduje się ona na końcu taśmy Briana i nie obchodzi nas, gdzie jest ten koniec, możemy to po prostu zignorować. Oznacza to, że jeśli dane wejściowe
ab\0de
byłyby, taśma Briana faktycznie wyglądałaby tak:Wreszcie, kiedy trafimy na EOF, pierwszy
?
na taśmie Briana nie będzie działać. W tym momencie kończymy program. Naiwny rozwiązaniem byłoby, aby przejść do końca taśmy i przełącznik sterujący Chucka, tak że termiantes programowych:>}>}<?
. W tym przypadku naprawdę sprytny pomysł Sp3000 pozwala zaoszczędzić trzy bajty:+
zamienia pierwszą komórkę Chucka1
. Oznacza to, że}
ma punkt początkowy i znajduje się_
na środku taśmy Chucka. Zamiast przejść obok niego, po prostu zamykamy lukę, zmieniając ją również w znak „1
z”+
. Zobaczmy teraz, co dzieje się z resztą kodu Briana z tym zmodyfikowanym Chuckiem ...{
wraca do pierwszej komórki Chucka jak zwykle i-
zamienia ją z powrotem w bajt zerowy. Oznacza to, że?
nie można tego zrobić. Ale teraz>}<
, który zwykle przesuwał głowicę taśmy na środek taśmy Chucka, przechodzi tuż obok niej do końca taśmy Chucka, a?
następnie przekazuje kontrolę Chuckowi, kończąc kod. Fajnie, gdy wszystko się ułoży ... :)źródło
Haskell, 16 bajtów
interact
odczytuje dane wejściowe, przekazuje je do funkcji podanej jako argument i wypisuje otrzymany wynik.id
jest funkcją tożsamości, tzn. zwraca dane wejściowe bez zmian. Dzięki lenistwu Haskellinteract
może pracować z nieskończonym wkładem.źródło
sh + binutils,
32 bajtyCóż, nie tak oczywiste. Od @ Random832
Oryginał:
Bolesnie oczywiste ...: D
źródło
dd
.cat
???Funciton , 16 bajtów
(Zakodowane jako UTF-16 z BOM)
Wyjaśnienie
Pole zwraca zawartość STDIN. Luźny koniec go wyprowadza.
źródło
Kod maszynowy Motorola MC14500B , 1,5 bajta
Napisane w systemie szesnastkowym:
Zapisane binarnie:
Wyjaśnienie
Każdy kod ma 4 bity.
źródło
Mornington Crescent , 41 bajtów
Nie mam pojęcia, czy Mornington Crescent może obsłużyć bajty zerowe, a wszystkie dane wejściowe są odczytywane przed uruchomieniem programu, ponieważ taka jest natura języka.
źródło
Brainfuck, 5 bajtów
Odpowiednik pseudokodu:
To obsługuje nieskończone strumienie, ale traktuje bajty zerowe jako EOF. To, czy BF może poprawnie obsłużyć bajty zerowe, zależy od implementacji do implementacji, ale zakłada to najbardziej powszechne podejście.
źródło
+[,.]
dobrze?Labirynt , 2 bajty
Jeśli strumień jest skończony, zakończy się to błędem, ale wszystkie dane wyjściowe wygenerowane przez błąd trafiają do STDERR, więc standardowy strumień wyjściowy jest poprawny.
Tak jak w Brainfuck
,
czyta bajt (wypychając go na główny stos Labiryntu) i.
zapisuje bajt (wyskakując z głównego stosu Labiryntu).Powodem tego jest to, że zarówno pętle
,
i.
są „ślepe uliczki” w (bardzo trywialne) reprezentowanego przez labirynt kodu źródłowego, tak że wskaźnik instrukcji po prostu odwraca się na miejscu i przenosi z powrotem do innego polecenia.Gdy trafimy, EOF
,
wypycha-1
zamiast tego i.
zgłasza błąd, ponieważ-1
nie jest prawidłowym kodem znakowym. To może się zmienić w przyszłości, ale jeszcze się na to nie zdecydowałem.Dla porównania możemy rozwiązać ten problem bez błędu w 6 bajtach w następujący sposób
Tutaj
)
zwiększa bajt, który czytamy, co daje0
w EOF i coś pozytywnego inaczej. Jeśli wartość jest0
taka, IP przechodzi od razu, uderzając w to,@
co kończy program. Jeśli wartość była dodatnia, IP skręci w prawo w kierunku,(
który zmniejsza górę stosu z powrotem do pierwotnej wartości. Adres IP znajduje się teraz w rogu i po prostu będzie wykonywać skręty w prawo, drukować.
, czytać nowy bajt.
, zanim ponownie trafi w widelec)
.źródło
C, 40 bajtów
źródło
getchar
zwraca -1 , więc kod wydrukuje nieskończony strumień 0xFF bajtów po (skończonym) wejściu.> <> , 7 bajtów
Wypróbuj tutaj . Wyjaśnienie:
Jeśli chcesz iść dalej, dopóki nie dać mu więcej wejściowe, wymienić
;
się!
.źródło
io
(2 bajty) robi to samo, ale zawiesza się i zapisujesomething smells fishy...
do STDERR na końcu wykonania, co jest dozwolone.Zespół X86, 70 bajtów
Demontaż za pomocą
objdump
:Źródło:
źródło
objdump
zdemontowałem go jako 32-bitowy kod, podczas gdy wydaje się, że skompilowałeś jako 16-bitowy. W co wierzyć? Ponieważ używaszint 0x80
, myślę, że jest przeznaczony dla Linuksa, ale po co kompilować jako 16-bitowy?Universal Lambda , 1 bajt
Program Universal Lambda to kodowanie wyrażenia lambda w systemie binarnym, posiekane na 8-bitowe fragmenty, wypełnianie niekompletnymi fragmentami dowolnymi bitami, konwertowane na strumień bajtów.
Bity są tłumaczone na termin lambda w następujący sposób:
00
wprowadza abstrakcję lambda.01
oznacza zastosowanie dwóch kolejnych terminów.111..10
, przy n powtórzeniach bitu1
, odnosi się do zmiennej n- tego lambda macierzystego; tj. jest to indeks De Bruijn w jednostce.Przez tę konwersję
0010
jest funkcją tożsamościλa.a
, co oznacza, że każdy jednobajtowy program formularza0010xxxx
jestcat
programem.źródło
!
jest0x21
, nie0x4_
?PowerShell,
884130 bajtówEDIT - zapomniałem, że mogę użyć
$input
automatycznej zmiennej do wprowadzania potoku ... EDIT2 - nie muszę testować istnienia$input
Tak, więc ... STDIN w PowerShell jest ... dziwne, powiedzmy. Zakładając, że musimy zaakceptować dane wejściowe ze wszystkich typów STDIN, jest to jedna z możliwych odpowiedzi na ten katalog i jestem pewien, że istnieją inne. 1
Jednak wprowadzanie potokowe w PowerShell nie działa tak, jak myślisz. Ponieważ potokowanie w PowerShell jest funkcją języka, a nie funkcją środowiska / powłoki (a PowerShell i tak nie jest tak naprawdę wyłącznie językiem), istnieją pewne dziwactwa w zachowaniu.
Na początek i najbardziej odpowiednie dla tego wpisu, potok nie jest oceniany natychmiastowo (przez większość czasu). Oznacza to, że jeśli mamy
command1 | command2 | command3
w naszej powłoce,command2
nie przyjmujemy danych wejściowych ani nie rozpoczynamy przetwarzania, dopóki się niecommand1
zakończy ... chyba że zapiszesz gocommand1
za pomocąForEach-Object
... innego niżForEach
. (chociażForEach
jest to aliasForEach-Object
, ale to osobny problem, ponieważ mówięForEach
jako oświadczenie, a nie alias)Oznaczałoby to, że coś takiego
yes | .\simple-cat-program.ps1
(choćyes
tak naprawdę nie istnieje, ale cokolwiek) nie zadziałałoby, ponieważyes
nigdy się nie zakończy. Gdybyśmy mogli to zrobićForEach-Object -InputObject(yes) | .\simple-cat-program.ps1
, powinniśmy (teoretycznie) działać.Poznanie ForEach i ForEach-Object na Microsoft „Hej, skrypciarze !” blog.
Wszystkie akapity wyjaśniają, dlaczego
if($input){$input}
istnieje. Bierzemy parametr wejściowy, który jest specjalnie tworzony automatycznie, jeśli dane wejściowe potoku są obecne, sprawdzamy, czy istnieją, a jeśli tak, wysyłamy je.Następnie pobieramy dane wejściowe od użytkownika
(read-host)
za pośrednictwem osobnego strumienia STDIN iwrite-host
wycofujemy je z-n
flagą (skrót od-NoNewLine
). Zauważ, że nie obsługuje to wprowadzania dowolnej długości, ponieważread-host
zostanie zakończone dopiero po wprowadzeniu kanału (technicznie, gdy użytkownik naciśnie „Enter”, ale funkcjonalnie równoważny).Uff
1 Istnieją jednak inne opcje:
Na przykład, jeśli martwimy się tylko wejściem potokowym i nie wymagamy pełnego programu, możesz zrobić coś takiego,
| $_
co po prostu wypisze wszystko, co zostanie wprowadzone. (Ogólnie rzecz biorąc, jest to nieco zbędne, ponieważ PowerShell ma domyślny wynik rzeczy „pozostawionych” po obliczeniach, ale to na bok.)Jeśli interesują nas tylko interaktywne dane wejściowe użytkownika, moglibyśmy skorzystać właśnie z tego
write-host(read-host)-n
.Dodatkowo funkcja ta madziwacznącechę polegającą na akceptowaniu danych z wiersza poleceń, na przykład.\simple-cat-program.ps1 "test"
zapełnianie (a następnie generowanie)$a
zmiennej.źródło
Cubix ,
65 bajtówTeraz obsługuje bajty zerowe!
Cubix to dwuwymiarowy esolang oparty na stosie. Cubix różni się od innych języków 2D tym, że kod źródłowy jest owinięty na zewnątrz sześcianu.
Przetestuj online! Uwaga: między iteracjami występuje opóźnienie 50 ms.
Wyjaśnienie
Pierwszą rzeczą, którą robi interpreter, jest ustalenie najmniejszej kostki, na której będzie pasował kod. W tym przypadku długość krawędzi wynosi 1. Następnie kod jest
.
uzupełniany brakiem operacji, aż wszystkie sześć stron zostanie wypełnione. Białe znaki są usuwane przed przetwarzaniem, więc ten kod jest identyczny z powyższym:Teraz kod jest uruchamiany. IP (wskaźnik instrukcji) zaczyna się na skrajnie lewej twarzy, wskazując na wschód.
Pierwszy znak, jaki napotyka IP
_
, to lustro, które odwraca IP, jeśli jest skierowane na północ lub południe; obecnie jest skierowany na wschód, więc to nic nie robi. Dalej jesti
, który wprowadza bajt ze STDIN.?
zmienia adres IP w lewo, jeśli najwyższy element jest ujemny, lub w prawo, jeśli jest dodatni. Istnieją tutaj trzy możliwe ścieżki:@
, co kończy program.o
._
. To odwraca go, wysyłając z powrotem do?
, który ponownie obraca w prawo i wyświetla bajt.Myślę, że ten program jest optymalny. Zanim Cubix mógł obsłużyć bajty zerowe (EOF wynosił 0, a nie -1), ten program działał na wszystko oprócz bajtów zerowych:
Napisałem brutalnego forcerka, aby znaleźć wszystkie 5-bajtowe programy dla kotów. Chociaż ukończenie zajmuje ~ 5 minut, najnowsza wersja znalazła 5 programów:
źródło
Vitsy, 2 bajty
z
pobiera cały stos wejściowy i przekazuje go do stosu aktywnego programu.Z
wypisuje wszystkie aktywne stosy do STDOUT.Metoda alternatywna:
źródło
MarioLANG , 11 bajtów
Nie jestem do końca pewien, czy jest to optymalne, ale jest najkrótsze, jakie znalazłem.
Obsługuje nieskończone strumienie i zakończy się z błędem po osiągnięciu EOF (przynajmniej implementacja referencyjna Ruby robi).
Jest inna wersja tego, która zmienia Mario w ninja, który potrafi podwójnie skakać:
W obu przypadkach Mario zaczyna spadać z lewej kolumny, w której
,
odczytuje bajt i.
zapisuje bajt (który generuje błąd w EOF, ponieważ,
nie zwraca poprawnego znaku).>
zapewnia, że Mario idzie w prawo (=
jest to dla niego tylko podstawa). Następnie przesuwa się w górę, albo przez podwójny skok z^
windą ("
i#
parą), albo przed<
nim, zanim każe mu wrócić do lewej kolumny.źródło
rs , 0 bajtów
Poważnie. rs po prostu wypisuje wszystko, co dostaje, jeśli dany skrypt jest całkowicie pusty.
źródło
GolfScript, 3 bajty
Pusty program przypomina standardowe wejście. Język prawdopodobnie nie obsługuje nieskończonych strumieni. Jednak dodaje nowy wiersz, jak wspomniał @Dennis. Robi to poprzez zawinięcie całego stosu w tablicę i wywołanie
puts
, które jest zdefiniowane jakoprint n print
, gdzien
jest nowa linia. Możemy jednak zmienić definicjęn
na STDIN, a następnie opróżnić stos, co właśnie:n;
robi.źródło
Pół rozbity samochód o dużym natężeniu ruchu , 9 + 3 = 12 bajtów
Half-Broken Car in Heavy Traffic (HBCHT) przyjmuje dane jako argumenty linii poleceń, więc biegnij jak
Zauważ, że +3 dotyczy
-s
flagi, która wyprowadza się jako znaki. Ponadto HBCHT nie wydaje się obsługiwać wartości NUL, ponieważ wszystkie zera są usuwane z wyniku (np.97 0 98
Jest wyprowadzany jako dwa znakiab
).Wyjaśnienie
W HBCHT samochód zaczyna się od zera,
o
a Twoim celem jest zjazd#
.^>v<
kieruj ruchem samochodu, jednocześnie modyfikując taśmę typu BF (^>v<
tłumacz na+>-<
). Jednak, jak sugeruje nazwa języka, samochód może skręcić tylko w prawo - wszelkie próby skrętu w lewo są całkowicie ignorowane (w tym ich efekty pamięci). Pamiętaj, że służy to wyłącznie do skręcania - twój samochód jest w stanie doskonale jechać do przodu / do tyłu.Innymi interesującymi częściami dotyczącymi HBCHT jest to, że początkowy kierunek samochodu jest losowy, a siatka jest toroidalna. Dlatego potrzebujemy tylko samochodu, aby dostać się do wyjścia bez modyfikowania taśmy we wszystkich czterech początkowych kierunkach:
W górę i w dół są proste, kierując się bezpośrednio do wyjścia.
Po lewej stronie zawijamy, wykonujemy
<
i zwiększamy^
. Nie możemy skręcić w lewo,<
więc zawijamy się i zmniejszamyv
, negując poprzedni przyrost. Ponieważ kierujemy się teraz w dół, możemy skręcić w prawo na<
i wyjść, po dwukrotnym przesunięciu wskaźnika i zmianie wartości komórek.Po prawej robimy to samo co w lewo, ale pomijamy pierwszą,
^
ponieważ nie możemy skręcić w lewo.Edycja : Okazuje się, że interpreter HBCHT pozwala wykonać tylko jedną ścieżkę za pomocą flagi linii poleceń, np.
Jednak flaga jest nie tylko zbyt kosztowna dla tego konkretnego pytania (przynajmniej 5 bajtów
" -d u"
), wydaje się, że wszystkie ścieżki nadal muszą być w stanie dotrzeć do wyjścia, aby wykonać kod.źródło
Minkolang , 5 bajtów
Wypróbuj tutaj.
Wyjaśnienie
o
wczytuje znak z wejścia i wypycha swój kod ASCII na stos (0
jeśli wejście jest puste).d
następnie powiela górę stosu (znak, który właśnie został wczytany).?
jest trampoliną warunkową, która przeskakuje, kolejna instrukcja z góry stosu nie jest0
. Jeśli wejście było puste,.
to nie jest ono przeskakiwane i program zatrzymuje się. W przeciwnym razieO
wyświetla górę stosu jako postać. Toroidalna natura Minkolangu oznacza, że zapętla się on do początku.źródło
INTERCALL , 133 bajty
wat
źródło
500
(nie jestem pewien), byłoby toPRINT D
prawda, prawda? (bez nagłówka)PUSH XX<newline>PRINT
lubPUSH XX AND PRINT
. No i jestem twórcą INTERCALLV , 0 bajtów
Wypróbuj online!
Idea „pamięci” V to po prostu gigantyczny zestaw znaków 2D. Przed uruchomieniem jakiegokolwiek programu wszystkie dane wejściowe są ładowane do tej tablicy (znane jako „Bufor”). Następnie na końcu dowolnego programu drukowany jest cały tekst w buforze.
Innymi słowy, pusty program to program cat.
źródło
Snowman 1.0.2 , 15 znaków
Pobrane bezpośrednio z
examples
katalogu Snowman . Czyta linię, drukuje linię, czyta linię, drukuje linię ...Zauważ, że ze względu na szczegóły implementacji, gdy STDIN jest pusty,
vg
zwróci to samo, co w przypadku pustej linii. W związku z tym po zamknięciu STDIN wielokrotnie drukuje nowe linie w nieskończonej pętli. Można to naprawić w przyszłej wersji.Objaśnienie kodu:
źródło
FireType , 7 bajtów
Wymaga pewnych zmian, które właśnie wypchnąłem . Reguły mówią:
więc jestem czysty!
źródło
Rozszczepienie , 4 bajty
Czy nie jest miło, gdy pokonujesz przykładowe programy we własnym repozytorium języka? :) Dla porównania, ma 7-bajtowe rozwiązanie
Wyjaśnienie
Więc
R
zaczyna Sterowanie przepływem z prawej toku atomu.?
wczytuje postać ze STDIN do masy atomu. Tak długo, jak czytamy postacie, energia pozostaje zerowa, więcJ
ump nie ma możliwości op i!
drukuje postać. Atom zapętla się z powrotem do początku (R
jest teraz brakiem operacji) i powtarza cały proces.Kiedy uderzymy w EOF,
?
ustawimy energię atomu na1
, więcJ
ump pominie teraz polecenie drukowania. Ale kiedy atom uderzy?
po tym, jak EOF został już zwrócony, zamiast tego zniszczy atom, co zakończy program.(Rozwiązanie autora języka używa jawnego polecenia
;
do zakończenia programu, który w0
innym przypadku jest pomijany z dwoma portami).źródło
Shtriped , 20 bajtów
To bezczelnie pokazuje, że prawie każdy drukowany ciąg ASCII jest prawidłowym identyfikatorem w Shtriped.
Jak to działa:
Nie ma prawdziwego sposobu na wykrycie EOF, więc pętle te są zawsze podobne do odpowiedzi w Pythonie .
Możesz go jednak łatwo zatrzymać, gdy podany zostanie pusty wiersz (30 bajtów):
Należy pamiętać, że Shtriped I / O obsługuje tylko drukowalne ASCII , tabulatory, przesunięcia linii, znaki powrotu karetki, tabulatory pionowe i przesunięcia formularzy (łącznie 100 znaków). Wynika to z tego, że wewnętrznie łańcuchy są reprezentowane jako nieujemne liczby całkowite o dowolnej dokładności i musi istnieć skończony alfabet znaków, aby móc zakodować wszystkie łańcuchy.
źródło