Programowanie nieskazitelnego świata

87

Zdefiniujmy nieskazitelny program jako program, który sam nie ma żadnych błędów, ale spowoduje błąd, jeśli zmodyfikujesz go, usuwając ciągłe podciągi N znaków, gdzie 1 <= N < program length.

Na przykład trzyznakowy program w języku Python 2

`8`

jest nieskazitelnym programem ( dzięki, Sp ), ponieważ wszystkie programy wynikające z usunięcia podciągów o długości 1 powodują błędy (w rzeczywistości błędy składniowe, ale zrobi to każdy rodzaj błędu):

8`
``
`8

a także wszystkie programy wynikające z usunięcia podciągów o długości 2 powodują błędy:

`
`

Gdyby na przykład `8program nie zawierał błędów `8`, nie byłby nieskazitelny, ponieważ wszystkie wyniki usuwania podciągów muszą zawierać błędy.

Twoim zadaniem w tym wyzwaniu jest napisanie możliwie najkrótszego nieskazitelnego programu, który nie pobiera danych wejściowych, ale wypisuje jedno z następujących pięciu słów:

world
earth
globe
planet
sphere

To, które słowo wybierzesz, zależy wyłącznie od Ciebie. Jedyne słowo plus opcjonalny znak nowej linii powinny być wydrukowane na stdout (lub najbliższą alternatywę dla twojego języka). Najkrótszy program w bajtach wygrywa.

Uwagi:

  • Wymagany jest samodzielny program, a nie funkcja.
  • W słowach rozróżniana jest wielkość liter; wyjście Worldlub EARTHjest niedozwolone.
  • Ostrzeżenia kompilatora nie są liczone jako błędy.
  • Błędne podprogramy mogą pobierać dane wejściowe lub dane wyjściowe lub robić cokolwiek innego, o ile zawsze ostatecznie powodują błąd.

Oto fragment kodu stosu, który będzie zawierał listę programów, które należy popsuć, biorąc pod uwagę potencjalnie nieskazitelny program:

<script src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'></script><script>function go() { var s = $('#i').val(), e = []; for (var i = 1; i < s.length; i++) { for (var j = 0; j <= s.length - i; j++) { e.push(s.substring(0, j) + s.substring(j + i)); } } $('#o').val(e.join('\n---\n')); }</script>Program:<br><textarea id='i' rows='16' cols='80'>`8`</textarea><br><button onclick='go()' type='button'>Go</button><br><br>Programs that should error: (--- separated)<br><textarea id='o' rows='16' cols='80'></textarea><br>

Hobby Calvina
źródło
1
@geokavel Tak. Złapanie wyjątku oznacza, że ​​nie jest to już błąd.
Calvin's Hobbies
33
Dwa razy więcej usuniętych odpowiedzi niż nieusuniętych. To osiągnięcie!
DLosc
1
Czy program może odczytać własny kod źródłowy?
Shelvacu,
2
Gdzie zobaczyć gravegard odpowiedzi „blisko, ale nie cygara” i ich komentarzy?
Vi.
1
@Vi. Uzyskaj 2000 powtórzeń, aby móc wyświetlać usunięte posty .
ThisSuitIsBlackNot

Odpowiedzi:

46

Szyna , 24 bajty

$'main'    #
 -[world]o/

Myślę, że to działa. I jest zarówno krótki, jak i czytelny (jeśli chodzi o Rail).

  • Jeśli usunięty podciąg obejmuje jakąkolwiek część $'main', otrzymujemy Internal Error: Crash: No 'main' function found.
  • Jeśli usunięty podłańcuch zawiera opcję #, nie ma możliwości, aby program zakończył się czysto, więc zawsze będzie się kończył Crash: No valid move. Uważam, że nie jest możliwe usunięcie podciągu, tak aby ścieżka tworzyła prawidłową (nieskończoną) pętlę.
  • Jeśli usunięty substring znajduje się przed nim #, zostanie odłączony od końca toru, więc pociąg się zawiesi (z tym samym błędem jak powyżej).
  • Jeśli usunięty podciąg znajduje się za #, odłączy również #koniec ścieżki (a potencjalnie nawet początek ścieżki od punktu wejścia $). Więc znowu ten sam błąd.

Co do rzeczywistego programu: każdy program kolejowy musi mieć $'main'(lub dłuższy wariant, ale tutaj gramy w golfa) jako punkt wejścia do funkcji, a pociąg rozpoczyna się w $kierunku południowo-wschodnim. Wszystko w pierwszym wierszu może być jednak częścią ścieżki, więc usunięcie 'main'ścieżki jest następujące:

$          #
 -[world]o/

-I /są po prostu kawałki szyny której musimy pozwolić pociąg wziąć te 45 ° zakręty.

[world]popycha ciąg worldi odrukuje go. #oznacza koniec toru - jedyny sposób na bezpieczne zakończenie programu kolejowego.

Co ciekawe, to rozwiązanie jest możliwe tylko dlatego, że Rail pozwala torom przejść przez mainlinię - jeśli nie #byłoby to możliwe, byłoby to po pierwszej nowej linii, a kod można zawsze skrócić do

$'main'
 #

który jest poprawnym programem, który nic nie robi. (Znaki spacji pomiędzy 'i #nie miałyby na to wpływu.)

Również dość interesujące: gdybym właśnie grał w golfa w zadaniu drukowania, worldnie byłoby to znacznie krótsze ani prostsze:

$'main'
 -[world]o#
Martin Ender
źródło
4
Co się stanie, jeśli usunę jakiś znak między [a]?
Martin Lütke,
@ MartinLütke odłączy się /od #.
Martin Ender,
2
@ MartinLütke Nie tylko można usunąć nawiasy, ponieważ nie są one ciągłe.
Calvin's Hobbies
Co jeśli usuniesz znak nowej linii między dwiema liniami?
Vi.
1
@Vi. To odłącza $od początku toru, więc pociąg natychmiast się zawiesza (Rail oczekuje, że tor będzie kontynuował południowy wschód od $).
Martin Ender
43

Funciton ( 186 136 bajtów w UTF-16)

╔══════════════╗
║19342823075080╟
║88037380718711║
╚══════════════╝

Ten program wypisuje „świat”.

Większość podciągów usuniętych z tego spowoduje, że nie będzie to kompletne pudełko, na które parser będzie narzekał. Jedyne możliwe usunięcia, które pozostawiają pełne pole, to:

 ╔══════════════╗
|║19342823075080╟  (remove this whole line)
|║88037380718711║
 ╚══════════════╝
 ╔══════════════╗
 ║|19342823075080╟   ← substring starts at | here
 ║|88037380718711║   ← substring ends at | here
 ╚══════════════╝
... ↕ or anything in between these that removes a whole line’s worth ↕ ...
 ╔══════════════╗
 ║19342823075080|╟   ← substring starts at | here
 ║88037380718711|║   ← substring ends at | here
 ╚══════════════╝
 ╔══════════════╗
|║19342823075080╟
 ║88037380718711║  (both lines entirely)
|╚══════════════╝
 ╔══════════════╗
 ║19342823075080╟
|║88037380718711║  (remove this whole line)
|╚══════════════╝

Większość z nich usuwa zwisający koniec w prawym górnym rogu skrzynki, która jest złączem wyjściowym. Bez tego luźnego końca pudełko jest tylko komentarzem:

╔══════════════╗
║88037380718711║
╚══════════════╝

To już nie jest poprawny program, ponieważ analizator oczekuje programu z dokładnie jednym wyjściem:

Błąd: pliki źródłowe nie zawierają programu (program musi mieć dane wyjściowe).

Jedyną możliwością, która pozostawia złącze wyjściowe, jest ostatnia z powyższych, która pozostawia to:

╔══════════════╗
║19342823075080╟
╚══════════════╝

Jednak liczba ta nie koduje prawidłowego ciągu Unicode w ezoterycznym UTF-21 Funcitona. Spróbuj uruchomić to, otrzymasz:

Nieobsługiwany wyjątek: System.ArgumentOutOfRangeException: Prawidłowa wartość UTF32 zawiera się między 0x000000 a 0x10ffff włącznie i nie powinna zawierać zastępczych wartości punktów kodowych (0x00d800 ~ 0x00dfff).

Dlatego ten program jest nieskazitelny.

Timwi
źródło
3
Wydaje mi się, że masz szczęście w ostatniej sprawie (nie dlatego, że łatwo jest przypadkowo uzyskać prawidłową sekwencję Unicode, ale nadal ...)
Esolanging Fruit
34

Visual C ++ - 96 95 bajtów

#include<iostream>
#define I(a,b)a<<b
int main()I({std::cout,I('w',I('o',I('r',I('l','d';)))))}

Nieruchomości:

  1. Nie można usunąć żadnej części int main()bez błędu kompilacji.
  2. Nie można usunąć modyfikowania makr ekspansję na wszystkich, usuwając ana wszelkie sposoby main()nigdy nie pobiera {, usuwając bw ogóle znaczy nasza linia nie kończy się w sposób ;, usuwając <środki std::cout<'w'powoduje błąd i usunięcie <<przyczyny std::cout'w', 'w''o'itp
  3. Nie można usunąć parametrów z definicji lub wywołania makra, jedynymi prawidłowymi nazwami dla definicji byłyby I(a), I(b)które nigdy nie pasują i Iktóre rozwijają się przedtem (; z drugiej strony używanie I(,przyczyn <<<<i ,)upuszcza średnik (z wyjątkiem wszelkich innych błędów).
  4. Nie można usunąć części wszystkiego std::coutbez natrafienia na wiodące <<, a zatem nie można usunąć żadnego z #include<iostream>początku bez błędu kompilacji.
  5. Nie można usunąć żadnej części pojedynczego znaku, ''występuje błąd pustego znaku i 'w,itd. ... spróbuj przekształcić wszystko w jedną postać.
  6. Nie można usunąć lewej / prawej strony makra bez pozostawiania zbyt wielu )lub (po drugiej stronie, np. Nie można robić takich rzeczy I('w',I('r'.

Kompiluje online za pomocą Visual C ++ .

Po raz kolejny nie jest to wyczerpujący dowód. Jeśli uważasz, że możesz to zrobić bez pracy, daj mi znać.

Poprzednie wersje stosowały zupełnie inne podejście i okazało się, że nie są nieskazitelne, więc usunąłem te wyniki.


Weryfikacja:

Poniższy program potwierdził, że ta wersja jest nieskazitelna przy użyciu clkompilatora Visual C ++ 2010. Szkoda, że ​​nie zadałam sobie trudu napisania tego wcześniej:

#include <fstream>
#include <iostream>
char *S = "#include<iostream>\n#define I(a,b)a<<b\nint main()I({std::cout,I('w',I('o',I('r',I('l','d';)))))}";
//uncomment to print source code before compile
// #define prints
int main(){
   for(int i=0; i<95; i++)
      for(int j=i; j<95; j++){
         std::fstream fs;
         fs.open ("tmptst.cpp",std::fstream::out);
         for(int k=0; k<95; k++)
         if(k<i || k>j){
            fs << S[k];
            #ifdef prints
               std::cout<<S[k];
            #endif
         }
         fs.close();
         #ifdef prints
            std::cout<<'\n';
         #endif
         //Compile and surpress/pipe all output
         //if it doesn't compile we get a nonzero errorlevel (i.e.true) from system.
         if(!system("cl -nologo tmptst.cpp >x"))
            return 0;
      }
      std::cout<<"PRISTINE!";
}
Linus
źródło
1
Zauważamy, że chociaż jest to nieskazitelne w tym kompilatorze, nie we wszystkich kompilatorach.
Jozuego
1
Podaj przykład ....
Linus
3
W niektórych kompilatorach pusty program C ++ daje program, który nic nie robi. W zależności od implementacji iostream, #include <iostream> może również się skompilować.
Jozuego
5
@Joshua Tylko podprogramy o długości 1 lub większej mają znaczenie, więc nie ma znaczenia, co robi pusty program.
ThisSuitIsBlackNot
2
@Comintern, niezupełnie. Jeśli nie zaznaczysz pola wyboru, aby uruchomić plik wykonywalny, /copcja jest automatycznie dołączana i kompiluje się (jak w przypadku tworzenia biblioteki, a nie programu). Jeśli /czaznaczysz pole uruchamiania, którego witryna nie zawiera , nie otrzymasz komunikatu o powodzeniu, a zamiast tego znajdziesz naturalny „LINK: błąd krytyczny LNK1561: należy zdefiniować punkt wejścia”.
Linus
32

Python 3, 79 33

if 5-open(1,'w').write('world'):a

open(1,'w')otwiera standardowe wyjście, a następnie drukujemy ciąg. writezwraca liczbę zapisanych znaków. Służy to do utwardzenia przed usunięciem podciągów: Usunięcie części ciągu powoduje zwrócenie czegoś innego niż 5, a 5 minus ta wartość następnie przyjmuje wartość true. Ale to powoduje, że ifosoba zostaje stracona i ajest niezdefiniowana.

Jest to oparte na sprytnym dziewiczym stylu Andersa Kaseorga tutaj .

Ponieważ tylko jedno stwierdzenie wymaga weryfikacji, jest to znacznie krótsze niż stare rozwiązanie, ale także mniej ogólne.

Stare rozwiązanie:

try:
 q="print('world');r=None"
 if exec('e=q')==eval(q[17:]):exec(e)
finally:r

Aby sprawdzić, czy to naprawdę nieskazitelny program:

w=r'''try:
 q="print('world');r=None"
 if exec('e=q')==eval(q[17:]):exec(e)
finally:r'''
exec(w)
for j in range(1,len(w)):
 for i in range(len(w)+1-j):
  e=w[:i]+w[i+j:]
  try:exec(e,{});print('WORKED',e)
  except:pass

Niektóre kluczowe punkty:

  • Każde wykonane polecenie może zostać usunięte. Sprawdzenie, czy qzostało wykonane, wymaga instrukcji poza q. To trydobrze rozwiązuje, wymagając co najmniej dwóch instrukcji, z których żadnej nie można całkowicie usunąć.
  • Weryfikacja qwykonania została dokonana poprzez ocenę rna końcu.
  • Sprawdzeniu, że qnie został zmodyfikowany został osiągnięty przez eval(q[17:]), który musi ocenić na Nonena qbyć wykonana.
  • ifWarunek jest nieco skomplikowany, aby dostać prawo. Aby upewnić się, że został oceniony, ma fajny efekt uboczny ustawienia e, który należy ustawić r. (To jest powód, dla którego użyłem Pythona 3, exprponieważ funkcja robi cuda dla efektów ubocznych na poziomie wyrażenia.)
Philipp
źródło
Czy nie jest wyzwanie, że żadne usunięcie nie spowoduje błędu składniowego? Wygląda na to, że wywołujesz błędy w czasie wykonywania.
Martin Lütke,
5
@ MartinLütke Wszelkie błędy są w porządku.
Calvin's Hobbies
1
Czy to nie 79 bajtów?
The Matt
@TheMatt Tak? Właśnie je policzyłem i wydaje się, że masz rację. Może dawno mnie liczyło nowe wiersze CRLF ... Jak zawstydzające. Dzięki!
Philipp
25

Haskell, 61

x=uncurry(:)
main=putStr$x('w',x('o',x('r',x('l',x('d',[])))))

Jakikolwiek błąd jest OK? W tym wypadku:

Haskell, 39

main=putStr$take 5$(++)"world"undefined
Martin Lütke
źródło
Czy to działa, jeśli usuniesz jedną z liter?
lirtosiast
Awaria podczas wykonywania. Ponieważ będzie próbował ocenić niezdefiniowany.
Martin Lütke,
To jest wspaniałe. Leniwa ocena FTW, wydaje się!
DLosc
1
Chciałbym, żeby „inits” było w preludium :(. Wtedy: main = putStr $ inits „world” !! 5 (27 bajtów)
Martin Lütke
16

JavaScript, 74 73 35 bajtów

if((alert(a="world")?x:a)[4]!="d")x

Okazuje się, że odpowiedź była znacznie prostsza niż myślałem ...

Wyjaśnienie

if(
  (
    alert(a="world") // throws a is not defined if '="world"' is removed
        ?x           // throws x is not defined if 'alert' or '(a="world")' is removed
        :a           // throws a is not defined if 'a="world"' or 'a=' is removed
  )
  [4]!="d"           // if "world" is altered fifth character will not be "d"
                     // if 'd' is removed it will compare "world"[4] ("d") with ""
                     // if '[4]' is removed it will compare "world" with "d"
                     // if '(alert(a="world")?x:a)' is removed it will compare [4] with "d"
                     // if '?x:a' is removed [4] on alert result (undefined[4]) will error
                     // if '[4]!="d"' is removed the if will evaluate "world" (true)
                     // if '!', '!="d"' or '(alert...[4]!=' is removed the if will
                     //     evaluate "d" (true)
)x                   // throws x is not defined if reached

// any other combination of removing substrings results in a syntax error
użytkownik 81655
źródło
usuń wszystko oprócz a="world", nie powoduje błędu
anOKsquirrel
3
@anOKsquirrel Tylko jeden podciąg można usunąć.
Dennis
4
Przeszedłem przez to tak: „Czy mogę to usunąć? Nie, ten błąd wystąpiłby. Czy można to usunąć? Cóż, myślę, że spowodowałoby to inny błąd. Aha! Te znaki można usunąć! Och, poczekaj ...” +1
ETHprodukcje
if(a="world")["bol"+a[4]]nie popełnia błędu.
anOKsquirrel
4
Święta krowa, teraz jest dwa razy imponująca! Chciałbym móc dać +1 jeszcze raz ...
ETHproductions
15

Java 8, 301 bajtów

Ponieważ każde pytanie wymaga odpowiedzi w języku Java.

class C{static{System.out.print(((((w='w')))));System.out.print((((o='o'))));System.out.print(((r='r')));System.out.print((l='l'));System.out.print(d='d');e=(char)((f=1)/((g=8)-C.class.getDeclaredFields()[h=0].getModifiers()));}public static void main(String[]a){}static final char w,o,r,l,d,e,f,g,h;}

Rozszerzony

class C {
    static {
        System.out.print(((((w = 'w')))));
        System.out.print((((o = 'o'))));
        System.out.print(((r = 'r')));
        System.out.print((l = 'l'));
        System.out.print(d = 'd');
        e = (char) ((f = 1) / ((g = 8) - C.class.getDeclaredFields()[h = 0].getModifiers()));
    }

    public static void main(String[] a) { }

    static final char w, o, r, l, d, e, f, g, h;
}

Wyjaśnienie

  • public static main(String[]a){} jest wymagane.
  • Jeśli deklaracje pól zostaną usunięte (lub uczynione niestatycznymi), pierwszy blok statyczny nie będzie mógł ich znaleźć.
  • Jeśli blok statyczny zostanie usunięty (lub uczyniony niestatycznym), pola nie zostaną zainicjowane.

Najtrudniejsza część:

  • Jeśli finalsłowo kluczowe zostanie usunięte, druga linia ocenia 1/(8-8), powodując / by zerowyjątek.
Ypnypn
źródło
Dlaczego nie możesz usunąć wnętrza żadnej z instrukcji drukowania?
Nic Hartley,
2
@QPaysTaxes Nie ma pustej System.out.print()metody. Jest za println(), ale nie za print(). Więc jeśli d='d'go usuniesz, to da The method print(boolean) in the type PrintStream is not applicable for the arguments ()jako błąd (a jeśli d=go usuniesz , da to The blank final field d may not have been initializedjako błąd).
Kevin Cruijssen
15

Funciton , 143 142 136 bajtów

Wynik jest jak zwykle w UTF-8, ponieważ UTF-16 byłby o dwa bajty większy (z powodu BOM).

╔══════════╗
║1934282307║╔╗
║5080880373╟╚╝
║80718711  ║
╚══════════╝

Tak więc zastanawiałem się nad odpowiedzią Funcitona przez pewien czas i pomyślałem, że byłoby to niemożliwe, ponieważ zawsze można usunąć pełną linię, a kod nadal tworzy prawidłowy blok. Potem rozmawiałem o tym z Timwi, a on doszedł do wniosku, że możesz po prostu umieścić cały numer w jednym wierszu, tak że usunięcie go zepsułoby program z powodu braku złącza wyjściowego.

Ale literały w jednym wierszu są notorycznie drogie, zarówno ze względu na większą liczbę znaków, jak i większą liczbę znaków spoza ASCII. A jego wzmianka o bloku „pusty komentarz” skłoniła mnie do myślenia…

Więc wymyśliłem to bardziej wydajne rozwiązanie, które wykorzystuje dodatkowy pusty blok komentarza, który pęka, gdy próbujesz usunąć wszystko, co pozostawiłoby dosłowny blok w takcie:

  • Nie możemy ewentualnie usunąć trzeciej linii, ponieważ wtedy usuwamy złącze wyjściowe.
  • Jeśli usuniemy drugą linię, blok komentarza traci górną krawędź i łamie się.

Pozostawia to dwie opcje (podziękowania dla Steve'a za wskazanie tego):

  • Usuń czwartą linię. To pozostawia oba pola w takcie. Jednak po 19342823075080880373zdekodowaniu wynikowej liczby całkowitej odpowiadający ciąg znaków zawiera punkt kodowy, 0x18D53Bktóry nie jest prawidłowym znakiem Unicode, System.Char.ConvertFromUtf32ulega awarii z ArgumentOutOfRangeException.
  • Usuń pełną linię, zaczynając od prawego górnego rogu. Ponownie oba pola są taktowane, ale wynikowa liczba całkowita 508088037380718711zawierałaby dwa nieprawidłowe punkty kodowe 0x1B0635i 0x140077prowadziłaby do tego samego wyjątku.

Zauważ, że nawet bez pustego bloku komentarza usunięcie drugiego wiersza doprowadziłoby do nieprawidłowego punktu kodowego. Ale blok komentarz zapobiega że bierzemy linię od środka drugiej linii, aby uzyskać całkowitą, jak 193428037380718711na przykład, który nie spowoduje błąd.

Martin Ender
źródło
Co się stanie, jeśli usuniesz podciąg zaczynający się od znaku po złączu wyjściowym i kończący dokładnie 1 linię później? tzn. usunięcie środkowej linii bloku komentarza i linii zawierającej „80718711” w bloku głównym, ale pozostawienie nienaruszonych narożników obu pól.
Steve
@ Steve Poprawiłem odpowiedź, aby uwzględnić tę sprawę. Po przyjrzeniu się temu trochę więcej, pozwoliło mi to na zapisanie dwóch znaków / sześciu bajtów.
Martin Ender
10

Ruby, 36

eval(*[(s="planet")[$>.write(s)^6]])

Przypisujemy s="planet", a następnie zapisujemy ten ciąg do STDOUT. Zwraca liczbę napisanych znaków. Xor to z 6, więc jeśli cokolwiek innego niż 6 znaków zostanie napisane, otrzymamy niezerową liczbę całkowitą. Następnie dzielimy się na sten indeks. Tylko 0 znak s„p” jest poprawnym łańcuchem (no-op). Przekazujemy to do eval, używając (*[argument])składni równoważnej tylko (argument)z tym wyjątkiem, że nie jest poprawna poza wywołaniem metody.

Priorytet zweryfikowany programowo na Ruby 1.9.3 i 2.2

histocrat
źródło
O kurczę. To jest niesamowite.
klaskać
Co się stanie, jeśli usuniesz *?
LegionMammal978,
Następnie przekazujesz tablicę do eval zamiast łańcucha, który jest ArgumentError.
histocrat
9

C #, 128 118 101 bajtów

Myśl o nadużywaniu ciągłej reguły podciągów.

Kod

class h{static void Main()=>System.Console.Write(new char[1
#if!i
*5]{'w','o','r','l','d'
#endif
});}

Dlaczego to działa

  1. class hi static void Main()są wymagane.
  2. Usunięcie któregokolwiek z znaków 'w','o','r','l','d'powoduje błąd, ponieważ tablica znaków jest inicjowana długością 1*5.
  3. Nie można usunąć zawartości wewnątrz Main () bez naruszenia zasady ciągłego znakowania, ponieważ części są oddzielone przez preprocsy. (Patrz poniżej)

Przed golfem i separacją

class h
{
    static void Main() =>
        System.Console.Write(new char[1 * 5]{'w','o','r','l','d'});
}

Zweryfikowano za pomocą

https://ideone.com/wEdB54

EDYTOWAĆ:

  • Zapisano niektóre bajty, używając #if !xzamiast #if x #else.
  • Użyto =>składni func. #if!xzamiast #if !x. Kredyty dla @JohnBot.
  • Ze względu na =>składnię func można usunąć dodatkowy warunek preproc.
Helix Quar
źródło
Cześć helix! Czy uważasz, że możesz wyjaśnić, w jaki sposób i dlaczego twoja odpowiedź działa nieco bardziej?
isaacg,
@isaacg Edytowane. Dowód do naśladowania.
Helix Quar,
Nie mogę go uruchomić bez staticdnia Main.
Johnbot,
@Johnbot Tak. Musiałem się skradzić. Naprawiony.
Helix Quar,
Można zapisać charakter poprzez Maine element funkcyjny Expression treściwe i 2 więcej usuwając spacje przed warunkiem preprocesora: class h{static void Main()=>System.Console.Write(new char[1\n#if!l\n*5]{'w','o','r','l','d'\n#if!o\n});\n#endif\n}\n#endif. Według mojego obliczenia to 115.
Johnbot,
9

MATLAB, 37 36 33 bajtów

feval(@disp,reshape('world',1,5))

Ponieważ nie jestem pewien, czy wolno nam również wypisywać ans = , musiałem znaleźć jakieś obejście, aby wypisać w odpowiedni sposób. Samo używanie fprintf nie działało, ponieważ bez względu na to, co próbowałem, po prostu odmawiałem błędu. Samo użycie disp nie było opcją, ponieważ wymagałoby tylko 1 argumentu, a sam argument oczywiście wykonałby się również bez błędów.

Jeśli dołączenie ans = do wyjścia nie stanowi problemu , MATLAB można wykonać za pomocą 20 bajtów :

reshape('world',1,5)
slvrbld
źródło
naprawdę muszę dowiedzieć się więcej o funkcjach wbudowanych (+1) // btw twój program ma ocenę 20
Abr001am
2
To naprawdę zależy od tego, jak surowe są zasady. Stwierdzają, że należy wypisać tylko „świat” (+ opcjonalny końcowy znak nowej linii), więc to 33 bajty.
slvrbld
Tak, policzymy to jako 33. Dziękujemy za zrozumienie :)
Hobby Calvina
9

> <> , 17 bajtów

e"ooooo7-c0pBhtra

Wypróbuj online!

Drukuje „ziemię”.

Jedynym sposobem, w jaki ><>program zamyka się bezbłędnie, jest wykonanie ;znaku, co stanowi problem, ponieważ można po prostu usunąć wszystkie znaki wcześniej, aby ;był to pierwszy wykonany znak. Aby obejść ten problem, użyj ppolecenia, aby ;zamiast tego zmodyfikować program tak, aby dołączał się do niego podczas wykonywania. Usunięcie jakiejkolwiek sekcji kodu powoduje, że ;nigdy nie zostanie wygenerowane, powodując błędy poprzez nieprawidłowe instrukcje B, ha także tniedopełnienie stosu i nieskończone pętle, które ostatecznie zabrakną pamięci. Musiałem tylko upewnić się, że wszystkie nieskończone pętle zapełniają cały stos.

Wszystkie warianty zostały przetestowane przy użyciu tego fragmentu kodu python:

code = 'e"ooooo7-c0pBhtra'
count = {"invalid":0, "underflow":0, "memory":0}
for l in range(1, len(code)):
    for x in range(0, len(code)-l+1):
        print(code[:x] + code[x+l:], "\t\t", end='')
        try:
            interp = Interpreter(code[:x]+code[x+l:])
            for _ in range(0,1000):
                interp.move()
            print(len(interp._stack), "< ", end='')
            interp2 = Interpreter(code[:x]+code[x+l:])
            for _ in range(0,2000):
                interp2.move()
            print(len(interp2._stack))
            count["memory"] += 1
        except Exception as e:
            print(e)
            if str(e) == "pop from empty list": count["underflow"] += 1
            else: count["invalid"] += 1
print(count) 
#don't judge me

dodane do (nieco zmodyfikowanej wersji) oficjalnego interpretera fish.py przez twórcę> <>. Spośród 152 możliwych podprogramów, 92 zignorowano z powodu niepoprawnych instrukcji, 18 z niedopełnienia stosu, a 42 z braku pamięci.

Śmieszne fakty, pierwsza wersja tego e"ooooo6-c0pAhtramiała kilka dziwacznych podprogramów, którym udało się użyć polecenia put, aby umieścić plik, [który wyczyści stos, zamiast niepoprawnej instrukcji A. Również „ziemia” jest jedynym z wyrażeń, które będą działać z tą metodą, ponieważ pierwsza litera ejest prawidłową instrukcją w ><>. W przeciwnym razie "polecenie musi zostać umieszczone z przodu programu, a prawidłowy podprogram może być "sam.

Jo King
źródło
8

Ruby, 34

eval(*[($>.write("world")-1).chr])

Ma to kilka elementów:

eval(*[ expr ]) jest zapożyczony z odpowiedzi histocrata i jest nieskazitelny, a także weryfikacja wartości zwracanej expr jest prawidłowym programem ruby, który nie zawiera błędów. method(*arr)to składnia ruby, która wywołuje methodwartości arrargumentów jako wartości. Powodem, dla którego jest to potrzebne, jest to, że jest poprawny tylko jako parametry metody, więc jeśli evalzostanie usunięty, (*[expr])jest to błąd składniowy. Jeśli wyrażenie zostanie usunięte, evalnarzeka na brak wystarczających argumentów

$>.write("world")-1nie może być zniekształcony, z wyjątkiem wewnątrz ciągu i odejmowania. $>.write("world")zapisuje „świat” do STDOUT i zwraca liczbę zapisanych znaków, a następnie odejmuje 1. Dlatego jeśli program nie jest zniekształcony, wartość będzie wynosić dokładnie 4 . Jeśli jest zniekształcony (albo -1jest usunięty, albo łańcuch skrócony), zwróci jeden z -1,0, 1, 2, 3 lub 5 . Każde inne zniekształcenie powoduje błąd składniowy.

Wywołanie chrnumeru zwraca znak reprezentowany przez ten numer. Tak więc, wywołany w wyniku powyższego przykładu, popełnia błąd na -1, w przeciwnym razie zwraca łańcuch jednoznakowy.

Nie jestem właściwie pewien, dlaczego tak jest, ale wygląda na to, że Ruby interpretuje \x04jako znak spacji, co oznacza, że ​​wyrażenie jest poprawne (puste programy ruby ​​nic nie robią). Jednak dowolny z pozostałych znaków ( \x00- \x03i \x05) powoduje Invalid char '\x01' in expression. Znalazłem to, po prostu iterując nad możliwą matematyką, którą mógłbym zrobić z liczbą zwróconą. Wcześniej korzystałem

$>.write("planet
")*16

gdzie „planeta” plus znak nowej linii to 7 znaków, razy 16, aby uzyskać 112 p, jedyna funkcja litera w języku Ruby jest domyślnie zdefiniowana. Jeśli nie otrzyma żadnych argumentów, jest to faktycznie brak możliwości


Wyróżnienie: $><<"%c"*5%%w(w o r l d)jest bardzo blisko, ale nie jest nieskazitelne. Usunięcie "%c"*5%powoduje brak błędów. Mini wyjaśnienie:

$>jest stdout i <<jest wywoływaną funkcją. "%c"*5generuje ciąg formatu "%c%c%c%c%c", który następnie próbuje być sformatowany ( %) przez tablicę: %w(w o r l d)która jest krótszą wersją ['w','o','r','l','d']. Jeśli w tablicy jest za mało lub za dużo elementów, które nie pasują do ciągu formatu, generowany jest błąd. Pięta achillesowa jest taka "%c"*5i %w(w o r l d)może istnieć niezależnie, i $><<potrzebuje tylko argumentu obu. Istnieje więc kilka różnych sposobów przekształcania tego programu w kuzynów bez błędów.


Zweryfikowano za pomocą:

s = 'eval(*[($>.write("world")-1).chr])'
puts s.size
(1...s.length).each do |len| #how much to remove
  (0...len).each do |i| #where to remove from
    to_test = s.dup
    to_test.slice!(i,len)
    begin #Feels so backwards; I want it to error and I'm sad when it works.
      eval(to_test)
      puts to_test
      puts "WORKED :("
      exit
    rescue SyntaxError
      #Have to have a separate rescue since syntax errors
      #are not in the same category as most other errors
      #in ruby, and so are not caught by default with 
      #a plain rescue
    rescue
      #this is good
    end
  end
end
Shelvacu
źródło
Przyjemne byłoby wyjaśnienie odpowiadające odpowiedzi histokraty . Wygląda na to, że używasz tego samego podstawowego podejścia, ale ponieważ nie znam Ruby, nie mogę zrozumieć szczegółów.
ThisSuitIsBlackNot
@ThisSuitIsBlackNot Czy dałem z siebie wszystko, czego nie rozumiesz?
Shelvacu,
Doskonałe wyjaśnienie, dzięki!
ThisSuitIsBlackNot
6

Python 3 , 43 bajty

for[]in{5:[]}[open(1,"w").write("world")]:a

Wypróbuj online!

Jak to działa

Aby chronić przed usunięciem podciągów, używamy open(1,"w").writezamiast print. W Pythonie 3 writezwraca liczbę napisanych znaków, które sprawdzimy, 5aby upewnić się, że żadna część łańcucha nie została usunięta. Robimy to, sprawdzając wartość zwracaną w słowniku {5:[]}i zapętlając wynik for[]in…:a, co zakończy się niepowodzeniem, jeśli nie otrzymamy pustej iterowalnej forinstrukcji lub jeśli instrukcja zostanie usunięta.

Anders Kaseorg
źródło
4

JavaScript (Node.js), 93 95 bajtów

if(l=arguments.callee.toString().length,l!=158)throw l;console.log("world");if(g=l!=158)throw g

Sprawdź dwukrotnie swój rozmiar, aby w razie braku znaków generowany był błąd. Długość wynosi 156, ponieważ Node.js poprzedza function (exports, require, module, __filename, __dirname) {kod w czasie wykonywania.

Dzięki Martin Büttner za wskazanie błędu. Naprawiono teraz.

Naouak
źródło
4

Perl 5.10+, 71 63 bajtów

(${open 0;@{\(read(0,$a,63)!=63?die:@_)};say"world"});{$a//die}

Drukuje worldz końcowym znakiem nowej linii. Uruchom tak:

perl -M5.010 file

Zależy to od liczby bajtów kodu źródłowego, więc filemusi zawierać powyższy kod i nic więcej (bez shebang, bez końcowego znaku nowej linii). Wymagany jest Perl 5.10+ sayi operator zdefiniowany //.


Stworzenie nieskazitelnego programu w Perlu jest niezwykle trudne, ponieważ:

  • Dowolny identyfikator gołe słowo (na przykład foo, a, _) jest ważne stwierdzenie z no strict 'subs';(domyślnie). Oznacza to, że program nie może rozpoczynać się ani kończyć literą, cyfrą ani podkreśleniem.

  • Jak wyjaśnia tchrist , „Identyfikatory określone poprzez dereferencję symboliczną absolutnie nie mają żadnych ograniczeń w ich nazwach”. Oznacza to, że program nie może się rozpocząć z jednego z sigilami $, @, %, lub *, ponieważ usuwając wszystkie oprócz pierwszego i ostatniego znaku zawsze pozostawić poprawną nazwę zmiennej.

  • Wiele wbudowanych funkcji (w tym większość funkcji generujących dane wyjściowe) działa $_domyślnie, więc wywołania często działają, nawet jeśli usuniesz argument (np. say"world"Vs. say).

Jak to działa

To rozwiązanie zostało zainspirowane odpowiedzią Node.js firmy Naouak , która sprawdza swoją długość, aby upewnić się, że znaki nie zostały usunięte.

Program ma dwie sekcje, jedną w nawiasach, a drugą w bloku:

(...);{...}

Pierwsza sekcja odczytuje plik źródłowy i umiera, jeśli ma mniej niż 63 znaki. Druga sekcja sprawdza, czy readwykonanie zakończyło się pomyślnie. Jeśli jedna sekcja zostanie usunięta (z nawiasami otaczającymi lub nawiasami klamrowymi lub bez), druga sekcja zgłosi wyjątek.

Usunięcie środkowej, lewej lub prawej strony programu spowoduje wyważenie nawiasów i / lub nawiasów klamrowych, powodując błąd składniowy.

Jeśli pierwszy diezostanie zmieniony (do d, e, di, de, lub ie, które są ważne identyfikatory), kontrola długości staje się:

@{\(read(0,$a,63)!=63?di:@_)};

który ocenia:

@{\'di'};

Pobiera odwołanie do łańcucha i próbuje wyrejestrować go jako tablicę, powodując błąd:

Not an ARRAY reference

Jeśli jakakolwiek inna instrukcja zostanie zmieniona, sprawdzanie długości zakończy się niepowodzeniem i program umrze.


Zweryfikowano nieskazitelność za pomocą następującego programu:

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

use File::Temp;
use List::MoreUtils qw(uniq);

sub delete_substr {
    my ($str, $offset, $len) = @_;

    my $tmp = $str;
    substr($tmp, $offset, $len) = '';

    return $tmp;
}

sub generate_subprograms {
    my ($source) = @_;

    my $tot_len = length $source;
    my @subprograms;                                             

    foreach my $len (1 .. $tot_len - 1) { 
        foreach my $offset (0 .. $tot_len - $len) {
            push @subprograms, delete_substr($source, $offset, $len);
        }                                                        
    }                                                            

    return uniq @subprograms;                                    
}                                                                

chomp(my $source = <DATA>);                                                                                                       
my $temp = File::Temp->new;                                                                                        

foreach my $subprogram ( generate_subprograms($source) ) {       
    print $temp $subprogram;

    my $ret = system(qq{/usr/bin/perl -M5.010 $temp > /dev/null 2>&1});
    say($subprogram), last if $ret == 0;

    truncate $temp, 0;
    seek $temp, 0, 0;
}

__DATA__
(${open 0;@{\(read(0,$a,63)!=63?die:@_)};say"world"});{$a//die}
ThisSuitIsBlackNot
źródło
4

Ruby + coreutils, 33 27 26 bajtów

`base#{$>.write"world
"}4`

