Tugas
Baca dalam aliran teks atau file yang mungkin tak terbatas, mengeluarkan kontennya hingga kata hello
tersebut dikeluarkan, mematuhi aturan berikut.
Setelah
hello
dikeluarkan, kode Anda harus segera keluar. Seharusnya tidak menunggu baris baru misalnya.Kode Anda harus ditampilkan saat berjalan. Itu seharusnya tidak dibaca dalam jumlah besar input dan kemudian mulai menghasilkan.
Jika stream / file tidak mengandung
hello
, kode Anda harus terus mengeluarkan input selamanya atau sampai akhir stream / file tercapai.Ini adalah tantangan case-sensitive, jadi
hello
tidak sama denganHello
.Anda dapat berasumsi bahwa input hanya terdiri dari karakter dan baris ASCII yang dapat dicetak.
Kode Anda tidak dapat berharap bahwa teks akan dihentikan oleh baris baru atau akan ada baris baru sama sekali dalam input. Selain itu, kode Anda tidak dapat berasumsi bahwa kode itu akan berjalan pada mesin dengan jumlah memori tak terbatas.
Anda dapat mengasumsikan bahwa kode Anda akan dipanggil dari direktori kosong.
Contoh aliran input
I once had a horse called hellopina.
Keluaran
I once had a horse called hello
Tip
Jalankan yes | tr -d \\n | <your program>
untuk memeriksa apakah ia bekerja dengan aliran yang tak terbatas. Jika tidak mencetak apa pun dan / atau kebocoran memori, program tidak mematuhi spesifikasi. Ini harus dicetak yyyyyyyyyyyyyyyyyyyyyy...
selamanya tanpa baris baru.
Jawaban:
Jelly , 24 byte
Cobalah online!
Penjelasan:
sumber
C (gcc) ,
8180767572717069 byteCobalah online!
Bagaimana itu bekerja
Ini adalah program lengkap. Kami mendefinisikan fungsi f untuk tujuan kami. Untuk menyimpan byte, dinyatakan dengan dua argumen yang default ke int . Ini adalah perilaku yang tidak terdefinisi, tetapi dalam praktiknya, n akan diinisialisasi sebagai 1 saat menjalankan program tanpa argumen tambahan, c akan menahan 32 bit lebih rendah dari pointer ke vektor argumen
Sementara kondisinya
tahan, kami akan menjalankan tubuh while :
Untuk sepenuhnya memahami kondisinya, pertama-tama kita harus memeriksa tubuh. Untuk saat ini, yang kami amati adalah yang
c=getchar()
membaca satu byte dari STDIN (jika mungkin) dan menyimpannya dalam variabel c .Urutan byte halo terlihat sebagai berikut dalam representasi berbeda.
Semua ini berada dalam kisaran [96, 192) , sehingga
c/96
akan mengevaluasi ke 1 untuk setiap byte ini, dan ke 0 untuk semua karakter ASCII yang tersisa. Dengan cara ini,putchar(c)/96*c
( putchar mencetak dan mengembalikan argumennya) akan mengevaluasi ke c jika c adalah`
, huruf kecil, salah satu{|}~
, atau karakter DEL; untuk semua karakter ASCII lainnya, itu akan mengevaluasi ke 0 .n diperbarui dengan menggesernya lima bit ke kiri, kemudian XORing hasilnya dengan hasil dari paragraf sebelumnya. Karena int adalah 32 bit lebar (atau lebih kita asumsikan dalam jawaban ini), beberapa bit yang bergeser mungkin "jatuh dari kiri" (ditandatangani integer overflow adalah perilaku tidak terdefinisi, tetapi gcc berperilaku sebagai instruksi x64 yang dihasilkannya di sini). Dimulai dengan nilai n yang tidak diketahui , setelah memutakhirkannya untuk semua karakter halo , kami mendapatkan hasil berikut.
Perhatikan bahwa 25 bit yang lebih rendah membentuk integer 0xb33def , yang merupakan konstanta ajaib dalam kondisi tersebut. Sementara ada beberapa tumpang tindih antara bit dari dua byte yang berdekatan, pemetaan byte di bawah 96 hingga 0 memastikan bahwa tidak ada false positive.
Kondisi ini terdiri dari dua bagian:
~(getchar())
mengambil bitwise TIDAK dari hasil membaca (atau berusaha membaca) satu byte dari STDIN.Jika getchar berhasil, itu akan mengembalikan nilai byte read sebagai int . Karena input seluruhnya terdiri dari karakter ASCII, byte baca hanya dapat memiliki 7 bit yang lebih rendah, sehingga bitwise TIDAK akan memiliki 25 bit tertinggi yang ditetapkan dalam kasus ini.
Jika getchar gagal (tidak ada input lagi), itu akan mengembalikan -1 dan bitwise TIDAK akan menjadi 0 .
n-0xb33def<<7
kurangi konstanta ajaib dari sebelumnya dari n , lalu alihkan hasilnya 7 unit ke kiri.Jika 5 byte terakhir dibaca adalah hello , 25 bit terendah n akan sama dengan 0xb33def dan pengurangannya akan nol. Menggeser perbedaan akan menghasilkan 0 karena 7 bit tertinggi akan "jatuh dari kiri".
Di sisi lain, jika 5 byte terakhir dibaca bukan halo , salah satu dari 25 bit terendah dari perbedaan akan ditetapkan; setelah bergeser, salah satu dari 25 bit tertinggi adalah.
Akhirnya, jika getchar berhasil dan kami belum mencetak halo , bitwise AND, semua 25 bit tertinggi dari operan kiri dan setidaknya satu dari 25 bit tertinggi dari yang benar akan ditetapkan. Dengan cara ini,
&
akan menghasilkan bilangan bulat bukan nol dan loop berlanjut.Di sisi lain, jika input sudah habis atau kita sudah mencetak halo , salah satu operan bitwise AND akan menjadi nol, dan begitu juga hasilnya. Dalam hal ini, kami keluar dari loop dan program berakhir.
sumber
Bash,
747510399888276 byte-10 byte berkat @DigitalTrauma!
-11 byte terima kasih kepada @manatwork!
-6 byte terima kasih kepada @Dennis!
Penjelasan:
Cobalah online!
sumber
Labirin ,
4341 byteTerima kasih kepada Sp3000 untuk menghemat 2 byte.
Cobalah online!
Penjelasan
Ide dasarnya adalah untuk menyandikan lima karakter terakhir dalam basis 256 dalam satu integer. Ketika karakter baru masuk, kita dapat "menambahkan" dengan mengalikan bilangan bulat dengan 256 dan menambahkan titik kode baru. Jika kita ingin melihat hanya pada 5 karakter terakhir, kita mengambil nilai modulo 256 5 = 2 40 = 1099511627776. Kemudian kita cukup memeriksa apakah nilai ini sama dengan 448378203247, yang adalah apa yang kita dapatkan ketika kita memperlakukan poin kode dari
hello
sebagai basis-256 digit.Adapun kode ...
<...>
adalah sedikit idiom Labyrinth. Ini memungkinkan Anda untuk menulis loop tanpa batas tanpa aliran kontrol bersyarat pada satu baris, menghemat banyak byte pada spasi dan umpan baris. Kondisi utama agar ini berfungsi adalah bahwa ada dua nilai pakai di atas tumpukan ketika kita mencapai<
(kita biasanya menggunakan0
s untuk itu, tetapi nilai aktualnya sewenang-wenang).Tentu saja, program ini memang membutuhkan beberapa logika kondisional untuk mencari tahu kapan harus mengakhiri. Tetapi mengakhiri program dengan kondisional dimungkinkan dengan membagi dengan nilai yang nol ketika kita ingin program berakhir. The
<...>
membangun karya dengan menggeser seluruh baris kiri (siklis) ketika IP adalah pada akhir kiri, dan kemudian segera bergeser kembali ke posisinya. Ini berarti bahwa kode sebenarnya dieksekusi dari kanan ke kiri. Mari kita balikkan:Ini adalah salah satu iterasi dari loop yang membaca karakter, berakhir jika kita telah mencapai EOF, mencetak karakter, menambahkannya ke pengkodean kita, memotongnya menjadi 5 karakter, memeriksa kesetaraan dengan
hello
dan mengulangi. Inilah cara kerjanya secara detail (ingat bahwa Labyrinth berbasis stack):sumber
Brainfuck, 658 byte
Lebih dari 500 byte berada dalam konstanta yang saya butuhkan untuk bermain golf sedikit.
Ini pada dasarnya adalah mesin keadaan, jadi input tak terbatas bukanlah masalah.
Ini adalah versi yang sedikit berkomentar
sumber
ahehellob
dengan benar; di tengah-tengah kecocokan potensial, itu hanya memeriksa huruf berikutnyahello
dan tidak mencari untukh
memulai kembali.Bash ,
736866 byteMengasumsikan direktori tanpa atau hanya file tersembunyi. Harus dijalankan sebagai
<path/to/script>
.Cobalah online!
Cara kerjanya (ketinggalan jaman)
Pada awal loop sementara , pertama-tama kita menguji apakah string dalam variabel s (awalnya kosong) sama dengan olleh ( halo mundur, olé), dan kembalikan 0 (cocok) atau 1 (bukan yang cocok). Walaupun secara formal bagian dari kondisi loop, hasilnya tidak akan memengaruhi itu sendiri, karena hanya perintah terakhir sebelum
do
menentukan apakah kondisi tersebut berlaku.Selanjutnya, kita mengatur pemisah bidang internal ke string kosong (jadi
read
tidak akan tersedak di spasi putih), membaca byte mentah (-r
) dari STDIN dan menyimpannya dic
.$?
adalah kode keluar dari perintah sebelumnya, jadi ini membaca tepat satu (-N1
) byte untuk non-cocok dan nol byte (-N0
). Membaca nol byte, baik karena menekan EOF atau karena-N0
ditentukan, menyebabkanread
keluar dengan kode status 1 , sehingga loop sementara akan berakhir; kalau tidak, tubuh dieksekusi dan kita mulai lagi dari awal.Di dalam tubuh, pertama kita mencetak byte yang kita baca, maka update s dengan
s=$c${s::4}
. Ini akan menambah byte read ke (hingga) empat byte pertama dalam s , jadi s akan sama dengan olleh begitu hello telah dicetak.sumber
brainfuck, 117 byte
Diformat:
Cobalah online .
Ini menginisialisasi rekaman dengan karakter
hello
diimbangi oleh107
, spasi dengan satu nilai setiap tiga sel, kemudian melacak lima karakter terakhir yang terlihat dan memeriksa kecocokan dengan setiap karakter baru yang diproses, menggunakan bendera di sebelah kanan string untuk melacak apakah ada kecocokan.sumber
Ruby ,
4660 byteCobalah online!
Membaca karakter dari stdin hingga 5 terakhir
hello
, lalu mengeluarkan string (atau hingga tidak ada karakter yang tersisa di stdin). Berakhir dengan kesalahan.Setara dengan:
Atau, lebih ungolfed:
sumber
a
tumbuh setiap kali arang dibaca. Apakah ini macet jika inputnya tidak terbatas?Python 3,
120116104 BytesBekerja dengan aliran tanpa batas, golf pertama kali, tips apa pun akan dihargai.
Terima kasih @DJMcMayhem karena telah menghemat beberapa byte :)
sumber
c=[0,c+1]['hello'[c]==a]
harus menghemat beberapa byte. Juga,a=1
lebih pendek juga.while
dalam Python.Haskell,
414743 byteKemalasan Haskell menangani input / output tak terbatas berhenti dengan baik.
Cobalah online!
Sunting: tidak menangani input hingga - diperbaiki. Terima kasih @ Leo untuk menunjukkan.
Sunting II: @ Ørjan Johansen menyimpan 4 byte. Terima kasih!
sumber
|w@"hello"<-take 5l=w
.Cubix,
94 83 82 79 6356 byteDiperluas:
Catatan
Cobalah online
Anda bisa mencoba programnya sini .
Penjelasan
Ide umum
Gagasan umum adalah bahwa kita ingin membaca sebuah karakter, dan kemudian memeriksanya terhadap berbagai karakter (pertama
h
, lalue
, kemudianl
dll). Untuk melacak karakter yang telah kita lewatkan, kita menyimpannya di bagian paling bawah tumpukan. Ketika kita membutuhkannya, kita dapat dengan mudah membawanya ke atas lagi.Baca / Tulis loop
Loop baca-tulis hanyalah baris ke- 5 . Semua karakter yang tidak digunakan digantikan oleh no-ops (
.
):Ini dapat dibagi menjadi dua bagian: Membaca dan (menulis dan memeriksa). Bagian pertama berisi instruksi hingga dan termasuk tanda tanya. Bagian kedua adalah sisa baris. Karena ini berulang, kita asumsikan kita mulai dengan setumpuk
[...]
Bagian kedua (menulis dan memeriksa) linier lagi. Tumpukan dimulai sebagai
[next-char, ..., input]
. Kami mengabstraksi karakter berikutnya, karena itu berubah kemudian dalam program.Sekarang, IP akan mulai lagi pada awal loop ini, mengatur ulang karakter berikutnya untuk diperiksa
h
.Mencocokkan karakter berikutnya
Jika IP berbelok-u (yaitu karakter yang kita baca dan cetak cocok dengan karakter berikutnya
'hello'
), kita perlu memeriksa karakter apa yang dimasukkan dan tergantung pada itu, dorong karakter berikutnya ke bagian bawah tumpukan. Setelah itu, kita perlu kembali ke loop baca / tulis, tanpa mendorongh
ke stack, jadi kita perlu cara lain untuk sampai ke sana.Hal pertama yang pertama: menentukan karakter apa yang dimasukkan. Tumpukan terlihat seperti ini:
[..., prev-char, input, 0]
.Untuk membandingkan input, kami menggunakan kode karakter
h
lagi. Awalnya, ini karena saya tidak benar-benar tahu bagaimana saya akan menangani ini danh
merupakan karakter pertama dalam string yang diperiksa, tetapi akhirnya menjadi cukup nyaman. Jika kita mengurangi kode karakter h dari input, kita dapatkan-3
jika inputnya adalahe
,0
jika inputnya adalahh
,4
jika inputnya adalahl
dan7
jika inputnya adalaho
.Ini berguna, karena
?
perintah tersebut memungkinkan kita dengan mudah memisahkan nilai negatif dari nilai positif dan nol. Dengan demikian, jika IP belok kiri, perbedaannya negatif, jadi inputnya adalahe
, jadi karakter selanjutnya harus menjadil
. Jika IP terus berjalan lurus, perbedaannya adalah0
, jadi inputnya adalahh
, jadi karakter selanjutnya harus menjadie
. Jika inputnya adalah anl
atau ano
, IP berbelok ke kanan.Semua instruksi yang dijalankan sebelum tanda tanya tersebut adalah:
Sekarang IP mengubah arahnya seperti yang dijelaskan di atas. Mari kita membahas berbagai kemungkinan yang berbeda.
Memasukkan
'e'
Pertama kita akan mempertimbangkan input
e
, yang menyebabkan IP bergerak ke atas dari?
, karena perbedaannya adalah 3. Semua karakter yang tidak relevan telah dihapus dari kubus.Karakter dieksekusi dalam urutan ini (tidak termasuk beberapa karakter aliran kontrol):
Sekarang IP telah mencapai loop baca / tulis lagi.
Memasukkan
'h'
Jika inputnya adalah
'h'
, selisihnya adalah 0, sehingga IP tidak mengubah arahnya. Inilah kubusnya lagi, dengan semua karakter yang tidak relevan dihapus. Karena jalur ini mencakup beberapa no-ops, semua no-ops yang dilaluinya telah diganti oleh&
. IP dimulai pada tanda tanya.Instruksi yang dijalankan adalah:
Dan sekarang kita memasuki loop baca / tulis lagi, jadi kita selesai.
Masukan lainnya
Semua input lainnya menghasilkan perbedaan positif, sehingga IP berbelok ke kanan pada tanda tanya. Kita masih perlu memisahkan
l
dano
, jadi itulah yang akan kita lakukan selanjutnya.Memisahkan
'l'
dan'o'
Perlu diingat bahwa perbedaannya adalah 7 untuk
o
dan 4 untukl
dan bahwa kita harus mengakhiri program jika inputnya adalaho
. Inilah kubus lagi dengan bagian-bagian yang tidak relevan digantikan oleh a.
dan no-ops IP crosses telah digantikan oleh ampersand.Membedakan antara dua
'l'
sJadi, sekarang kita sudah tahu inputnya adalah
l
, tetapi kita tidak tahu yang manal
. Jika ini yang pertama, kita perlu mendorong yang lainl
ke bagian bawah tumpukan, tetapi jika yang kedua, kita perlu mendorongo
. Ingat kami menyimpan-3
ke bagian bawah tumpukan tepat sebelum kami mendorong yang pertamal
? Kita dapat menggunakannya untuk memisahkan dua cabang.Tumpukan dimulai sebagai
[..., -3 or 140, ...]
Pertama
'l'
Jika ini yang pertama
'l'
, kita perlu mendorong yang lain'l'
. Untuk menyimpan byte, kami menggunakan karakter yang sama dengan yang pertama'l'
. Kami dapat menyederhanakan tumpukan menjadi[...]
. Inilah bagian yang relevan dari kubus, dengan no-op digantikan oleh ampersand.Instruksi berikut dijalankan:
Kami akan memasuki loop baca / tulis, jadi kami selesai dengan cabang ini.
Kedua
'l'
Jika input adalah yang kedua
'l'
dalam'hello'
, IP berbelok ke kanan di tanda tanya. Sekali lagi, kita dapat menyederhanakan tumpukan[...]
dan IP mulai?
, menunjuk ke selatan saat ini.Instruksi yang dijalankan adalah:
Dan IP akan memasuki loop baca / tulis lagi, jadi kita sudah selesai dengan cabang ini juga.
sumber
C ++,
142141 byteCobalah online!
sumber
#import
di program GCC C ++ ...#import
adalah ekstensi GCC yang sudah tidak digunakan lagi.Node, 124 byte
Tidak berasumsi bahwa streaming akan sesuai dengan memori yang tersedia.
sumber
C #, 134 byte
Cobalah secara Online
Membaca karakter, memeriksa bukan -1 (EOS) dan kami belum melihat "halo", kemudian menambahkannya ke string, dan menulis karakter keluar. Kami menambahkan karena
s[0]
jauh lebih pendek daripada(char)s
. Ini memiliki biaya kuadrat dalam panjang string, karena harus mengalokasikan dan memindai seluruh input setiap kali membaca karakter (ini akan macet setelah input 2GB karena kendala dalam CLR, apakah itu diperbolehkan?)Untuk versi (lebih lama: 142 byte) yang tidak kehabisan memori, dan yang memiliki biaya per karakter konstan, lihat di bawah:
Yang ini menyimpan 5 karakter terakhir dalam string 5-panjang, yang berarti perbandingan singkat, dan pencarian char terakhir murah, tetapi jauh lebih mahal untuk diperbarui.
sumber
PHP,
57 5553 bytekarena tidak ada file tanpa batas, saya mengambil input dari STDIN. Jalankan dengan
-nr
.Ulangi input, cetak karakter saat ini, tambahkan ke
$s
, potong$s
hingga 5 karakter terakhir. Istirahat lingkaran saat$s
inihello
.sumber
Vim, 39 byte
Cobalah online!
sumber
PowerShell, 111 byte
Mungkin ada cara yang lebih baik untuk melakukan ini, tetapi saya tidak bisa melihatnya saat ini.
Ini membaca sapuan kunci tanpa menekan gema. Karakter ditambahkan ke $ x yang dipangkas menjadi 5 karakter terakhir dan dibandingkan dengan "halo". Ini berlanjut sampai perbandingan benar.
Catatan: ini tidak berfungsi di PowerShell ISE. ReadKey dinonaktifkan di lingkungan itu.
sumber
Skema 115 byte
Versi yang dapat dibaca:
Ini mengambil arang individu dari stdin setiap kali di sekitar loop, dan menandai posisinya pada kata target karena memenuhi karakter "halo".
Berhenti ketika input habis atau "halo" telah terlihat. Tidak ada memori yang digunakan pada aliran infinite.
sumber
AWK, 95 byte
Ada 2 hal yang saya pelajari di sini:
1) Untuk membagi catatan antara penggunaan karakter
RS="(.)"
dan kemudianRT
harus digunakan, bukan$1
2)
ORS
digunakan olehprint
dan default ke"\n"
3) Saya tidak dapat menghitung ke 2 dan menggunakan
printf
"lebih murah" daripada menetapkanORS
dan menggunakanprint
Contoh penggunaan: Tempatkan kode dalam FILE
atau
Kode diuji menggunakan
yes | ...
saran Dennis dan saya melihat banyak sekaliy
.FYI, Anda dapat melakukan tugas RS sebagai opsi dan menariknya keluar dari
BEGIN
blok melalui:sumber
BEGIN{RS="(.)"}{printf RT}"olleh"==a=RT substr(a,1,4){exit}
.Python 3 (Linux),
7372 byteTerima kasih kepada @MitchSchwartz karena bermain golf 1 byte!
Cobalah online!
sumber
while
mengevaluasi dengan benar? Sepertinya Anda membandingkan boolean dengan string kosong.s[print(end=c):4]
menghemat satu byte'olleh'!=s and s>''and''<c)
. Tes tengah tidak diperlukan, tetapi merantai mereka lebih pendek daripada langsung'olleh'!=s and''<c
.8086 kode mesin, 22 byte
Kode perakitan yang setara:
sumber
Pyth,
4947 bytePyth tidak pandai mengambil satu karakter input. Semuanya ada di
$__import__("sys").stdin.read(1)
hanya melakukan itu. Juga, ini berarti ini hanya berjalan offline.Yang lainnya pendek ...
Program ini adalah loop sementara tanpa tubuh. Di dalam kondisi tersebut, program membaca karakter, mencetaknya kembali, menambahkan karakter itu ke
k
(yang awalnya string kosong), memotong semua kecuali 5 karakter terakhirk
, dan kemudian memeriksa bahwa hasilnya tidak"hello"
.32 karakter mendapatkan satu byte input, 15 karakter sisanya.
Diuji di Linux, bekerja bahkan tanpa baris baru, masukan tanpa batas, dll.
sumber
Lua,
6864 bytesumber
l:sub(-4)
, maka Anda dapat mengurangi inisialisasil=""
.Ruby,
59494843 byteSekarang bebas kata-kata kasar, lebih pendek, dan tanpa kebocoran memori.
Disimpan 5 byte dengan menghilangkan beberapa tanda kurung dan ruang berkat Dennis
sumber
Röda ,
4947 byteCobalah online!
Ini adalah fungsi anonim yang membaca karakter dari aliran inputnya dan mengeluarkannya sampai "halo" ditemukan. Menggunakan array
a
untuk melacak karakter terakhir.Ini mengeluarkan beberapa sampah ke STDERR, tapi saya mengerti bahwa itu diperbolehkan .
Penjelasan:
sumber
Java 7,
122118124123150141 byteSekarang berhenti ketika ujung aliran tercapai. Sekarang menangani input tanpa batas tanpa kehabisan memori.
sumber
write
sedang digunakanprint
. Saya tidak bisa membatalkan downvote saya, maaf untuk itu :(Ruby, 51 byte
sumber
AHK , 116 byte
Tidak ada yang pintar atau magis di sana, sungguh. Variabel
%1%
adalah argumen yang diteruskan pertama dan harus menjadi jalur file dengan aliran. File harus disimpan saat diperbarui tetapi kode akan membaca sampai akhir bahkan jika diperluas setelah pembacaan dimulai.sumber
Mathematica, 107 byte
Output menjadi bidang di mana pengguna dapat mengetik teks tanpa batas (termasuk baris baru) hingga 5 karakter terakhir sama dengan
"hello"
; pada saat itu, ia keluar.sumber
brainfuck , 281 byte
Saya tidak yakin mengapa, tapi saya merasa brainfuck adalah hal yang tepat untuk melakukan ini. Tidak memerlukan memori yang tak terbatas, dan dapat menghasilkan selamanya.
Dijelaskan
Cobalah online!
sumber
ahehellob
.