Du hattest mich bei Hallo

30

Aufgabe

Lesen Sie einen möglicherweise unendlichen Textstrom oder eine Datei ein und geben Sie den Inhalt aus, bis das Wort helloausgegeben wurde. Beachten Sie dabei die folgenden Regeln.

  • Nach helloder Ausgabe sollte Ihr Code sofort beendet werden. Es sollte beispielsweise nicht auf eine neue Zeile warten.

  • Ihr Code sollte so wie er ist ausgegeben werden. Das heißt, es sollte nicht zu viele Eingaben einlesen und dann mit der Ausgabe beginnen.

  • Wenn der Stream / die Datei keine enthält hello, sollte Ihr Code die Eingabe nur für immer oder bis zum Ende des Streams / der Datei ausgeben.

  • Dies ist eine case sensitive Herausforderung, also hellonicht gleich Hello.

  • Sie können davon ausgehen, dass die Eingabe ausschließlich aus druckbaren ASCII-Zeichen und Zeilenumbrüchen besteht.

  • Ihr Code kann nicht erwarten, dass der Text durch eine neue Zeile abgeschlossen wird oder dass die Eingabe überhaupt neue Zeilen enthält. Außerdem können Sie nicht davon ausgehen, dass der Code auf einem Computer mit unendlich viel Speicher ausgeführt wird.

  • Sie können davon ausgehen, dass Ihr Code aus einem leeren Verzeichnis aufgerufen wird.

Beispiel für einen Eingabestream

I once had a horse called hellopina.

Ausgabe

I once had a horse called hello

Spitze

Führen Sie es aus yes | tr -d \\n | <your program>, um zu überprüfen, ob es mit unendlichen Streams funktioniert. Wenn nichts gedruckt wird und / oder Speicherplatz verloren geht, stimmt das Programm nicht mit der Spezifikation überein. Es sollte yyyyyyyyyyyyyyyyyyyyyy...für immer ohne Zeilenumbrüche gedruckt werden.

Dennis
quelle
1
Dürfen wir nach dem "Hallo" noch etwas lesen? Die Frage scheint jegliches zusätzliche Lesen zu verbieten, was in Sprachen wie (Standard) C problematisch sein könnte, die gepufferte Eingaben mit automatischem Vorauslesen bereitstellen.
Toby Speight
Sie sollten wahrscheinlich die akzeptierte Antwort auf die Assembly ändern, da sie 2 Byte kürzer ist.
18.
@Riker Es wäre toll, wenn jemand es testen könnte oder zumindest sagt, dass es zuerst funktioniert.

Antworten:

2

Gelee , 24 Bytes

“Ṣẉ»ẇ⁸Ṇȧ®
ṫ-3;ƈ©Ȯ¤µ⁺Ç¿ṛ“

Probieren Sie es online!

Erläuterung:

ṫ-3;ƈ©Ȯ¤µ⁺Ç¿ṛ“ Main link. Arguments: 0
ṫ-3            Truncate the list to its 4 last elements.
   ;ƈ©Ȯ¤       Store a character from STDIN in the register, print it, and append it to the list (list is initially [0]).
        µ      Start a new monadic chain, everything to the left is a link.
          Ç    Execute the helper link with the existing list as its argument.
         ⁺ ¿   Do-while loop, left link is body, right link is condition.
            ṛ“ When the loop ends, replace the return value with [] (invisible on output).

“Ṣẉ»ẇ⁸Ṇȧ® Helper link. Arguments: string
“Ṣẉ»ẉ⁸Ṇ   Check if "hello" isn't in the string.
        ® Return the character we stored in the register.
       ȧ  Check if both of the above are truthy.
Erik der Outgolfer
quelle
26

C (gcc) , 81 80 76 75 72 71 70 69 Bytes

main(n,c){while(~(c=getchar())&n-0xb33def<<7)n=n<<5^putchar(c)/96*c;}

Probieren Sie es online!

Wie es funktioniert

Dies ist ein volles Programm. Wir definieren eine Funktion f für unsere Zwecke. Um Bytes zu sparen, wird mit zwei Argumenten deklariert, die standardmäßig int sind . Dies ist undefiniertes Verhalten, aber in der Praxis wird n als 1 initialisiert, wenn das Programm ohne zusätzliche Argumente ausgeführt wird. C enthält die unteren 32 Bits des Zeigers auf den Argumentvektor

Während der Bedingung

~(c=getchar())&n-0xb33def<<7

hält, werden wir den Körper der while- Schleife ausführen :

n=n<<5^putchar(c)/96*c

Um den Zustand vollständig zu verstehen, müssen wir zuerst den Körper untersuchen. Im c=getchar()Moment beobachten wir nur, dass ein einzelnes Byte aus STDIN (falls möglich) gelesen und in der Variablen c gespeichert wird .

Die Bytesequenz Hallo sieht in verschiedenen Darstellungen wie folgt aus.

char     decimal     binary (8 bits)
'h'      104         0 1 1 0 1 0 0 0
'e'      101         0 1 1 0 0 1 0 1
'l'      108         0 1 1 0 1 1 0 0
'l'      108         0 1 1 0 1 1 0 0
'o'      111         0 1 1 0 1 1 1 1