Wypróbuj online!

Rubiki w ruby ​​wykonują wewnątrz nich polecenie i zwracają wszystko, co program wstawiony do STDOUT jako ciąg znaków. #{expr}Składnia umożliwia umieszczanie wyrażeń w ciągach znaków i backticks. Ten program można przepisać (nieskazitelnie) jako:

system("base" + (STDOUT.write("world\n")).to_s + "4")

IO#writezwraca liczbę zapisanych bajtów, więc jeśli łańcuch zostanie skrócony, nie będzie to właściwa liczba. #{}Osadzenie automatycznie przekształca liczbę w ciąg znaków. Jeśli jakiś element zostanie usunięty i nie spowoduje to błędu składniowego, uruchomione zostanie niepoprawne polecenie. Jeśli część "world"zostanie usunięta niż jednego base04through base54spróbuje uruchomić.

Wymagana jest nowa linia, zarówno w ciągu, jak i poza nim. W przeciwnym razie pierwsze 5 znaków ( `base) można usunąć, dzięki czemu cały wiersz będzie komentarzem. Musi także znajdować się jeden lub więcej znaków między pierwszym kliknięciem wstecznym #, w przeciwnym razie {można je usunąć, aby cały komentarz stał się komentarzem powłoki .


exec(*[(s="ec%co earth")%s[10]])

execZastępuje bieżący proces ruby ​​podanym poleceniem. Zobacz moją drugą odpowiedź, aby uzyskać wyjaśnienie meth(*[])składni i jej konieczności.

(s="ec%co earth")przypisuje ciąg „ec% co earth” do zmiennej s. Przydziały zwracają to, co zostało przypisane, więc łańcuch również jest zwracany.

"format string %d" % 5jest cukrem syntaktycznym sprintf("format string %d",5), jednak odstępy wokół %nie są konieczne.

s[10]pobiera znak w ciągu o indeksie 10. Gdy nie jest zniekształcony, znak ten to „h”, ostatnia litera w ciągu. Jednak usunięcie dowolnych znaków w ciągu oznacza, że ​​jest on krótszy, więc nie ma znaku w indeksie 10, więc s[10]powraca nili "%c" % nilpowoduje błąd.

jeśli %s[10]zostanie usunięty, wówczas Ruby próbuje uruchomić polecenie, ec%co earthktóre nie działa.

Zmiana 10na 1lub 0powoduje również nieznane polecenie (albo eceolub ecco). Całkowite usunięcie go technicznie nie jest błędem składniowym, ponieważ wywołuje metodę #[]w ciągu, ale narzeka na niewystarczającą liczbę argumentów.


Uwaga na temat ogólnego rozwiązania tego problemu: Musisz mieć jakieś opakowanie, które weryfikuje kod wewnątrz w sposób abstrakcyjny, będąc jednocześnie nieskazitelnym. Na przykład program z podziałem na końcu ( blablabla/somevar) nigdy nie zadziała, ponieważ podział można zawsze usunąć ( blablabla). Oto kilka takich opakowań, z których korzystałem do tej pory:

  • eval(*[kod ])używany przez histocrat i w mojej pierwszej odpowiedzi. Sprawdza, czy dane wyjściowe są poprawnym programem ruby
  • exec(*[kod ])użyty powyżej potwierdza, że ​​odpowiedź jest poprawną komendą
  • `#{ kod }`

Składnia wsteczna uruchamia również polecenie (i dlatego potwierdza, że ​​jest poprawna), jednak STDOUT jest przechwytywany jako ciąg zamiast wyprowadzania jako proces nadrzędny STDOUT (Ruby's). Z tego powodu nie mogłem użyć go do tej odpowiedzi, EDYCJA: Sprawiłem, że zadziałało. Ograniczenia przedstawione powyżej.

Edycja: Podziękowania dla @histocrat za wskazanie pewnych wad

Shelvacu
źródło
Fajne podejście! Możesz (i dlatego musisz) usunąć odstęp między writepoczątkiem ciągu, ale nie sądzę, żeby miało to wpływ na nieskazitelność. Ponadto na moim komputerze base64zawiesi się oczekiwanie na dane wejściowe, co może być niezgodne z regułami.
histocrat
@histocrat Wow, jestem zaskoczony, że to $>.write"world"działa, dzięki! Jeśli chodzi o czekanie na base64, wydaje się, że różni się w zależności od systemu. TIO działa dobrze. To sprawia, że ​​jest jeszcze bardziej niewyraźne, czy przestrzega zasad.
Shelvacu,
3

PowerShell, (97 bajtów + 5 dla nazwy programu) = 102 bajtów

"$(try{if(($a=(gc .\c.ps1).Length)-eq97){"world";a}}catch{if($a-ne97){a}$error.clear();exit}a)";a

Sprawdza się, zanim się zniszczy ... dwa razy.

Oczekuje, że zostanie zapisany jako c.ps1i wykonane z lokalnego katalogu jako takiego:
PS C:\Tools\Scripts\Golfing\> .\c.ps1.

Alias gcjest skrótem od Get-Contenti jest podobny do catodczytu pliku (w tym przypadku naszej ścieżki wykonania .\c.ps1). Pobieramy .Lengthplik, ustawiamy go $ai sprawdzamy, czy nie jest równy 97 z -eq97. Jeśli jest równy (tzn. Program nie został zmodyfikowany), drukujemy za pomocą "world"i wykonujemy nieprawidłowe polecenie a. Zmusza to catchdo działania, co pozwala nam sprawdzić się ponownie. Tym razem, jeśli nasz kod nie jest równy 97, rzucamy niepoprawne polecenie, więc nasz program błędnie wydrukował tekst błędu na wyjściu. Mamy wtedy clear()błąd i exitnormalnie.

Oczywiste jest, że jeśli którekolwiek ifz nich zostanie zmienione, w drugim wystąpi błąd. Jeśli jakakolwiek część "world";zostanie zmieniona, pierwsza ifspowoduje błąd. Ponieważ musi być ciągły, nie możemy usunąć obu ifinstrukcji. Łańcuchy na środku spowodują niedopasowane nawiasy lub spowodują wykonanie drugiego {a}. Symbol try/ catchma wychwycić błąd z pierwszej ifinstrukcji, abyśmy mogli go poprawnie usunąć. Zewnętrzne "$( )"zapobiegają cięciu strun z obu końców. Ostatnim ;ajest zapobieganie wycinaniu części środkowej, które skutkowałyby prawidłowymi programami (np. "it}a)";a, Które wydrukują, it}a)a następnie wystąpią błędy).

