Hello World odporny na awarie (znany również jako wywiad)

66

Pod koniec twojego wywiadu Evil Interviewer mówi: „Sprawiamy, że wszyscy nasi kandydaci biorą krótki test kodowania, aby sprawdzić, czy naprawdę wiedzą, o czym mówią. Nie martw się; to łatwe. A jeśli stworzysz działający program, natychmiast zaoferuję ci pracę ”. Gestem nakazuje ci usiąść przy pobliskim komputerze. „Wszystko, co musisz zrobić, to stworzyć działający program Hello World. Ale” - i uśmiecha się szeroko - „jest pewien haczyk. Niestety jedyny kompilator, który mamy na tym komputerze, ma mały błąd. Losowo usuwa jedną postać z plik kodu źródłowego przed kompilacją. Ok, do zobaczenia za pięć minut! ” I wychodzi z pokoju, gwiżdżąc radośnie.

Czy możesz zagwarantować, że dostaniesz pracę?

Zadanie

Napisz program, który wydrukuje Hello, world!na standardowe wyjście nawet po usunięciu jednego znaku z dowolnej pozycji w pliku. Lub zbliżyć się do tego tak blisko, jak to możliwe.

Zasady

Brak zewnętrznych wyników - Hello, world!musi być jedyną istotną rzeczą wydrukowaną na standardowe wyjście. Można dodawać inne znaki, jeśli są one naturalnie tworzone przez wybrany język - na przykład końcowy znak nowej linii lub nawet coś podobnego [1] "Hello, world!"(na przykład, jeśli używasz R), ale musi drukować dokładnie to samo za każdym razem. Na przykład nie można drukować Hello, world!Hello, world!ani przez Hello world!" && x==1pewien czas. Ostrzeżenia są jednak dozwolone.

Testowanie Aby przetestować swój wynik, musisz przetestować każdą możliwą permutację programu: przetestuj go przy każdym usuniętym znaku i sprawdź, czy daje on poprawny wynik. Poniżej zamieściłem prosty program Perla do tego celu, który powinien działać w wielu językach. Jeśli to nie działa, utwórz program testowy i dołącz go do swojej odpowiedzi.

Punktacja Twój wynik to liczba niepowodzeń programu . Innymi słowy, liczba pojedynczych pozycji w pliku, w których usunięcie znaku uniemożliwia działanie programu. Najniższy wynik wygrywa. W przypadku remisu wygrywa najkrótszy kod.

Trywialne rozwiązania, takie jak "Hello, world!"w kilku językach (15 punktów) są dopuszczalne, ale nie wygrywają. Znalazłem przynajmniej rozwiązanie Perla z wynikiem 4, które ostatecznie opublikuję.

Aktualizacja: Oficjalny zwycięzca użyje języka programowania Turing-complete i nie użyje żadnego predefiniowanego mechanizmu drukowania Hello, world!. Wszelkie używane zasoby zewnętrzne (inne niż standardowe biblioteki dla twojego języka) są uważane za część programu i podlegają temu samemu jednoznakowemu usunięciu. Wymagania te zostały przyklejone do biurka na karteczce samoprzylepnej. Przepraszam, jeśli na początku ich nie widziałeś.

Aktualizacja 2: Tak, twój program musi faktycznie wykonać zadanie opisane powyżej, aby otrzymać wynik! Oznacza to, że powinien pomyślnie wydrukować Hello, world!co najmniej raz. To powinno być oczywiste. Przełączniki wiersza polecenia i inne ustawienia, które zwiększają funkcjonalność, również liczą się jako część programu i podlegają usunięciu pojedynczego znaku. Program musi wykonać swoje zadanie bez udziału użytkownika. Niepowodzenie kompilacji liczy się w liczbie niepowodzeń.

Miłego programowania i obyś dostał pracę. Ale jeśli ci się nie uda, prawdopodobnie i tak nie chciałeś pracować dla tego złego szefa.

Skrypt testowy Perla:

use warnings;
use strict;

my $program   = 'test.pl';
my $temp_file = 'corrupt.pl';
my $command = "perl -X $temp_file"; #Disabled warnings for cleaner output.
my $expected_result = "Hello, world!";

open my $in,'<',$program or die $!;
local $/;           #Undef the line separator   
my $code = <$in>;   #Read the entire file in.

my $fails = 0;
for my $omit_pos (0..length($code)-1)
{
    my $corrupt = $code;
    $corrupt =~ s/^.{$omit_pos}\K.//s;  #Delete a single character

    open my $out,'>',$temp_file or die $!;
    print {$out} $corrupt;  #Write the corrupt program to a file
    close $out;

    my $result = `$command`;    #Execute system command.
    if ($result ne $expected_result)
    { 
        $fails++;
        print "Failure $fails:\nResult: ($result)\n$corrupt";
    }
}