Alle diese fallen in den Bereich [96, 192) , so c/96wird bewerten 1 für jedes dieser Bytes und auf 0 für alle übrigen ASCII - Zeichen. Auf diese Weise putchar(c)/96*c( putchar druckt und gibt ihr Argument) wird bewerten , c , wenn c ist `, ein Kleinbuchstabe, eine der {|}~oder die DEL Zeichen; für alle anderen ASCII-Zeichen wird 0 ausgewertet .

n wird aktualisiert, indem es um fünf Bits nach links verschoben wird und anschließend das Ergebnis mit dem Ergebnis aus dem vorherigen Absatz XOR-verknüpft wird. Da ein Int 32 Bit breit ist (oder wie in dieser Antwort angenommen), könnten einige der verschobenen Bits "von links fallen" (vorzeichenbehafteter Integer-Überlauf ist undefiniertes Verhalten, aber gcc verhält sich wie der hier erzeugte x64-Befehl). Ausgehend von einem unbekannten Wert von n erhalten wir nach der Aktualisierung für alle Zeichen von hallo das folgende Ergebnis.

 n  ?????????????????????????|???????
'h'                          |    01101000
'e'                          |         01100101
'l'                          |              01101100
'l'                          |                   01101100
'o'                          |                        01101111
-----------------------------+--------------------------------
    <------ discarded ------>|???????0101100110011110111101111

Beachten Sie, dass die unteren 25 Bits die Ganzzahl 0xb33def bilden , die die magische Konstante in der Bedingung ist. Während es eine gewisse Überlappung zwischen den Bits zweier benachbarter Bytes gibt, stellt die Zuordnung von Bytes unter 96 zu 0 sicher, dass keine falsch positiven Ergebnisse vorliegen.

Die Bedingung besteht aus zwei Teilen:

  • ~(getchar()) Nimmt das bitweise NICHT des Ergebnisses des Lesens (oder des Versuchs, ein Byte aus STDIN zu lesen).

    Wenn getchar erfolgreich ist, wird der Wert des gelesenen Bytes als int zurückgegeben . Da die Eingabe ausschließlich aus ASCII-Zeichen besteht, können für das gelesene Byte nur die unteren 7 Bits festgelegt werden. In diesem Fall werden für das bitweise NICHT die höchsten 25 Bits festgelegt.

    Wenn getchar fehlschlägt (keine weitere Eingabe), wird -1 zurückgegeben und das bitweise NOT wird 0 sein .

  • n-0xb33def<<7subtrahiert die magische Konstante von vorher von n und verschiebt das Ergebnis um 7 Einheiten nach links.

    Wenn die letzten 5 gelesenen Bytes Hallo waren , sind die niedrigsten 25 Bits von n gleich 0xb33def, und die Subtraktion setzt sie auf Null. Das Verschieben der Differenz ergibt 0, da die 7 höchsten Bits "nach links fallen".

    Wenn andererseits die letzten 5 gelesenen Bytes nicht Hallo waren , wird eines der niedrigsten 25 Bits der Differenz gesetzt; Nach dem Verschieben wird eines der höchsten 25 Bits sein.

Wenn getchar erfolgreich war und wir noch kein Hallo ausgegeben haben , wird das bitweise UND gesetzt, das alle 25 höchsten Bits des linken Operanden und mindestens eines der 25 höchsten Bits des rechten Operanden enthält. Auf diese Weise &erhalten Sie eine Ganzzahl ungleich Null und die Schleife wird fortgesetzt.

Wenn andererseits die Eingabe erschöpft ist oder wir bereits Hallo gedruckt haben , ist einer der bitweisen UND-Operanden Null, und das Ergebnis auch. In diesem Fall brechen wir aus der Schleife aus und das Programm wird beendet.

Dennis
quelle
Sie sollten wahrscheinlich erwähnen, dass dies von der Eingabe abhängt, die in ASCII codiert wird, bevor Sie sich mit der Erläuterung befassen.
Toby Speight
2
@TobySpeight Ich glaube nicht, dass es üblich ist, dies anzugeben. Welche Art von ASCII-inkompatibler Codierung sollte eine C-Antwort verwenden?
Dennis
EBCDIC ist die offensichtliche Codierung, die nicht ASCII ist. C schreibt keine bestimmte Zeichenkodierung vor (nur, dass die Dezimalstellen der Reihe nach durch aufeinanderfolgende Werte dargestellt werden müssen).
Toby Speight
enthält den obigen Programmstopp , wenn der Strom , der die nicht ASCII- Zeichenfolge „« uA ÷ o“1: 111 o 6F 2: ÷ 246 f6 3: A 160 a0 4: ú 163 5:« 174
RosLuP
@RosLuP Die Challenge-Spezifikation garantiert, dass die Eingabe aus druckbaren ASCII-Zeichen und Zeilenumbrüchen besteht.
Dennis
19

Bash, 74 75 103 99 88 82 76 Bytes

-10 Bytes dank @DigitalTrauma!
-11 Bytes dank @manatwork!
-6 Bytes dank @Dennis!

IFS=
b=ppcg
while [ ${b/hello} ];do
read -rN1 a
b=${b: -4}$a
echo -n $a
done

Erläuterung:

IFS=    # making sure we can read whitespace properly
b=ppcg  # set the variable b to some arbitrary 4 letter string

while [ ${b/hello} ]; do  # while the variable b doesn't contain "hello", do the following
    read -rN1 a           # get input
    b=${b: -4}$a          # set b to its last 4 chars + the inputted char
    echo -n $a            # output the inputted char
done

Probieren Sie es online!

betseg
quelle
2
Das ist toll! Ich hatte gehofft, dass es eine heftige Antwort geben würde.
13

Labyrinth , 43 41 Bytes

Danke an Sp3000 für das Speichern von 2 Bytes.

<_%-742302873844_::%*:*:420#+.:%):,*652_>

Probieren Sie es online!

Erläuterung

Die Grundidee ist, die letzten fünf Zeichen in der Basis 256 in einer einzelnen Ganzzahl zu codieren. Wenn ein neues Zeichen eingeht, können wir es "anhängen", indem wir die ganze Zahl mit 256 multiplizieren und den neuen Codepunkt hinzufügen. Wenn wir nur die letzten 5 Zeichen betrachten wollen, nehmen wir den Wert modulo 256 5 = 2 40 = 1099511627776. Dann können wir einfach überprüfen, ob dieser Wert gleich 448378203247 ist, was wir erhalten, wenn wir die Codepunkte von behandeln helloals Base-256-Ziffern.

Wie für den Code ... <...>ist ein bisschen ein Labyrinth-Idiom. Damit können Sie eine Endlosschleife ohne bedingten Kontrollfluss in eine einzelne Zeile schreiben und so viele Bytes in Leerzeichen und Zeilenvorschüben einsparen. Die Hauptbedingung dafür ist, dass sich auf dem Stapel zwei verfügbare Werte befinden, wenn wir den erreichen <(normalerweise verwenden wir dafür 0s, aber der tatsächliche Wert ist willkürlich).

Natürlich benötigt das Programm eine Bedingungslogik, um herauszufinden, wann es zu beenden ist. Das bedingte Beenden des Programms ist jedoch möglich, indem durch einen Wert von Null dividiert wird, wenn das Programm beendet werden soll. Das <...>Konstrukt verschiebt die gesamte Zeile (zyklisch) nach links, wenn sich die IP am linken Ende befindet, und verschiebt sie dann sofort wieder in ihre Position. Dies bedeutet, dass der Code tatsächlich von rechts nach links ausgeführt wird. Kehren wir es um:

_256*,:)%:.+#024:*:*%::_448378203247-%_

Dies ist eine Iteration der Schleife, die ein Zeichen liest, endet, wenn wir EOF erreicht haben, das Zeichen druckt, es zu unserer Codierung hinzufügt, das auf 5 Zeichen abschneidet, auf Gleichheit mit prüft hellound wiederholt. So funktioniert das im Detail (denken Sie daran, dass Labyrinth stapelbasiert ist):

_256*            Multiply the encoding by 256 in preparation for the next iteration.
,                Read one byte from STDIN.
:)%              Duplicate, increment, modulo. If we hit EOF, then , returns
                 -1, so incrementing and modulo terminates the program due to
                 the attempted division by zero. However, if we did read a
                 character, we've just compute n % (n+1), which is always n itself.
:.               Print a copy of the character we just read.
+                Add it to our encoding (we'll make sure to multiply the
                 encoding by 256 at the end of the iteration, so there's room
                 for our new character).
#024             Push 1024, using the stack depth to push the initial 1.
:*:*             Square it twice. That gives 2^40.
%                Take the encoding modulo 2^40 to truncate it to the last 5
                 characters.
::               Make two copies of the encoding.
_448378203247    Push the value that corresponds to "hello".
-                Subtract it from the encoding, giving zero iff the last 5
                 characters were "hello".
%                Take the other copy of the encoding modulo this value, again
                 terminating if we've reached "hello".
                 The actual value of this modulo - if it didn't terminate the
                 the program - is junk, but we don't really care, we just need
                 any disposable value here for the <...>
_                We push a zero as the second disposable value.
Martin Ender
quelle
8

Brainfuck, 658 Bytes

+[>,.>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[-<->]+<[>-<[-]]>[-<,.>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[-<->]+<[>-<[-]]>[-<,.>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[-<->]+<[>-<[-]]>[-<,.>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[-<->]+<[>-<[-]]>[-<,.>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[-<->]+<[>-<[-]]>[-<<->>]]]]]<<]

Über 500 Bytes sind in den Konstanten, die ich ein bisschen Golf spielen muss.

Es ist im Wesentlichen eine Zustandsmaschine, sodass unendliche Eingaben kein Problem darstellen.

Dies ist die leicht kommentierte Version

+
[
  >,.
  >h
  [-<->]
  +<
  [
    >-<[-][in input spot, not h]
  ]
  >
  [
    -
    <
    [in input spot, h has been read]
    ,.
    >e
    [-<->]
    +<
    [
      >-<[-][in input spot, not e]
    ]
    >
    [
      -
      <
      [in input spot, e has been read]
      ,.
      >l
      [-<->]
      +<
      [
        >-<[-][in input spot, not l]
      ]
      >
      [
        -
        <
        [in input spot, l has been read]
        ,.
        >l
        [-<->]
        +<
        [
          >-<[-][in input spot, not l]
        ]
        >
        [
          -
          <
          [in input spot, l has been read]
          ,.
          >o
          [-<->]
          +<
          [
            >-<[-][in input spot, not o]
          ]
          >
          [
            -
            <
            [in input spot, o has been read]
            <->>
          ]
        ]
      ]
    ]
  ]
  <<
]
jvluso
quelle
Das sieht lustig aus :)
Willkommen bei Programming Puzzles und Code Golf StackExchange!
Betseg
1
Dieser Code hat mehrere Probleme, aber das größte Problem ist, dass er keine Logik enthält, um Fälle wie ahehellobrichtig zu behandeln. In der Mitte eines möglichen Matches wird nur nach dem nächsten Buchstaben gesucht hellound es wird nicht nach einem hgesucht, der von vorne beginnen kann.
Mitch Schwartz
8

Bash , 73 68 66 Bytes

IFS=
[[ $1 != olleh ]]&&read -rN1 c&&echo -n $c&&exec $0 $c${1::4}

Nimmt ein Verzeichnis mit keinen oder nur versteckten Dateien an. Muss ausgeführt werden als <path/to/script>.

Probieren Sie es online!

Wie es funktioniert (veraltet)

Zu Beginn der while- Schleife prüfen wir zunächst, ob die Zeichenfolge in der Variablen s (anfangs leer) gleich olleh ( hallo rückwärts, olé) ​​ist, und geben dementsprechend 0 (Übereinstimmung) oder 1 (keine Übereinstimmung) zurück. Das Ergebnis ist zwar formal Teil der Schleifenbedingung, wirkt sich jedoch nicht auf diese aus, da nur der letzte Befehl davor dobestimmt, ob die Bedingung erfüllt ist.

Als Nächstes setzen wir das interne Feldtrennzeichen auf die leere Zeichenfolge (sodass readLeerzeichen nicht -runterdrückt werden ), lesen unformatierte Bytes ( ) aus STDIN und speichern sie in c. $?ist der Exit-Code des vorherigen Befehls, der genau ein ( -N1) Byte für eine Nichtübereinstimmung und null Byte ( -N0) liest . Das Lesen von Null-Bytes, unabhängig davon, ob es auf EOF zurückzuführen ist oder -N0angegeben wurde, führt readzum Beenden mit Statuscode 1 , sodass die while-Schleife endet. Ansonsten wird der Körper ausgeführt und wir fangen von vorne an.

Im Body drucken wir zuerst das gelesene Byte und aktualisieren dann s mit s=$c${s::4}. Dies stellt das gelesene Byte (bis zu) den ersten vier Bytes in s voran , so dass s gleich olleh ist, sobald hallo gedruckt wurde.

Dennis
quelle
Tatsächlich sehr nett!
8

Brainfuck, 117 Bytes

--->>>------>>>+>>>+>>>++++<,[.-----<-[>--<-----]<[<<<]>>>[<[<<<+>>>>->+<<-]>[>>
+>]<[+[-<<<]]>>[<+>-]>>]<[[-]<<<,<]>]

Formatiert:

--->>>------>>>+>>>+>>>++++
<,
[
  .-----<-[>--<-----]<[<<<]
  >>>
  [
    <[<<<+>>> >->+<<-]
    >[>>+>]
    <[+[-<<<]]
    >>[<+>-]
    >>
  ]
  <[[-]<<<,<]
  >
]

Probieren Sie es online aus .

Dies initialisiert das Band mit den Charakteren in helloOffset durch 107, wobei ein Wert alle drei Zellen heraus gesperrt, hält dann in den letzten fünf Zeichen verfolgen gesehen und sucht nach einer Übereinstimmung mit jedem neuen Charakter verarbeitet, eine Flagge auf der rechten Seite der Zeichenfolge mit zu Verfolgen Sie, ob es eine Übereinstimmung gegeben hat.

Mitch Schwartz
quelle
7

Ruby , 46 60 Bytes

a="";loop{q=$<.getc;~p if a[-5..-1]=="hello"||!q;a+=q;$><<q}

Probieren Sie es online!

Liest Zeichen von stdin bis zu den letzten 5 und gibt hellodann die Zeichenkette aus (oder bis keine Zeichen mehr in stdin sind). Beendet mit Fehler.

Gleichwertig:

a = ""
loop {
    q = $<.getc
    ~p if a[-5..-1] == "hello" || !q
    a += q
    $><< q
}

Oder mehr ungolfed:

a = ""
loop do
    q = STDIN.getc
    break if a[-5..-1] == "hello" or not q
    a += q
    print q
end
Conor O'Brien
quelle
1
awächst jedes Mal, wenn ein Zeichen gelesen wird. Stürzt das ab, wenn die Eingabe unendlich ist?
Betseg
@ Betseg hm, vielleicht. Lassen Sie mich sehen, ob ich das beheben kann
Conor O'Brien
7

Python 3, 120 116 104 Bytes

Funktioniert mit unendlichen Bächen, das erste Mal Golfen, alle Tipps sind willkommen.

import sys
a=1
c=''
while(a):
    a=sys.stdin.read(1)
    if a:print(end=a)
    c=(c+a)[-5:]
    if c=='hello':break

Danke @DJMcMayhem für das Speichern einiger Bytes :)

R. Martin
quelle
Willkommen auf der Seite! c=[0,c+1]['hello'[c]==a]sollten Sie einige Bytes sparen. Auch a=1ist auch kürzer.
DJMcMayhem
2
whileIn Python wird die Klammer nicht benötigt .
PurkkaKoodari
6

Haskell, 41 47 43 Bytes

f l|w@"hello"<-take 5l=w|a:b<-l=a:f b|1<2=l

Haskells Faulheit bewältigt die unendlichen Ein- und Ausgänge gut.

Probieren Sie es online!

Bearbeiten: Endliche Eingabe nicht verarbeitet - behoben. Vielen Dank an @Leo für den Hinweis.

Edit II: @ Ørjan Johansen hat 4 Bytes gespeichert. Vielen Dank!

nimi
quelle
2
Die Eingabe kann auch endlich sein, daher denke ich, dass Sie sich mit dem Fall befassen müssen, wenn Sie das Ende der Zeichenfolge erreichen
Leo,
@Leo: Hoppla, ich habe es total verpasst. Fest.
Nimi
2
Die erste Wache kann auf gekürzt werden |w@"hello"<-take 5l=w.
Ørjan Johansen
@ ØrjanJohansen: oh, das ist schön. Vielen Dank!
Nimi
6

Cubix, 94 83 82 79 63 56 Bytes

p>q'-?w.uh'e@U7.'hqi?oqB-!ul.-..$WWu_q<o'\;>....6t?.../!@

Erweitert:

        p > q '
        - ? w .
        u h ' e
        @ U 7 .
' h q i ? o q B - ! u l . - . .
$ W W u _ q < o ' \ ; > . . . .
6 t ? . . . / ! @ . . . . . . .
. . . . . . . . . . . . . . . .
        . . . .
        . . . .
        . . . .
        . . . .

Anmerkungen

  • Der Interpreter deaktiviert das Eingabefeld beim Programmstart. Als solches ist ein unendlicher Strom von Eingaben unmöglich. Dieses Programm nimmt die Eingabe zeichenweise vor. Ohne diese Einschränkung würde es also ordnungsgemäß funktionieren.
  • Dieses Programm räumt den Stapel nicht auf und es wird sehr schnell chaotisch. Da die Maschine, auf der dies verwendet wird, anscheinend unendliche Eingabeströme liefern kann, scheint es vernünftig anzunehmen, dass sie auch unendlichen Speicher hat.
  • Jegliche Golfhilfe wird sehr geschätzt.

Probieren Sie es online aus

Sie können das Programm hier ausprobieren .

Erläuterung

Grund Idee

Die allgemeine Idee ist, dass wir ein Zeichen lesen und es dann mit unterschiedlichen Zeichen vergleichen möchten (zuerst h, dann e, lusw.). Um den Überblick über den vermissten Charakter zu behalten, halten wir ihn ganz unten im Stapel. Wenn wir es brauchen, können wir es leicht wieder nach oben bringen.

Lese- / Schreibschleife

Die Schreib-Lese-Schleife ist einfach die 5 th Linie. Alle nicht verwendeten Zeichen werden durch no-ops ( .) ersetzt:

        . . . .
        . . . .
        . . . .
        @ . . .
' h q i ? o q B - ! u l . - . .
. . . . _ . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
        . . . .
        . . . .
        . . . .
        . . . .

Dies kann in zwei Teile unterteilt werden: Lesen und (Schreiben und Prüfen). Der erste Teil enthält die Anweisungen bis einschließlich des Fragezeichens. Der zweite Teil ist der Rest der Linie. Da dies eine Schleife darstellt, gehen wir davon aus, dass wir mit einem Stapel von beginnen[...]

    @
'hqi?
    _

Explanation
'h          Push the character code of the h
            Stack: [..., 104]
  q         Send it to the bottom
            Stack: [104, ...]
   i        Read one character of the input (-1 for EOF)
            Stack: [104, ..., input]
    ?       Start of condition:
              if (input < 0):
    @           execute '@', ending the program
              if (input = 0):
                continue going right
              if (input > 0):
    _           turn to the right, reflect back ('_') and
                turn right again, effectively not changing 
                the direction at all

Der zweite Teil (Schreiben und Prüfen) ist wieder linear. Der Stapel beginnt als [next-char, ..., input]. Wir haben das nächste Zeichen abstrahiert, weil sich das später im Programm ändert.

oqB-!ul.-  Explanation
o          Output the character at the top of the stack
 q         Send the input to the bottom of the stack
           Stack: [input, next-char, ...]
  B        Reverse the stack
           Stack: [..., next-char, input]
   -       Push the difference of the top two characters, which
           is 0 if both are equal, something else otherwise
           Stack: [..., next-char, input, diff]
    !      if (diff = 0):
     u       make a u-turn to the right
           else:
      l.     execute two no-ops
        -    push [input - next-char - input], which is disregarded
             later, so it effectively is a no-op as well.

Jetzt beginnt die IP wieder am Anfang dieser Schleife und setzt das nächste zu überprüfende Zeichen zurück h.

Matching das nächste Zeichen

Wenn die IP eine Kehrtwende gemacht hat (dh das gelesene und gedruckte Zeichen stimmt mit dem nächsten Zeichen überein 'hello'), müssen wir überprüfen, welches Zeichen die Eingabe war, und in Abhängigkeit davon das nächste Zeichen zum Ende des Stapels schieben. Danach müssen wir in die Lese- / Schreibschleife zurückkehren, ohne hzum Stapel zu wechseln, also brauchen wir einen anderen Weg, um dorthin zu gelangen.

Das Wichtigste zuerst: Bestimmen Sie, welches Zeichen die Eingabe war. Der Stapel sieht wie folgt aus : [..., prev-char, input, 0].

        . . . .
        - ? . .
        u h ' e
        . . . .
. . . . . . . . . ! u . . . . .
. . . . . . . . . \ ; . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
        . . . .
        . . . .
        . . . .
        . . . .

Um die Eingabe zu vergleichen, verwenden wir wieder den Zeichencode von h. Das lag anfangs daran, dass ich nicht genau wusste, wie ich damit umgehen sollte, und hes war das erste Zeichen in der Zeichenfolge, nach dem gesucht werden musste, aber es erwies sich als recht praktisch. Wenn wir den Zeichencode von h von der Eingabe subtrahieren, erhalten wir, -3ob die Eingabe ist e, 0ob die Eingabe ist h, 4ob die Eingabe ist lund 7ob die Eingabe ist o.

Dies ist nützlich, da mit dem ?Befehl negative Werte leicht von positiven Werten und Null getrennt werden können. Wenn sich die IP nach links dreht, war die Differenz negativ, die Eingabe ealso, und das nächste Zeichen sollte ein sein l. Wenn die IP weiter geradeaus geht, war der Unterschied 0, also war die Eingabe h, also sollte das nächste Zeichen ein sein e. Wenn der Eingang ein loder ein ist o, wird die IP nach rechts gedreht.

Alle Anweisungen, die vor dem oben genannten Fragezeichen ausgeführt werden, sind:

;!e'h-     Explanation
;          Delete the top of the stack
           Stack: [..., prev-char, input]
 !         if (input = 0):
  e          execute 'e' (no-op)
   'h      Push the character code of h
           Stack: [..., prev-char, input, 104]
     -     Push the difference of the input and 104
           Stack: [..., prev-char, input, 104, diff]

Jetzt ändert die IP ihre Richtung wie oben beschrieben. Gehen wir die verschiedenen Möglichkeiten durch.

Eingang 'e'

Zuerst betrachten wir die Eingabe e, die bewirkt, dass sich die IP von der nach oben bewegt ?, da der Unterschied 3 beträgt. Alle irrelevanten Zeichen wurden aus dem Cube entfernt.

        . > q '
        . ? . .
        . . . .
        . . . .
. . q . . . . . . . . l . . . .
$ W W . . . . . . . . > . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
        . . . .
        . . . .
        . . . .
        . . . .

Die Zeichen werden in dieser Reihenfolge ausgeführt (mit Ausnahme einiger Kontrollflusszeichen):

q'l$WWq
q           Save the difference (-3) to the bottom of the stack so
            we can tell whether the l on the bottom of the stack is
            the first or the second l in hello
            Stack: [-3, ...]
 'l         Push the character code of l to the stack
            Stack: [-3, ..., 108]
   $W       no-op
     W      Sidestep into the loop
      q     Send the character code to the bottom
            Stack: [108, -3, ...]

Jetzt hat die IP die Lese- / Schreibschleife wieder erreicht.

Eingang 'h'

Wenn die Eingabe war 'h', ist die Differenz 0, sodass die IP ihre Richtung nicht ändert. Hier ist noch einmal der Würfel, bei dem alle irrelevanten Zeichen entfernt sind. Da dieser Pfad einige No-Ops enthält, wurden alle übergebenen No-Ops durch ersetzt &. Die IP beginnt am Fragezeichen.

        . . . .
        . ? w .
        . . ' e
        . . . .
. . . . . . . . . ! . . . . . .
. . . u _ q < . . \ . . . . . .
. . ? & & & / . . & . . . . . .
. . & . . . . . . & . . . . . .
        . . . .
        & & & &
        . . . .
        . . . .

Die ausgeführten Anweisungen sind:

'e!\?q_
'e          Push the character code of the e
            Stack: [..., 101]
  !         if (101 = 0):
   \          reflect away (effectively a no-op)
    ?       if (101 > 0):
              turn right (always happens)
     q      Move 101 to the bottom of the stack
            Stack: [101, ...]
      _     No-op

Und jetzt treten wir wieder in die Lese- / Schreibschleife ein, also sind wir fertig.

Andere Eingänge

Alle anderen Eingaben führen zu einer positiven Differenz, sodass die IP am Fragezeichen nach rechts wechselt. Wir müssen immer noch das lund das trennen o, also werden wir das als nächstes tun.

Trennen der 'l'und'o'

Denken Sie daran, dass der Unterschied 7 für ound 4 für ist lund dass wir das Programm beenden müssen, wenn die Eingabe eine war o. Hier ist noch einmal der Würfel, wobei die irrelevanten Teile durch a .und die No-Ops durch Et-Zeichen ersetzt wurden.

        . . q .
        . ? w .
        . h ' .
        . U 7 .
. . . . . . . . . . . . . - . .
. . . . . . . . . . . . . & . .
. . . . . . / ! @ . . . . & . .
. . . . . . & . . . . . . & . .
        . . & .
        . . & .
        . . & .
        . . & .

h7'wq-!@    
h           no-op
 7          Push 7 to the stack
            Stack: [..., diff, 7]
  'wq       Push w to the stack and send it to
            the bottom. We don't care about it,
            so it's now part of the ellipsis.
            Stack: [..., diff, 7]
     -!     if (diff = 7):
       @        End the program

Unterscheidung zwischen den beiden 'l's

Jetzt wissen wir also, dass es sich um eine Eingabe handelte l, aber wir wissen nicht, welche l. Wenn es der erste ist, müssen wir einen anderen lauf den Boden des Stapels schieben , aber wenn es der zweite ist, müssen wir einen schieben o. Erinnerst du dich, dass wir -3am Ende des Stapels gespeichert haben , kurz bevor wir den ersten gepusht haben l? Damit können wir die beiden Zweige trennen.

        . . . .
        . . . .
        . . . .
        . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
6 t ? . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
        . . . .
        . . . . 
        . . . .
        . . . .

Der Stapel beginnt als [..., -3 or 140, ...]

Explanation
6t?         
6t          Take the 6th item from the top and move
            it to the top (which is either -3 or 140)
  ?         If that's positive, turn right, otherwise,
            turn left

Zuerst 'l'

Wenn dies der erste war 'l', müssen wir einen anderen drängen 'l'. Um Bytes zu sparen, verwenden wir dieselben Zeichen wie für das erste 'l'. Wir können den Stack zu vereinfachen [...]. Hier ist der relevante Teil des Cubes, bei dem No-Ops durch kaufmännisches Und ersetzt werden.

        p > q '
        . . . .
        . . . .
        . . . .
' . q . . . . . . . . l . . . .
$ W W . . . . . . . . > & & & &
. . ? . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
        . . . .
        . . . .
        . . . .
        . . . .

Die folgenden Anweisungen werden ausgeführt:

$'pq'lq
$'          no-op
  pq        no-op
    'l      Push the character code of l
            Stack: [..., 108]
      q     Send it to the bottom
            Stack: [108, ...]

Wir treten in die Lese- / Schreibschleife ein, also sind wir mit diesem Zweig fertig.

Zweite 'l'

Wenn die Eingabe der zweite war 'l'in 'hello'wandte sich die IP - Recht auf das Fragezeichen. Wieder einmal können wir den Stack vereinfachen [...]und die IP beginnt bei ?und zeigt diesmal nach Süden.

        . . . .
        . . . .
        . . . .
        . . . .
. . . . . . . . . . . . . . . .
. . . u _ q < o ' \ . . . . . .
. . ? . . . . . . & . . . . . .
. . & . . . . . . & . . . . . .
        . . . .
        & & & &
        . . . .
        . . . .

Die ausgeführten Anweisungen sind:

'oq_
'o          Push the character code of 'o'
            Stack: [..., 111]
  q         Move the top item to the bottom
            Stack: [111, ...]
   _        No-op

Und die IP tritt gleich wieder in die Lese- / Schreibschleife ein, sodass wir auch mit diesem Zweig fertig sind.

Luke
quelle
Eine heldenhafte Anstrengung!
5

C ++, 142 141 Bytes

#import<iostream>
void f(std::istream&i){i>>std::noskipws;char c;for(std::string s="     ";s!="hello"&&i>>c;)s.erase(0,1),s+=c,std::cout<<c;}

Probieren Sie es online!

Steadybox
quelle
Wäre das mit GCC möglich? Ich sehe es nicht #importin GCC C ++ Programmen ...
ckjbgames
1
@ckjbgames #importist eine veraltete GCC-Erweiterung.
Steadybox
1
@ckjbgames mehr Infos hier: stackoverflow.com/questions/172262/…
iFreilicht
@iFreilicht Diese Frage hat mich eigentlich dazu gebracht, das zu fragen.
ckjbgames
1
@ckjbgames Vielleicht möchten Sie einen Blick auf die zweite Antwort werfen : stackoverflow.com/a/172264/2533467 "Der Import in gcc unterscheidet sich vom Import in VC ++. Es ist eine einfache Möglichkeit, einen Header höchstens einmal einzuschließen . "
iFreilicht
3

Knoten, 124 Bytes

with(process)with(stdin)on('data',d=>[...d].map(c=>(s=(stdout.write(c),s+c).slice(-5))=='hello'&&exit()),setEncoding(),s='')

Ich gehe nicht davon aus, dass der Stream in den verfügbaren Speicher passt.

Neil
quelle
3

C #, 134 Bytes

using C=System.Console;class P{static void Main(){var s="";for(int c;(c=C.Read())>=0&!s.Contains("olleh");C.Write(s[0]))s=(char)c+s;}}

Probieren Sie es online

Liest ein Zeichen, überprüft, dass es nicht -1 (EOS) ist und dass wir "Hallo" noch nicht gesehen haben, stellt es dann einem String voran und schreibt das Zeichen aus. Wir stellen voran, weil s[0]es viel kürzer ist als (char)s. Dies hat quadratische Kosten in der Länge des Strings zur Folge, da jedes Mal, wenn ein Zeichen gelesen wird, die gesamte Eingabe zugewiesen und durchsucht werden muss.

using C=System.Console;

class P
{
    static void Main()
    {
        var s="";
        for(int c;(c=C.Read())>=0&!s.Contains("olleh");C.Write(s[0]))
            s=(char)c+s;
    }
}

Informationen zu einer (längeren: 142 Byte) Version, die nicht über genügend Speicher verfügt und konstante Kosten pro Zeichen aufweist, finden Sie unten:

using C=System.Console;class P{static void Main(){var s="     ";for(int c;(c=C.Read())>=0&s!="hello";C.Write(s[4]))s=s.Substring(1)+(char)c;}}

Dieser hält die letzten 5 Zeichen in einer Zeichenfolge von 5 Längen, was kurze Vergleiche und eine billige Suche nach dem letzten Zeichen bedeutet, aber die Aktualisierung ist erheblich teurer.

using C=System.Console;

class P
{
    static void Main()
    {
        var s="     ";
        for(int c;(c=C.Read())>=0&s!="hello";C.Write(s[4]))
            s=s.Substring(1)+(char)c;
    }
}
VisualMelon
quelle
3

PHP, 57 55 53 Bytes

while(hello!=$s=substr($s.$c,-5))echo$c=fgetc(STDIN);

Da es keine unendlichen Dateien gibt, nehme ich Eingaben von STDIN entgegen. Laufen Sie mit -nr.

Durchlaufen Sie die Eingabe, drucken Sie das aktuelle Zeichen, hängen Sie es an $sund schneiden Sie $sdie letzten 5 Zeichen ab. Schleife unterbrechen, wenn $sist hello.

Titus
quelle
3

Vim, 39 Bytes

:im hello hello:se noma
:map : i

i

Probieren Sie es online!

:im hello                        "Remap 'hello' in insert mode to
          hello                "write hello, then hit escape
                 :se noma       "then set the buffer to not-modifiable
:map : i                        "THEN remap ':' to 'i' so that can't be changed

i                                "enter insert mode and await an infinite stream of input
nmjcman101
quelle
Ist dies eine akzeptierte Eingabemethode für Vim? Ich dachte, Vim-Programme erwarten normalerweise, dass sich die Eingabe bereits im Puffer befindet, bevor sie gestartet werden.
Martin Ender
Um ehrlich zu sein weiß ich nicht Das stimmt, lässt aber kaum einen unendlichen Strom zu, also habe ich es einfach so gemacht, ohne wirklich darüber nachzudenken.
nmjcman101
Was passiert, wenn der Eingabestream ein Escapezeichen enthält?
Dim
@dim fragte ich, und OP spezifizierte nur druckbares ASCII und Zeilenumbrüche. ESC ist im druckbaren ASCII-Format afaik
nmjcman101 am
3

PowerShell, 111 Byte

Es gibt wahrscheinlich einen besseren Weg, dies zu tun, aber ich kann es im Moment nicht sehen.

while(($x=($x+$host.UI.RawUI.ReadKey("IncludeKeyDown").character+"     ").substring(1,5)).CompareTo("hello")){}

Dies liest die Tastenanschläge, ohne das Echo zu unterdrücken. Das Zeichen wird zu $ ​​x hinzugefügt, das auf die letzten 5 Zeichen gekürzt und mit "Hallo" verglichen wird. Dies geht so lange weiter, bis der Vergleich wahr ist.

Hinweis: Dies funktioniert in PowerShell ISE nicht. ReadKey ist in dieser Umgebung deaktiviert.

MickyT
quelle
3

Schema 115 Bytes

(do((c(read-char)(read-char))(i 0(if(eqv? c(string-ref"hello"i))(+ i 1)0)))((or(eof-object? c)(= i 5)))(display c))

Lesbare Version:

(do ((c (read-char) (read-char))                            ; read stdin
     (i 0 (if (eqv? c (string-ref "hello" i)) (+ i 1) 0)))  ; check target
    ((or (eof-object? c) (= i 5))) ; finish if end of stdin, or word found
  (display c))                     ; display each character

Dies nimmt jedes Mal ein einzelnes Zeichen von stdin in der Schleife und markiert seine Position auf dem Zielwort, wenn es auf die Zeichen von "hallo" trifft.

Stoppt, wenn die Eingabe erschöpft ist oder "Hallo" gesehen wurde. Kein Speicher für unendlichen Stream.

Peter
quelle
Coole Antwort, willkommen auf der Seite!
DJMcMayhem
3

AWK, 95 Bytes

BEGIN{RS="(.)"
split("hello",h,"")}{for(j=0;++j<6;){c=RT
printf c
if(c!=h[j])next
getline}exit}

Es gibt 2 Dinge , die ich hier gelernt:
1) Datensätze aufgeteilt zwischen den Zeichen verwenden RS="(.)"und dann RTmuss statt verwendet wird $1
2) ORSverwendet wird , durch printund ist voreingestellt auf "\n"
3) I nicht auf 2 zählen kann und die Verwendung printfist „billiger“ als die Zuordnung ORSund mitprint

Anwendungsbeispiel: Code in DATEI einfügen

awk -f FILE some_data_file

oder

some process | awk -f FILE

Code wurde mit Dennis ' yes | ...Vorschlag getestet und ich sah viele, viele ys.

Zu Ihrer Information, Sie können die RS-Zuweisung optional durchführen und sie aus dem BEGINBlock herausziehen über:

awk -v RS='(.)'
Robert Benson
quelle
Wirklich knifflige Lösung! (Vielleicht , weil es Freitag Nachmittag, aber ich es gut Eintrag für verschleierte Herausforderung finden.) Obwohl ich einen awkish Ansatz versuchen würde: BEGIN{RS="(.)"}{printf RT}"olleh"==a=RT substr(a,1,4){exit}.
Manatwork
Seltsamerweise habe ich vor einer Stunde fast genau geantwortet ... und vergessen, es einzureichen. : p
Robert Benson
3

Python 3 (Linux), 73 - 72 Byte

s=c='_';I=open(0)
while'olleh'!=s>''<c:c=I.read(1);s=c+s[print(end=c):4]

Vielen Dank an @MitchSchwartz für das Golfen ab 1 Byte!

Probieren Sie es online!

Dennis
quelle
Ich verstehe nicht Wie wird die Bedingung für whilerichtig bewertet? Es sieht so aus, als würden Sie einen Booleschen Wert mit einem leeren String vergleichen.
iFreilicht
1
s[print(end=c):4]speichert ein Byte
Mitch Schwartz
1
@iFreilicht Python analysiert verkettete Bedingungen wie in Mathematik ( zum Beispiel a <b <c ). Die Bedingung ist eine Abkürzung für 'olleh'!=s and s>''and''<c). Der mittlere Test wird nicht benötigt, aber das Verketten ist kürzer als der einfache 'olleh'!=s and''<c.
Dennis
@MitchSchwartz Das tut es. Vielen Dank!
Dennis
3

8086 Maschinencode, 22 Bytes

00000000  bf 11 01 b4 01 cd 21 ae  75 f6 81 ff 16 01 72 f3  |......!.u.....r.|
00000010  c3 68 65 6c 6c 6f                                 |.hello|
00000016

Äquivalenter Montagecode:

org 0x100
use16
a:  mov di, msg
b:  mov ah, 1       ; read one byte from stdin with echo
    int 0x21        ; dos syscall -> result in AL
    scasb           ; if (DI++ == AL)
    jne a
    cmp di, msg+5
    jb b
    ret
msg db "hello"
user5434231
quelle
Wie funktioniert es?
1
Ich habe den entsprechenden Assembler-Code hinzugefügt. Es basiert im Grunde genommen auf einem sehr nützlichen DOS-Systemaufruf, der ein Byte von stdin liest und es gleichzeitig auf stdout zurücksendet. Der 8086 verfügt auch über eine Single-Byte-String-Vergleichsanweisung, die sich hier als nützlich erweist.
user5434231
2

Pyth, 49 47 Bytes

Wn"hello"=>5+kp$__import__("sys").stdin.read(1)

Pyth ist nicht sehr gut darin, einen einzelnen Buchstaben einer Eingabe zu nehmen. Alles in$__import__("sys").stdin.read(1) macht das einfach. Dies bedeutet auch, dass dies nur offline ausgeführt wird.

Alles andere ist kurz ...

Das Programm ist eine körperlose while-Schleife. Innerhalb der Bedingung liest das Programm ein Zeichen, druckt es zurück, fügt dieses Zeichen an k(das anfangs die leere Zeichenfolge ist) , schneidet alle Zeichen bis auf die letzten 5 ab kund prüft dann, ob das Ergebnis nicht stimmt "hello".

32 Zeichen erhalten ein Byte, den Rest erledigen 15 Zeichen.

Getestet unter Linux, funktioniert auch ohne Zeilenvorschub, unendliche Eingabe usw.

isaacg
quelle
2

Lua, 68 64 Bytes

l=""while l~="hello"do c=io.read(1)io.write(c)l=l:sub(-4)..c end
Ausplaudern
quelle
1
Ändern Sie das Slicing in l:sub(-4), dann können Sie die Initialisierung von reduzieren l="".
Manatwork
@manatwork Das ist ordentlich. Danke für den Tipp.
Blab
2

Ruby, 59 49 48 43 Bytes

Jetzt rastlos, kürzer und ohne Speicherverlust.

s=''
s=$>.putc$<.getc+s[0,4]until'olleh'==s

5 Bytes gespart, indem dank Dennis einige Klammern und ein Leerzeichen entfernt wurden

daniero
quelle
Lassen Sie uns diese Diskussion im Chat fortsetzen .
Daniero
1

Röda , 49 47 Bytes

{a=[0]*5{|x|[x];a=a[1:]+x;z if[a&""="hello"]}_}

Probieren Sie es online!

Dies ist eine anonyme Funktion, die Zeichen aus ihrem Eingabestream liest und ausgibt, bis "Hallo" gefunden wird. Es verwendet das Arraya , um die letzten Zeichen zu verfolgen.

Es gibt etwas Müll an STDERR aus, aber ich habe verstanden, dass das erlaubt ist .

Erläuterung:

{
    a=[0]*5                /* Initialize the array with 5 zeroes. */
    {|x|                   /* For each x in the input stream: */
        [x];               /* Print x */
        a=a[1:]+x;         /* Add x and remove the sixth last character. */
        z if[a&""="hello"] /* If "hello" is found, crash the program */
                           /* with an undefined variable. */
    }_                     /* End for loop. */
}
fergusq
quelle
Wo ist die Roda-Dokumentation?
ckjbgames
@ckjbgames Hier. Ich verwende die neueste Version 0.12, die sich in einer eigenen Filiale in Github befindet.
Fergusq
1

Java 7, 122 118 124 123 150 141 Bytes

void c()throws Exception{String a="aaaaa";for(int b;!a.equals("hello")&(b=System.in.read())>=0;a=a.substring(1)+(char)b)System.out.write(b);}

Jetzt hört auf, wenn das Ende des Streams erreicht ist. Verarbeitet jetzt unendliche Eingaben, ohne dass der Arbeitsspeicher knapp wird.

Sack
quelle
Ich wette, das kann nicht mit unendlichen Eingaben umgehen.
Titus
@ Titus behoben ...
Poke
Ich habe downvoted, ohne zu sehen, writedass stattdessen verwendet wird print. Ich kann meine Ablehnung nicht rückgängig machen, sorry dafür :(
Olivier Grégoire
1

Ruby, 51 Bytes

x="";$><<x[-1]while/hello./!~x=x[/.{0,5}$/]+$<.getc
  • Erwartet keine Zeilenumbrüche
  • Arbeitet mit unendlichen Eingaben
GB
quelle
1

AHK , 116 Bytes

Loop,Read,%1%
{a=%A_LoopReadLine%`n
Loop,Parse,a
{Send % c:=A_LoopField
If((f:=c SubStr(f,1,4))=="olleh")
ExitApp
}}