Istnieje kilka szczególnych okoliczności:

  • Jeżeli gc, gc<space>lub gc .\są usuwane, program będzie ostatecznie błędu się z jakimś smakiem out błędu pamięci (z powodu wielokrotnych wezwań self-egzekucyjnym) i prawdopodobnej katastrofie skorupy (a może i komputera). Nie testowany.
  • Jeśli <space>.\c.ps1lub .\c.ps1zostaną usunięte, program zatrzyma się i poprosi użytkownika o wprowadzenie danych. Bez względu na to, co wprowadzi użytkownik, program nadal będzie występować błąd, ponieważ liczenie rozmiaru będzie nieprawidłowe.
  • Jeśli podciąg rozpoczynający się od $i kończący się przed ostatnim "jest wycinany, program wyświetli wszystko, co pozostanie, a następnie wystąpi błąd, ponieważ anie jest prawidłowy.

Zweryfikowano za pomocą:

$x='"$(try{if(($a=(gc .\c.ps1).Length)-eq97){"world";a}}catch{if($a-ne97){a}$error.clear();exit}a)";a'
$yy='"$(try{if(($a=( .\c.ps1).Length)-eq97){"world";a}}catch{if($a-ne97){a}$error.clear();exit}a)";a'
$yyy='"$(try{if(($a=(.\c.ps1).Length)-eq97){"world";a}}catch{if($a-ne97){a}$error.clear();exit}a)";a'
$yyyy='"$(try{if(($a=(c.ps1).Length)-eq97){"world";a}}catch{if($a-ne97){a}$error.clear();exit}a)";a'