print "\n$fails failed out of " . length $code;
dkudriavtsev
źródło
1
Czy usunięty znak może spowodować, że program się nie skompiluje? Czy nadal jest to liczone jako niedziałające?
lochok
@lochok, tak, to by się liczyło jako niepowodzenie. Każdy usunięty znak, który prowadzi do Hello, World!braku wydruku, jest błędem.
2
Podobne pytanie: codegolf.stackexchange.com/questions/4486/…
mowwwalker 18.04.13
@Walkerneo, dzięki! Szukałem podobnych pytań i nie znalazłem tego. Myślę jednak, że jest to zupełnie inne. W szczególności to pytanie gwarantuje, że muszą być obsługiwane tylko modyfikacje prowadzące do poprawnego składniowo kodu.
Czy możesz podać przykład „przełączników wiersza polecenia i innych ustawień zwiększających funkcjonalność”? Czy masz na myśli przełączniki i ustawienia podane dla samego programu, czy używasz przełączników i ustawień w środowisku kompilacji?
CasaDeRobison

Odpowiedzi:

129

Befunge, wynik 0

Myślę, że go złamałem - żadne usunięcie pojedynczego znaku nie zmieni wyniku.
Usunięcie dowolnego znaku z wiersza 1 nic nie zmienia - nadal spada w tym samym miejscu.
Linie 2 i 3 są zbędne. Zazwyczaj linia 2 jest wykonywana, ale jeśli usuniesz z niej znak, <zostanie pominięty, a linia 3 przejmie kontrolę.
Usunięcie nowego wiersza też go nie zepsuło (zepsuło moją poprzednią wersję).
Niestety, nie ma programu testowego.

EDYCJA : bardzo uproszczone.

                              vv
@,,,,,,,,,,,,,"Hello, world!"<<
@,,,,,,,,,,,,,"Hello, world!"<<

Krótkie wyjaśnienie przepływu:

  1. Befunge zaczyna wykonywać od lewego górnego rogu, przesuwając w prawo. Przestrzenie nic nie robią.
  2. v obraca przepływ wykonania w dół, więc idzie w dół o jedną linię.
  3. < obraca przepływ wykonania w lewo, więc odczytuje wiersz 2 w odwrotnej kolejności.
  4. "Hello, world!"wypycha ciąg do stosu. Przesunięty jest w odwrotnej kolejności, ponieważ wykonujemy od prawej do lewej.
  5. ,wyskakuje postać i drukuje ją. Ostatni wypychany znak jest drukowany jako pierwszy, co ponownie odwraca ciąg.
  6. @ kończy program.
ugoren
źródło
2
+1, świetne rozwiązanie. Nie sądzę, aby program testowy był potrzebny, ponieważ jest oczywiste, że istnieje tylko niewielka liczba potencjalnie znaczących usunięć.
4
Łatwo to zweryfikować i nie wymaga dyskusji. Geniusz!
Karma Fusebox
Gratulujemy doskonałego rozwiązania.
2
Wiem, że to nie jest golf golfowy , ale oto wersja w 66 bajtach .
MD XF
42

Perl, wynik 0

(147 znaków)

Oto moje rozwiązanie, które udało mi się uzyskać z 4 do 0:

eval +qq(;\$_="Hello, world!";;*a=print()if length==13or!m/./#)||
+eval +qq(;\$_="Hello, world!";;print()if*a!~/1/||!m/./#)##)||
print"Hello, world!"

Musi się pojawić wszystko w jednej linii, aby działać; podziały wierszy służą wyłącznie do „czytelności”.

Korzysta z patologicznie dopuszczalnej składni Perla. Niektóre najważniejsze:

  • Barewords, które nie są rozpoznawane, są traktowane jako ciągi znaków. Kiedy evalstaje się evl, nie jest to błędem, jeśli w tym momencie dopuszczalny jest łańcuch.
  • Jednoargumentowy +operator, który w pewnych sytuacjach nie robi nic poza jednoznaczną składnią. Jest to przydatne w powyższym przypadku, ponieważ function +argument(gdzie + jest jednoargumentowy) staje się string + argument(dodawanie), gdy nazwa funkcji jest zniekształcona i staje się łańcuchem.
  • Wiele sposobów deklarowania łańcuchów: łańcuch podwójnie cytowany qq( )może stać się łańcuchem pojedynczym q(); ciąg rozdzielony nawiasami qq(; ... )może stać się ciągiem oddzielonym średnikiem qq; ... ;. #wewnątrz ciągów można wyeliminować problemy z równoważeniem, przekształcając rzeczy w komentarze.

Długość tego można prawdopodobnie nieco zmniejszyć, choć wątpię, czy uda się pokonać rozwiązanie ugorena.


źródło
13
+1 za
podział wiersza służy
40

HQ9 +

To nigdy nie zakończy się uzyskaniem zamierzonego wyniku, gdy postać zostanie usunięta, więc otrzyma wynik zero.

HH

Kiedy zaczynam?

skeevey
źródło
1
Tworzy jednak „cześć, świecie”, a nie „Cześć, świecie!” jak określono.
Paul R
16
Bzdury, język został po prostu niepoprawnie określony na wiki esolang;)
skeevey 17.04.2013
11
Dobre dla ciebie, jeśli mają kompilator HQ9 + na komputerze wywiadu ... :)
Możesz napisać własny kompilator błędów.
PyRulez
2
@ mbomb007 Ten interpreter drukuje Hello, world!dla Hpolecenia.
Dennis
12