Da drin ist nichts Schlaues oder Magisches. Die Variable %1%ist das erste übergebene Argument und sollte ein Dateipfad mit dem Stream sein. Die Datei muss beim Aktualisieren gespeichert werden, der Code wird jedoch bis zum Ende gelesen, auch wenn er nach dem Beginn des Lesens erweitert wird.

Ingenieur Toast
quelle
1

Mathematica, 107 Bytes

i="";EventHandler[Dynamic@i,"KeyDown":>(i=i<>CurrentValue@"EventKey";If[StringTake[i,-5]=="hello",Exit[]])]

Die Ausgabe wird zu einem Feld, in das der Benutzer unbegrenzt Text (einschließlich Zeilenumbrüche) eingeben kann, bis die letzten 5 Zeichen gleich sind "hello". An diesem Punkt wird es beendet.

numbermaniac
quelle
1

Brainfuck , 281 Bytes

>++++++++[<+++++++++++++>-]>++++++++++[<++++++++++>-]<+>>+++++++++[<++++++++++++>-]>++++++++++[<+++++++++++>-]<+>+[[[[[,.<<<<[->>>>->+<<<<<]>>>>>[-<<<<<+>>>>>]<],.<<<[->>>->+<<<<]>>>>[-<<<<+>>>>]<],.<<[->>->+<<<]>>>[-<<<+>>>]<],.<<[->>->+<<<]>>>[-<<<+>>>]<],.<[->->+<<]>>[-<<+>>]<]