for($i=1;$i-lt$x.Length;$i++){
  for($j=0;$j-lt($x.Length-$i);$j++){
    $y=($x[0..$j]+$x[($i+$j+1)..$x.Length])-join''
    $y>.\c.ps1
    $error.clear()
    if(!($y-in($yy,$yyy,$yyyy))){try{.\c.ps1}catch{};if(!($error)){exit}}
    $q++;
    write-host -n "."
    if(!($q%150)){""}
  }
}
"No success."

(Podziękowania dla Martina za jego rozległą pomoc!)

AdmBorkBork
źródło
3

C (gcc) (Linux, -Werror=undef), 66 bajtów

main(a){a
=
1
/
(puts("world")/
6);
#if(7^__LINE__)
#else
}
#endif

Wypróbuj online!

Świetne wyzwanie! To było zwodniczo trudne, ale jestem prawie pewien, że mam teraz prawidłowy program!

Używa polecenia preprocesora, aby nie można było usunąć nowych linii, ponieważ nawias zamykający do mainjest uwzględniany tylko wtedy, gdy __LINE__==6. Uniemożliwia również maincałkowite wyczyszczenie , ponieważ pozostawia to swobodę ruchu #endif(ważne jest, aby #endifbyło poza main).

Użyłem, #elseponieważ byłem dość przekonany, że żadna wersja __LINE__==6tego nie może usunąć podciągu i nadal jest prawdziwa, ponieważ zarówno one, jak 6i __LINE__same są prawdziwe. Używa również -Werror=undef, aby coś takiego #ifdef(LINE__)nie było fałszywe, ale było błędem.

