Bạn đã chào tôi


30

Bài tập

Đọc trong một luồng văn bản hoặc tệp có thể vô hạn, xuất nội dung của nó cho đến khi từ hellođược xuất ra, tuân theo các quy tắc sau.

  • Khi hellođã được xuất, mã của bạn sẽ thoát ngay lập tức. Nó không nên chờ đợi một dòng mới chẳng hạn.

  • Mã của bạn sẽ xuất ra khi nó đi. Đó là nó không nên đọc trong một lượng lớn đầu vào và sau đó bắt đầu xuất ra.

  • Nếu luồng / tệp không chứa hello, mã của bạn sẽ tiếp tục xuất ra đầu vào mãi mãi hoặc cho đến khi kết thúc luồng / tệp.

  • Đây là một thách thức nhạy cảm trường hợp, vì vậy hellokhông bằng Hello.

  • Bạn có thể giả định rằng đầu vào chỉ bao gồm các ký tự ASCII có thể in và các dòng mới.

  • Mã của bạn không thể hy vọng rằng văn bản sẽ bị chấm dứt bởi một dòng mới hoặc sẽ có bất kỳ dòng mới nào trong đầu vào. Ngoài ra, mã của bạn không thể cho rằng nó sẽ chạy trên một máy có dung lượng bộ nhớ vô hạn.

  • Bạn có thể cho rằng mã của bạn sẽ được gọi từ một thư mục trống.

Ví dụ luồng đầu vào

I once had a horse called hellopina.

Đầu ra

I once had a horse called hello

tiền boa

Chạy yes | tr -d \\n | <your program>để kiểm tra nếu nó hoạt động với các luồng vô hạn. Nếu nó không in bất cứ thứ gì và / hoặc rò rỉ bộ nhớ, chương trình không tuân thủ thông số kỹ thuật. Nó sẽ in yyyyyyyyyyyyyyyyyyyyyy...mãi mãi mà không có dòng mới.


1
Chúng tôi có được phép đọc bất cứ điều gì sau "xin chào" không? Câu hỏi dường như cấm mọi đọc thêm, có thể có vấn đề trong các ngôn ngữ như (Tiêu chuẩn) C, cung cấp đầu vào được đệm với tính năng đọc trước tự động.
Toby Speight

Có lẽ bạn nên thay đổi câu trả lời được chấp nhận cho câu hỏi lắp ráp, vì nó ngắn hơn 2 byte.
Rɪᴋᴇʀ

@Riker Sẽ thật tuyệt nếu ai đó có thể kiểm tra nó hoặc ít nhất nói rằng họ tin rằng nó hoạt động trước.

Câu trả lời:


2

Thạch , 24 byte

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

Hãy thử trực tuyến!

Giải trình:

ṫ-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.

26

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

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

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

Đây là một chương trình đầy đủ. Chúng tôi xác định một chức năng f cho mục đích của chúng tôi. Để lưu byte, nó được khai báo với hai đối số mặc định là int . Đây là hành vi không xác định, nhưng trong thực tế, n sẽ được khởi tạo là 1 khi chạy chương trình mà không có đối số bổ sung, c sẽ giữ 32 bit thấp hơn của con trỏ tới vectơ đối số

Trong khi điều kiện

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

nắm giữ, chúng tôi sẽ thực hiện trong khi thân vòng lặp của:

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

Để hiểu đầy đủ tình trạng, trước tiên chúng ta phải kiểm tra cơ thể. Hiện tại, tất cả những gì chúng ta quan sát là c=getchar()đọc một byte đơn từ STDIN (nếu có thể) và lưu trữ nó trong biến c .

Chuỗi byte xin chào trông như sau trong các biểu diễn khác nhau.

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