Befunge-98 , wynik 0, 45 bajtów

20020xx""!!ddllrrooww  ,,oolllleeHH""cckk,,@@

Wypróbuj online!

Chociaż już znaleziono optymalne rozwiązanie (i nie ma rozstrzygającego remisu), pomyślałem, że pokażę, że można to znacznie uprościć w Befunge 98.

Wyjaśnienie

20020xxNiezawodnie ustawia Delta (etapy wskaźnik instrukcji między kleszcze), aby (2,0)tak, że począwszy od pierwszego x, tylko co drugi komenda jest wykonywana. Zobacz tę odpowiedź, aby uzyskać szczegółowe wyjaśnienie, dlaczego to działa. Następnie kod jest po prostu:

"!dlrow ,olleH"ck,@

Najpierw umieszczamy wszystkie odpowiednie kody znaków na stosie za pomocą "!dlrow ,olleH". Następnie ck,oznacza drukowanie górnej części stosu ( ,), 13 ( cplus 1) czas ( k). @kończy program.

Martin Ender
źródło
11

J, 7 punktów

Wybieranie każdej litery o nieparzystej pozycji:

   _2{.\'HHeellllo,,  wwoorrlldd!!'
Hello, world!
randomra
źródło
5
To samo w golfscript byłoby 4 punkty:'HHeelllloo,, wwoorrlldd!!'2%
cardboard_box
@cardboard_box Możesz go przesłać. :)
randomra 18.04.13
Usprawiedliwienie, ponieważ to rozumiem i nie ma ochoty oszukiwać.
Michael Stern
3

Befunge-93, wynik 0 (63 bajtów)

Wiem, że to nie jest wyzwanie do gry w golfa, ale pomyślałem, że byłoby interesujące sprawdzić, czy istniejące rozwiązanie Befunge-93 można ulepszyć pod względem wielkości. Pierwotnie opracowałem tę technikę do zastosowania w podobnym wyzwaniu Error 404 , ale potrzeba owijania ładunku w tym przypadku sprawiła, że ​​rozwiązanie 3-liniowe było bardziej optymalne.

To nie jest tak dobre, jak odpowiedź Martina Befunge-98, ale nadal jest dość znaczącą redukcją zwycięskiego rozwiązania Befunge-93.

<>>  "!dlrow ,olleH">:#,_@  vv
  ^^@_,#!>#:<"Hello, world!"<<>#

Wypróbuj online!

Wyjaśnienie

Istnieją dwie wersje ładunku. W przypadku niezmienionego programu, pierwszy <powoduje, że program wykonuje się od prawej do lewej, owijając się do końca linii, dopóki nie dojdzie do vprzekierowania go do drugiej linii i <kierując go od lewej do prawej wersji ładunku.

Błąd w drugim wierszu powoduje <przesunięcie finału w lewo i zastąpienie go >kierunkiem przepływu w prawo. Polecenie #(most) nie ma nic do przeskoczenia, więc kod jest kontynuowany, dopóki nie zostanie zawinięty i nie osiągnie ^początku linii, kierując go do pierwszej linii, a następnie >kierując go w prawo do pozostawiono ładunek.

Większość błędów w pierwszym wierszu powoduje po prostu vprzesunięcie ostatnich poleceń o jeden, ale nie zmienia to głównego przepływu kodu. <Jednak usunięcie pierwszego jest nieco inne - w takim przypadku ścieżka wykonania przepływa bezpośrednio do ładunku od lewej do prawej w pierwszym wierszu.

Innym szczególnym przypadkiem jest usunięcie przerwy w linii. Kiedy kod zawija się do końca linii, w tym przypadku jest to koniec czegoś, co kiedyś było drugą linią. Gdy napotka #polecenie z prawej strony, przeskakuje on >i tym samym przechodzi bezpośrednio do ładunku od prawej do lewej.

W razie jakichkolwiek wątpliwości przetestowałem również skrypt Perla i potwierdziło, że „0 z 63 nie powiodło się”.

James Holderness
źródło
0

Gol> <> , zdobądź 0, 38 bajtów

<<H"Hello, world!"/
H"Hello, world!" <

Język jest uwalniany po wyzwaniu.

jimmy23013
źródło