W przypadku gcc (przynajmniej w Linuksie) putszwraca liczbę wydrukowanych znaków (w tym znak nowej linii), więc usunięcie dowolnej części ciągu powoduje puts("...")/6powrót 0, co 1/0powoduje wyjątek zmiennoprzecinkowy. Zauważ, że ten wyjątek nie jest spowodowany, chyba że 1/0jest przypisany do czegoś, więc a=jest wymagany.

Żadna inna część linii nie może zostać usunięta bez utworzenia błędu, zwykle błędu składniowego lub błędu łączenia.

Jako bonus, daje to dość trywialne 86-bajtowe rozwiązanie dla C ++, wystarczy dodać #include <cstdio>i zadeklarować ajako int. Wypróbuj online! (C ++)

Chris
źródło
O ile się nie mylę, możesz usunąć 1/podczas opuszczania nowej linii i nadal będzie działać .
gastropner
@gastropner Masz rację. 1przypuszczalnie w poprzedniej linii.
Chris
Niestety, to samo dotyczy. Następnie możesz usunąć =1. Myślę, że musisz ustawić 1 na linii samodzielnie.
gastropner
@gastropner Myślę, że masz rację. Zobaczę później. Dzięki!
Chris
2

PHP, 73 bajty

<?=call_user_func(($p='ns')|(($f="u{$p}erialize"))?$f:'','s:5:"world"');