Tất cả các giá trị này nằm trong phạm vi [96, 192) , do đó c/96sẽ ước tính là 1 cho mỗi byte này và 0 cho tất cả các ký tự ASCII còn lại. Bằng cách này, putchar(c)/96*c( putchar in và trả về đối số của nó) sẽ đánh giá cho c nếu c`, một chữ cái viết thường, một trong {|}~hoặc ký tự DEL; đối với tất cả các ký tự ASCII khác, nó sẽ ước tính thành 0 .

n được cập nhật bằng cách dịch chuyển năm bit sang trái, sau đó XOR kết quả với kết quả từ đoạn trước. Vì một int rộng 32 bit (hoặc vì vậy chúng tôi giả sử trong câu trả lời này), một số bit bị dịch chuyển có thể "rơi ra bên trái" (tràn số nguyên đã ký là hành vi không xác định, nhưng gcc hoạt động như lệnh x64 mà nó tạo ra ở đây). Bắt đầu với một giá trị không xác định là n , sau khi cập nhật nó cho tất cả các ký tự của lời chào , chúng tôi nhận được kết quả như sau.

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

Lưu ý rằng 25 bit thấp hơn tạo thành số nguyên 0xb33def , là hằng số ma thuật trong điều kiện. Mặc dù có một số trùng lặp giữa các bit của hai byte liền kề, ánh xạ byte dưới 96 đến 0 đảm bảo rằng không có bất kỳ dương tính giả nào.

Điều kiện bao gồm hai phần:

  • ~(getchar()) lấy bit bit KHÔNG phải là kết quả của việc đọc (hoặc cố đọc) một byte từ STDIN.

    Nếu getchar thành công, nó sẽ trả về giá trị của byte đọc dưới dạng int . Do đầu vào bao gồm toàn bộ các ký tự ASCII, byte đọc chỉ có thể được đặt 7 bit thấp hơn, do đó, bitwise KHÔNG sẽ có 25 bit cao nhất được đặt trong trường hợp này.

    Nếu getchar thất bại (không có thêm đầu vào), nó sẽ trả về -1 và bitwise KHÔNG sẽ là 0 .

  • n-0xb33def<<7trừ hằng số ma thuật từ trước từ n , sau đó dịch 7 kết quả sang trái.

    Nếu 5 byte đọc cuối cùng là hello , 25 bit thấp nhất của n sẽ bằng 0xb33def và phép trừ sẽ loại bỏ chúng. Thay đổi chênh lệch sẽ mang lại 0 vì 7 bit cao nhất sẽ "rơi ra bên trái".

    Mặt khác, nếu 5 byte đọc cuối cùng không được chào , một trong 25 bit thấp nhất của chênh lệch sẽ được đặt; sau khi dịch chuyển, một trong 25 bit cao nhất sẽ là.

Cuối cùng, nếu getchar thành công và chúng tôi chưa in xin chào , bit AND, tất cả 25 bit cao nhất của toán hạng bên trái và ít nhất một trong 25 bit cao nhất của bên phải sẽ được đặt. Bằng cách này, &sẽ mang lại một số nguyên khác không và vòng lặp tiếp tục.

Mặt khác, nếu đầu vào đã hết hoặc chúng tôi đã in xin chào , một trong các toán hạng của bitwise sẽ bằng 0 và kết quả cũng vậy. Trong trường hợp này, chúng tôi thoát ra khỏi vòng lặp và chương trình chấm dứt.


Có lẽ bạn nên đề cập rằng điều này phụ thuộc vào đầu vào được mã hóa trong ASCII, trước khi đi sâu vào giải thích.
Toby Speight

2
@TobySpeight Tôi không nghĩ nó phổ biến để chỉ định điều này. Loại mã hóa không tương thích ASCII nào mà bạn mong đợi câu trả lời C sẽ sử dụng?
Dennis

EBCDIC là mã hóa rõ ràng không phải là ASCII. C không quy định bất kỳ mã hóa ký tự cụ thể nào (chỉ có các chữ số thập phân phải được biểu thị bằng các giá trị liên tiếp, theo thứ tự).
Toby Speight

chương trình trên dừng lại nếu luồng chứa chuỗi không ascii "« úá ÷ o "1: o 111 6f 2: ÷ 246 f6 3: á 160 a0 4: ú 163 5:« 174
RosLuP

@RosLuP Thông số kỹ thuật thách thức đảm bảo rằng đầu vào sẽ bao gồm các ký tự ASCII có thể in và các dòng mới.
Dennis

19

Bash, 74 75 103 99 88 82 76 byte

-10 byte nhờ @DigitalTrauma!
-11 byte nhờ @manatwork!
-6 byte nhờ @Dennis!

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

Giải trình:

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

Hãy thử trực tuyến!


2
Điều đó thật tuyệt! Tôi đã hy vọng sẽ có một câu trả lời bash.

13

Mê cung , 43 41 byte

Cảm ơn Sp3000 đã lưu 2 byte.

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

Hãy thử trực tuyến!

Giải trình

Ý tưởng cơ bản là mã hóa năm ký tự cuối cùng trong cơ sở 256 theo một số nguyên duy nhất. Khi một ký tự mới xuất hiện, chúng ta có thể "nối" nó bằng cách nhân số nguyên với 256 và thêm điểm mã mới. Nếu chúng ta chỉ muốn nhìn vào 5 ký tự cuối cùng, chúng ta lấy giá trị modulo 256 5 = 2 40 = 1099511627776. Sau đó, chúng ta có thể kiểm tra xem giá trị này có bằng với 448378203247 hay không, đó là những gì chúng ta nhận được khi xử lý các điểm mã của hellodưới dạng chữ số cơ sở 256.

Đối với mã ... <...>là một chút thành ngữ Labyrinth. Nó cho phép bạn viết một vòng lặp vô hạn mà không có bất kỳ luồng điều khiển có điều kiện nào trên một dòng duy nhất, tiết kiệm rất nhiều byte trên khoảng trắng và nguồn cấp dữ liệu. Điều kiện chính để làm việc này là có hai giá trị dùng một lần trên đỉnh của ngăn xếp khi chúng ta đạt đến <(chúng ta thường sử dụng 0s cho điều đó, nhưng giá trị thực tế là tùy ý).

Tất nhiên, chương trình cần một số logic có điều kiện để tìm ra khi nào nên chấm dứt. Nhưng điều kiện kết thúc chương trình là có thể bằng cách chia cho một giá trị bằng 0 khi chúng ta muốn chương trình kết thúc. Cấu <...>trúc hoạt động bằng cách dịch chuyển toàn bộ hàng bên trái (theo chu kỳ) khi IP ở đầu bên trái, và sau đó ngay lập tức chuyển nó trở lại vị trí. Điều này có nghĩa là mã thực sự được thực hiện từ phải sang trái. Hãy đảo ngược nó:

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

Đây là một lần lặp của vòng lặp đọc một ký tự, chấm dứt nếu chúng ta đạt EOF, in ký tự đó, thêm nó vào mã hóa của chúng ta, cắt ngắn thành 5 ký tự, kiểm tra sự bằng nhau hellovà lặp lại. Đây là cách nó hoạt động chi tiết (hãy nhớ rằng Labyrinth dựa trên stack):

_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.

8

Brainfuck, 658 byte

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

Hơn 500 byte là trong các hằng số mà tôi cần chơi gôn một chút.

Nó thực chất là một máy trạng thái, vì vậy đầu vào vô hạn không phải là vấn đề.

Đây là phiên bản hơi bình luận

+
[
  >,.
  >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]
            <->>
          ]
        ]
      ]
    ]
  ]
  <<
]

Điều này có vẻ vui :)

Chào mừng bạn đến với Câu đố lập trình và Code Golf StackExchange!
betseg

1
Mã này có nhiều vấn đề, nhưng vấn đề lớn nhất là nó không bao gồm logic để xử lý các trường hợp như ahehellobđúng; ở giữa một trận đấu tiềm năng, nó chỉ kiểm tra chữ cái tiếp theo hellovà không tìm kiếm hđể bắt đầu lại.
Mitch Schwartz

8

Bash , 73 68 66 byte

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

Giả sử một thư mục không có hoặc chỉ có các tập tin ẩn. Phải chạy như <path/to/script>.

Hãy thử trực tuyến!

Cách thức hoạt động (lỗi thời)

Vào lúc bắt đầu của trong khi vòng lặp, chúng tôi thử nghiệm đầu tiên nếu chuỗi trong biến s (ban đầu có sản phẩm nào) bằng olleh ( xin chào ngược, OLE), và trở về 0 (trận đấu) hoặc 1 (không phải là một trận đấu) cho phù hợp. Mặc dù chính thức là một phần của điều kiện của vòng lặp, kết quả sẽ không ảnh hưởng đến chính nó, vì chỉ có lệnh cuối cùng trước khi doxác định nếu điều kiện giữ.

Tiếp theo, chúng tôi đặt dấu tách trường bên trong thành chuỗi trống (vì vậy readsẽ không bị nghẹt trên khoảng trắng), đọc byte thô ( -r) từ STDIN và lưu trữ chúng vào c. $?là mã thoát của lệnh trước, vì vậy, lệnh này đọc chính xác một -N1byte ( ) cho một byte không khớp và 0 byte ( -N0). Đọc byte không, cho dù đó là do nhấn EOF hoặc do -N0được chỉ định, nguyên nhân readthoát ra với mã trạng thái 1 , do đó vòng lặp while sẽ kết thúc; mặt khác, cơ thể được thực thi và chúng ta bắt đầu lại.

Trong phần thân, trước tiên chúng ta in byte chúng ta đọc, sau đó cập nhật s với s=$c${s::4}. Điều này chuẩn bị byte đọc thành (tối đa) bốn byte đầu tiên tính bằng s , vì vậy s sẽ bằng olleh sau khi lời chào được in.


Thực sự rất tốt đẹp!

8

Brainfuck, 117 byte

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

Định dạng:

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

Hãy thử trực tuyến .

Thao tác này khởi tạo băng với các ký tự được hellobù trừ 107, cách nhau một giá trị cho mỗi ba ô, sau đó theo dõi năm ký tự cuối cùng được nhìn thấy và kiểm tra sự trùng khớp với mỗi ký tự mới được xử lý, sử dụng cờ ở bên phải chuỗi theo dõi xem đã có một trận đấu.


7

Ruby , 46 60 byte

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

Hãy thử trực tuyến!

Đọc các ký tự từ stdin cho đến 5 ký tự cuối cùng hello, sau đó xuất chuỗi (hoặc cho đến khi không còn ký tự nào trong stdin). Chấm dứt với lỗi.

Tương đương với:

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

Hoặc, vô duyên hơn:

a = ""
loop do
    q = STDIN.getc
    break if a[-5..-1] == "hello" or not q
    a += q
    print q
end

1
aphát triển mỗi khi một char được đọc. Liệu sự cố này nếu đầu vào là vô hạn?
betseg

@betseg hm, có thể. Hãy để tôi xem liệu tôi có thể khắc phục điều đó không
Conor O'Brien

7

Python 3, 120 116 104 byte

Hoạt động với các luồng vô hạn, lần đầu tiên chơi golf, bất kỳ lời khuyên nào cũng được đánh giá cao.

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

Cảm ơn @DJMcMayhem vì đã lưu một số byte :)


Chào mừng đến với trang web! c=[0,c+1]['hello'[c]==a]sẽ giúp bạn tiết kiệm một số byte. Ngoài ra, a=1là ngắn hơn quá.
DJMcMayhem

2
Bạn không cần dấu ngoặc đơn whiletrong Python.
PurkkaKoodari

6

Haskell, 41 47 43 byte

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

Sự lười biếng của Haskell xử lý tốt đầu vào / đầu ra vô hạn.

Hãy thử trực tuyến!

Chỉnh sửa: không xử lý đầu vào hữu hạn - đã sửa. Cảm ơn @Leo đã chỉ ra.

Chỉnh sửa II: @ rjan Johansen đã lưu 4 byte. Cảm ơn!


2
Đầu vào cũng có thể là hữu hạn, vì vậy tôi nghĩ rằng bạn cần phải giải quyết trường hợp này khi bạn đến cuối chuỗi
Leo

@Leo: Rất tiếc, hoàn toàn bỏ lỡ nó. Đã sửa.
nimi

2
Bảo vệ đầu tiên có thể được rút ngắn |w@"hello"<-take 5l=w.
Ørjan Johansen

@ RjanJohansen: oh, đó là một trong những tốt đẹp. Cảm ơn!
nimi

6

Cubix, 94 83 82 79 63 56 byte

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

Mở rộng:

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

Ghi chú

  • Trình thông dịch sẽ vô hiệu hóa trường đầu vào khi chương trình bắt đầu. Như vậy, một dòng đầu vào vô hạn là không thể. Chương trình này lấy từng ký tự đầu vào, vì vậy nếu không có giới hạn này, nó sẽ hoạt động bình thường.
  • Chương trình này không dọn sạch ngăn xếp và nó trở nên lộn xộn rất nhanh. Vì máy này sẽ được sử dụng trên rõ ràng có thể cung cấp luồng đầu vào vô hạn, nên có vẻ hợp lý khi cho rằng nó cũng có bộ nhớ vô hạn.
  • Bất kỳ và tất cả sự giúp đỡ chơi golf được nhiều đánh giá cao.

Dùng thử trực tuyến

Bạn có thể thử chương trình tại đây .

Giải trình

Ý tưởng chung

Ý tưởng chung là chúng tôi muốn đọc một ký tự, và sau đó kiểm tra nó với các ký tự khác nhau (đầu tiên h, sau đó e, sau đó, lv.v.). Để theo dõi nhân vật mà chúng tôi đã bỏ lỡ, chúng tôi giữ nó ở dưới cùng của ngăn xếp. Khi chúng ta cần nó, chúng ta có thể dễ dàng đưa nó lên đỉnh một lần nữa.

Vòng lặp đọc / ghi

Vòng lặp đọc-ghi chỉ đơn giản là dòng thứ 5 . Tất cả các ký tự không được sử dụng được thay thế bằng no-ops ( .):

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

Điều này có thể được chia thành hai phần: Đọc và (viết và kiểm tra). Phần đầu tiên chứa các hướng dẫn lên đến và bao gồm cả dấu hỏi. Phần thứ hai trở lên là phần còn lại của dòng. Vì vòng lặp này, chúng tôi giả sử chúng tôi bắt đầu với một chồng[...]

    @
'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

Phần thứ hai (viết và kiểm tra) là tuyến tính một lần nữa. Các ngăn xếp bắt đầu như [next-char, ..., input]. Chúng tôi trừu tượng hóa nhân vật tiếp theo, bởi vì điều đó thay đổi sau đó trong chương trình.

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.

Bây giờ, IP sẽ bắt đầu lại ở đầu vòng lặp này, đặt lại ký tự tiếp theo để kiểm tra h.

Phù hợp với nhân vật tiếp theo

Nếu IP thực hiện lần lượt (nghĩa là ký tự chúng ta đọc và in khớp với ký tự tiếp theo 'hello'), chúng ta cần kiểm tra ký tự đầu vào là gì và tùy thuộc vào đó, đẩy ký tự tiếp theo xuống dưới cùng của ngăn xếp. Sau đó, chúng ta cần quay lại vòng lặp đọc / ghi, mà không cần đẩy hvào ngăn xếp, vì vậy chúng ta cần một cách khác để đến đó.

Điều đầu tiên trước tiên: xác định nhân vật đầu vào là gì. Các ngăn xếp trông như thế này : [..., prev-char, input, 0].

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

Để so sánh đầu vào, chúng tôi sử dụng mã ký tự của hmột lần nữa. Ban đầu, điều này là do tôi không thực sự biết mình sẽ xử lý việc này như thế nào và hlà nhân vật đầu tiên trong chuỗi để kiểm tra, nhưng cuối cùng nó khá thuận tiện. Nếu chúng ta trừ mã ký tự của h khỏi đầu vào, chúng ta sẽ nhận được -3nếu đầu vào là e, 0nếu đầu vào là h, 4nếu đầu vào là l7 nếu đầu vào là o.

Điều này rất hữu ích, vì ?lệnh cho phép chúng ta dễ dàng tách các giá trị âm khỏi giá trị dương và 0. Như vậy, nếu IP rẽ trái, sự khác biệt là âm, do đó, đầu vào là e, vì vậy ký tự tiếp theo phải là một l. Nếu IP tiếp tục đi thẳng, sự khác biệt là 0, vì vậy đầu vào là h, vì vậy ký tự tiếp theo sẽ là một e. Nếu đầu vào là một lhoặc một o, IP rẽ phải.

Tất cả các hướng dẫn được thực hiện trước dấu chấm hỏi đã nói ở trên là:

;!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]

Bây giờ IP thay đổi hướng của nó như chi tiết ở trên. Chúng ta hãy đi qua các khả năng khác nhau.

Đầu vào 'e'

Trước tiên, chúng tôi sẽ xem xét đầu vào e, khiến IP di chuyển lên trên ?, vì sự khác biệt là 3. Tất cả các ký tự không liên quan đã bị xóa khỏi khối.

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

Các ký tự được thực hiện theo thứ tự này (không bao gồm một số ký tự điều khiển):

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, ...]

Bây giờ IP đã đạt đến vòng lặp đọc / ghi một lần nữa.

Đầu vào 'h'

Nếu đầu vào là 'h', chênh lệch là 0, do đó IP không thay đổi hướng của nó. Đây là khối lập phương một lần nữa, với tất cả các ký tự không liên quan được loại bỏ. Vì đường dẫn này bao gồm khá nhiều no-op, tất cả các no-op mà nó đi qua đã được thay thế bằng &. IP bắt đầu ở dấu hỏi.

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

Các hướng dẫn được thực hiện là:

'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

Và bây giờ chúng ta lại bước vào vòng lặp đọc / ghi, vậy là xong.

Đầu vào khác

Tất cả các đầu vào khác dẫn đến một sự khác biệt tích cực, vì vậy IP quay đúng ở dấu hỏi. Chúng ta vẫn cần tách biệt lo, vì vậy đó là những gì chúng ta sẽ làm tiếp theo.

Tách 'l''o'

Hãy nhớ rằng sự khác biệt là 7 cho ovà 4 cho lvà chúng ta phải kết thúc chương trình nếu đầu vào là một o. Đây là khối lập phương một lần nữa với các phần không liên quan được thay thế bằng a .và các dấu chéo IP đã được thay thế bằng ký hiệu.

        . . 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

Khác biệt giữa hai 'l's

Vì vậy, bây giờ chúng tôi biết rằng đầu vào là một l, nhưng chúng tôi không biết cái nào l. Nếu đó là lần đầu tiên, chúng ta cần đẩy người khác lxuống dưới cùng của ngăn xếp, nhưng nếu đó là lần thứ hai, chúng ta cần phải đẩy một o. Hãy nhớ rằng chúng tôi đã lưu -3vào dưới cùng của ngăn xếp ngay trước khi chúng tôi đẩy đầu tiên l? Chúng ta có thể sử dụng điều đó để tách hai nhánh.

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

Ngăn xếp bắt đầu như [..., -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

Đầu tiên 'l'

Nếu đây là lần đầu tiên 'l', chúng ta cần phải đẩy người khác 'l'. Để lưu byte, chúng tôi sử dụng các ký tự giống như lần đầu tiên 'l'. Chúng ta có thể đơn giản hóa ngăn xếp để [...]. Đây là phần có liên quan của khối lập phương, không có thay thế bằng ký hiệu.

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

Các hướng dẫn sau đây được thực hiện:

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

Chúng tôi sắp bước vào vòng đọc / ghi, vì vậy chúng tôi đã hoàn thành với nhánh này.

Thứ hai 'l'

Nếu đầu vào là người thứ hai 'l'trong 'hello', IP quay ngay tại dấu chấm hỏi. Một lần nữa, chúng ta có thể đơn giản hóa ngăn xếp [...]và IP bắt đầu ?, chỉ về phía nam lần này.

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

Các hướng dẫn được thực hiện là:

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

Và IP sắp sửa nhập lại vòng lặp đọc / ghi, vì vậy chúng tôi cũng đã hoàn thành với nhánh này.


Một nỗ lực anh hùng!

5

C ++, 142 141 byte

#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;}

Hãy thử trực tuyến!


Điều này sẽ có thể với GCC? Tôi không thấy #importtrong các chương trình GCC C ++ ...
ckjbgames

1
@ckjbgames #importlà một phần mở rộng GCC không dùng nữa.
Steadybox

1
@ckjbgames có thêm thông tin tại đây: stackoverflow.com/questions/172262/ cấp
iFreilicht

@iFreilicht Câu hỏi đó thực sự khiến tôi phải hỏi điều đó.
ckjbgames

1
@ckjbgames bạn có thể muốn xem câu trả lời thứ hai: stackoverflow.com/a/172264/2533467 "Nhập khẩu trong gcc khác với nhập khẩu trong VC ++. Đây là cách đơn giản để chỉ bao gồm một tiêu đề. "
iFreilicht

3

Nút, 124 byte

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

Không cho rằng luồng sẽ phù hợp với bộ nhớ khả dụng.


3

C #, 134 byte

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;}}

Dùng thử trực tuyến

Đọc một ký tự, kiểm tra xem nó không phải là -1 (EOS) và chúng ta chưa thấy "xin chào", sau đó đưa nó vào một chuỗi và viết ký tự ra. Chúng tôi trả trước vì s[0]ngắn hơn rất nhiều (char)s. Điều này có chi phí bậc hai theo chiều dài của chuỗi, vì nó phải phân bổ và quét toàn bộ đầu vào mỗi khi nó đọc một ký tự (điều này sẽ sụp đổ sau 2GB đầu vào do các ràng buộc trong CLR, có được phép không?)

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;
    }
}

Đối với phiên bản (dài hơn: 142 byte) sẽ không hết bộ nhớ và có chi phí cho mỗi ký tự không đổi, xem bên dưới:

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;}}

Cái này giữ 5 ký tự cuối cùng trong chuỗi 5 độ dài, có nghĩa là so sánh ngắn và tra cứu char cuối giá rẻ, nhưng đắt hơn đáng kể để cập nhật.

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;
    }
}

3

PHP, 57 55 53 byte

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

vì không có tệp vô hạn, tôi lấy đầu vào từ STDIN. Chạy với-nr .

Lặp lại thông qua đầu vào, in ký tự hiện tại, nối nó vào $s, cắt $sđến 5 ký tự cuối cùng. Phá vỡ vòng lặp khi $shello.


3

Vim, 39 byte

:im hello hello:se noma
:map : i

i

Hãy thử trực tuyến!

: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

Đây có phải là một phương thức nhập liệu được chấp nhận cho Vim? Tôi nghĩ rằng các chương trình Vim thường mong đợi đầu vào đã có trong bộ đệm trước khi chúng bắt đầu.
Martin Ender

Thành thật mà nói tôi không biết? Điều đó đúng, nhưng hầu như không cho phép một luồng vô hạn, vì vậy tôi chỉ làm theo cách này mà không thực sự nghĩ quá nhiều về nó.
nmjcman101

Điều gì xảy ra nếu có một ký tự thoát trong luồng đầu vào?
mờ

@dim Tôi đã hỏi và OP chỉ định ASCII có thể in và các dòng mới. ESC không được bao gồm trong ASCII afaik có thể in
nmjcman101

3

PowerShell, 111 byte

Có lẽ có một cách tốt hơn để làm điều này, nhưng tôi không thể nhìn thấy nó vào lúc này.

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

Điều này đọc các nét chính mà không làm giảm tiếng vang. Ký tự được thêm vào $ x được cắt bớt thành 5 ký tự cuối cùng và được so sánh với "xin chào". Điều này tiếp tục cho đến khi so sánh là đúng.

Lưu ý: điều này không hoạt động trong PowerShell ISE. ReadKey bị vô hiệu hóa trong môi trường đó.


3

Sơ đồ 115 byte

(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))

Phiên bản dễ đọc:

(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

Điều này nhận một char riêng lẻ từ stdin mỗi lần xung quanh vòng lặp và đánh dấu vị trí của nó trên từ đích khi nó gặp các ký tự của "xin chào".

Dừng khi hết đầu vào hoặc "xin chào". Không có bộ nhớ được sử dụng trên luồng vô hạn.


Câu trả lời tuyệt vời, chào mừng đến với trang web!
DJMcMayhem

3

AWK, 95 byte

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

Có 2 điều tôi học được ở đây:
1) Để phân chia các bản ghi giữa các ký tự sử dụng RS="(.)"và sau đó RTphải được sử dụng thay vì $1
2) ORSđược sử dụng bởi printvà được mặc định là "\n"
3) Tôi không thể đếm đến 2 và sử dụng printflà "rẻ hơn" so với gán ORSvà sử dụngprint

Ví dụ sử dụng: Đặt mã trong TẬP_TIN

awk -f FILE some_data_file

hoặc là

some process | awk -f FILE

Mã đã được thử nghiệm bằng yes | ...đề xuất của Dennis và tôi đã thấy rất nhiều ys.

FYI, bạn có thể thực hiện chuyển nhượng RS dưới dạng tùy chọn và kéo nó ra khỏi BEGINkhối thông qua:

awk -v RS='(.)'

Giải pháp thực sự khó khăn! (Có lẽ vì đó là chiều thứ Sáu, nhưng tôi thấy nó vào tốt cho thách thức khó hiểu quá.) Mặc dù tôi sẽ cố gắng một cách tiếp cận awkish hơn: BEGIN{RS="(.)"}{printf RT}"olleh"==a=RT substr(a,1,4){exit}.
manatwork

Thật kỳ lạ, tôi có câu trả lời gần như chính xác sẵn sàng để gửi một giờ trước ... và quên gửi nó. : 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]

Cảm ơn @MitchSchwartz đã chơi golf 1 byte!

Hãy thử trực tuyến!


Tôi không hiểu Làm thế nào để điều kiện để whileđánh giá đúng? Có vẻ như bạn đang so sánh một boolean với một chuỗi rỗng.
iFreilicht

1
s[print(end=c):4]tiết kiệm một byte
Mitch Schwartz

1
@iFreilicht Python phân tích cú pháp các chuỗi có điều kiện như trong toán học ( ví dụ a <b <c ). Điều kiện là một tốc ký cho 'olleh'!=s and s>''and''<c). Bài kiểm tra giữa không cần thiết, nhưng xâu chuỗi chúng ngắn hơn đơn giản 'olleh'!=s and''<c.
Dennis

@MitchSchwartz Đó là nó. Cảm ơn bạn!
Dennis

3

Mã máy 8086, 22 byte

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

Mã lắp ráp tương đương:

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"

Làm thế nào nó hoạt động?

1
Tôi đã thêm mã lắp ráp tương đương. Về cơ bản, nó dựa vào một tòa nhà DOS rất hữu ích, nó đọc một byte từ stdin và lặp lại nó thành thiết bị xuất chuẩn cùng một lúc. 8086 cũng có một hướng dẫn so sánh chuỗi đơn byte có ích ở đây.
dùng5434231

2

Bình thường, 49 47 byte

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

Pyth không giỏi lắm trong việc lấy một ký tự đầu vào. Tất cả mọi thứ trong$__import__("sys").stdin.read(1) chỉ đơn giản là làm điều đó. Ngoài ra, nó có nghĩa là điều này chỉ chạy ngoại tuyến.

Mọi thứ khác đều ngắn ...

Chương trình này là một vòng lặp trong khi vòng lặp. Trong điều kiện, chương trình đọc một ký tự, in lại, nối thêm ký tự kđó (ban đầu là chuỗi rỗng), cắt bỏ tất cả trừ 5 ký tự cuối cùng kvà sau đó kiểm tra xem kết quả có không "hello".

32 ký tự nhận được một byte đầu vào, 15 ký tự còn lại.

Đã thử nghiệm trên Linux, hoạt động ngay cả khi không có dòng mới, đầu vào vô hạn, v.v.


2

Lua, 68 64 byte

l=""while l~="hello"do c=io.read(1)io.write(c)l=l:sub(-4)..c end

1
Thay đổi phần cắt thành l:sub(-4), sau đó bạn có thể giảm việc khởi tạo l="".
manatwork

@manatwork Thật gọn gàng. Cảm ơn vì tiền hỗ trợ.
Blab


1

Röda , 49 47 byte

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

Hãy thử trực tuyến!

Đây là một chức năng ẩn danh đọc các ký tự từ luồng đầu vào của nó và xuất chúng cho đến khi tìm thấy "xin chào". Nó sử dụng mảnga để theo dõi các ký tự cuối cùng.

Nó xuất ra một số rác cho STDERR, nhưng tôi hiểu rằng đó là cho phép .

Giải trình:

{
    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. */
}

Tài liệu Roda ở đâu?
ckjbgames

@ckjbgames Đây. Tôi sử dụng phiên bản mới nhất 0.12, thuộc chi nhánh riêng của nó trong Github.
fergusq

1

Java 7, 122 118 124 123 150 141 byte

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);}

Bây giờ dừng lại khi kết thúc luồng. Bây giờ xử lý đầu vào vô hạn mà không hết bộ nhớ.


Tôi đặt cược điều này có thể xử lý đầu vào vô hạn.
Tít

@Titus đã sửa ...
Chọc

Tôi downvote mà không thấy writeđược sử dụng thay vì print. Tôi không thể hoàn tác downvote của mình, xin lỗi vì điều đó :(
Olivier Grégoire

1

Ruby, 51 byte

x="";$><<x[-1]while/hello./!~x=x[/.{0,5}$/]+$<.getc
  • Không mong đợi tin tức mới
  • Hoạt động với đầu vào vô hạn

1

AHK , 116 byte

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

Không có gì thông minh hay ma thuật trong đó, thực sự. Biến %1%là đối số được truyền đầu tiên và phải là đường dẫn tệp với luồng. Tệp phải được lưu khi được cập nhật nhưng mã sẽ đọc đến cuối ngay cả khi nó mở rộng sau khi đọc bắt đầu.


1

Toán học, 107 byte

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

Đầu ra trở thành một trường trong đó người dùng có thể nhập văn bản vô hạn (bao gồm cả dòng mới) cho đến khi 5 ký tự cuối cùng bằng "hello"; tại thời điểm đó, nó thoát ra.


1

Brainfuck , 281 byte

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

Tôi không chắc tại sao, nhưng tôi chỉ cảm thấy như Brainfuck là điều đúng đắn để làm điều này. Không yêu cầu bộ nhớ vô hạn và có thể xuất ra mãi mãi.

Giải thích

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
]

Hãy thử trực tuyến!


Tôi sẽ làm điều đó như thế này nhưng sau đó tôi nhận ra rằng điều này tạo ra byte 0 hoàn toàn cho đầu vào không chứa "hello": tio.run/nexus/ trộm
KarlKastor

Điều này cũng thất bại trên ahehellob .
Mitch Schwartz
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.