Ich bin mir nicht sicher warum, aber ich hatte einfach das Gefühl, dass Brainfuck das Richtige ist, um dies zu tun. Benötigt keinen unendlichen Speicher und kann für immer ausgegeben werden.

Erklärt

Set up the buffers with helo
This is done Naively; sue me
>++++++++[<+++++++++++++>-]     h
>++++++++++[<++++++++++>-]<+>   e
>+++++++++[<++++++++++++>-]     l
>++++++++++[<+++++++++++>-]<+>  o

THE MAIN LOOP
+
[ matches o
    [ matches l
        [ matches l
            [ matches e
                [ matches h
                    ,. Read a character and immediently write it
                    <<<<[->>>>->+<<<<<] Subtract it from h
                    >>>>>[-<<<<<+>>>>>] Correct the h
                    < Terminate this part of the loop if it matches h
                ]
                ,. Same as above
                <<<[->>>->+<<<<] Subtract it from e
                >>>>[-<<<<+>>>>] Correct the e
                < Terminate this part of the loop if it matches e
            ]
            ,. Same as above
            <<[->>->+<<<] Subtract it from l
            >>>[-<<<+>>>] Correct the l
            < Terminate this part of the loop if it matches l
        ]
        ,. Same as above
        <<[->>->+<<<] Subtract it from l
        >>>[-<<<+>>>] Correct the l
        < Terminate this part of the loop if it matches l
    ]
    ,. Same as above
    <[->->+<<] Subtract it from o
    >>[-<<+>>] Correct the o
    < Terminate this part of the loop if it matches o
]

Probieren Sie es online!

Ein Taco
quelle
Ich wollte es so machen, aber dann wurde mir klar, dass dies das Null-Byte unendlich für Eingaben ausgibt, die kein "Hallo" enthalten: tio.run/nexus/…
KarlKastor
Dies scheitert auch an ahehellob.
Mitch Schwartz