Wyjaśnienie

Zakładam domyślną konfigurację php.ini. Więc short_tags jest wyłączone. Oznacza to, że nie można usunąć =tagu otwierającego.

To jest w zasadzie <?=unserialize('s:5:"world"');.

Jeśli usuniesz dowolną część serializowanego ciągu, pojawi się błąd.

Możesz po prostu usunąć, unserializea skrypt po prostu wyświetli szeregowany ciąg. Aby temu zaradzić, używam call_user_func. Usunięcie jednego z parametrów spowoduje błąd.

'<?=call_user_func('unserialize','s:5:"world"');

Można jednak usunąć un, aby wywołać serializefunkcję. Więc wyjmujemy „ns”. Usunięcie jakichkolwiek znaków nie spowoduje niepoprawnej nazwy funkcji.

<?=call_user_func(($p='ns')&&($f="u{$p}erialize")?$f:'','s:5:"world"');

Użyjemy inline, jeśli będziemy używać przypisania zmiennej ze znacznikiem wyjściowym. Zamiast używać &&używamy „|” aby zapobiec usunięciu pojedynczego &lub usunięciu $fzadania

Możesz usunąć ='ns')&&($f="u{$p}erialize"i skończyć z ($p)?$f:''. Dlatego dodaję dodatkowy nawias wokół $f="u{$p}erialize".

Uwaga

Technicznie możesz usunąć otwierające tagi bez powodowania błędu. Nie jest to jednak już skrypt PHP, ale zwykły plik tekstowy.

Jasny - Arnold Daniels
źródło
2
Jeśli chodzi o twoją ostatnią notatkę, zwykły plik tekstowy nadal byłby prawidłowym programem PHP, prawda? Więc nie jestem pewien, czy to jest poprawne.
Calvin's Hobbies
To już nie jest PHP, ale zwykły tekst / HTML, więc nie jest to już poprawny program php
Martijn
1

Matlab (77)

bsxfun(@(c,b)arrayfun(@(x)getfield(c,{x}),conv(b,ismember(4,b))),'world',1:5)

Spróbuj

Uwaga:

Zgodnie z radą @ Optimiser dotyczącą zaprojektowania resuscytacji krążeniowo-oddechowej lub czegoś takiego, stanąłem wobec nieprzewidzianych podciągów, które nie prowadziły do ​​żadnego błędu kompilacji po usunięciu, przykład: usunięcie arrayfun(@(x)a(x),prod(b,ismember(4,1:5))),z poprzedniej edycji feval(@(a)arrayfun(@(x)a(x),prod(b,ismember(4,1:5))),'world')nie generuje żadnego błędu! również w przypadku tej samej edycji były bsxfun(@(a,b)arrayfun(@(x)(x),prod(b,ismember(4,b))),'world',1:5)i bsxfun(@(a,b)a,'world',1:5), jeśli zapytałeś o to, jak się znajdowałem, gdy znalazłem je w konsoli wyjściowej, płakałem jak dziecko, więc oto program:

b=0;string='bsxfun(@(c,b)arrayfun(@(x)getfield(c,{x}),conv(b,ismember(4,b))),''world'',1:5)'
for u=1:numel(string),for j=u:numel(string)-2,try a=eval([string(1:u) string(j+2:end)]);catch(b); a=0;end; if a~=0, ['here is it : ' string(1:u) string(j+2:end)],end;end;end

Przykład nieoczyszczącego programu

edytować:

Dziękujemy wszystkim oprócz @Martin za wskazanie mojego poprzedniego kodu (bez błędów).

Abr001am
źródło
1

SmileBASIC, 63 bajty

REPEAT
A=1/(PRGSIZE(0,1)==63)?"world
UNTIL 1/(PRGSIZE(0,1)==63)
12Me21
źródło
1

Grusza , 17 bajtów

Ten program zawiera bajty z ustawionym wysokim bitem (które nie są poprawne UTF-8 i dlatego nie mogą być wysyłane do TIO), więc oto xxdodwracalny zrzut heksowy:

00000000: 7072 696e 7427 776f 726c 6427 23cd 4290  print'world'#.B.
00000010: bf                                       .

Wyjaśnienie

Jest to tylko print'world'z dołączoną sumą kontrolną. Za pomocą brutalnej siły zweryfikowałem, że żadne z możliwych usunięć nie daje programowi z prawidłową sumą kontrolną, więc po każdym możliwym usunięciu pojawia się błąd.

Dość nudne, ale wiąże obecnego lidera, więc czułem, że warto było pisać.

ais523
źródło