Situs ini memiliki banyak masalah yang melibatkan penerapan berbagai bahasa dalam tag interpreter . Namun, praktis semua dari mereka adalah bahasa esoterik yang tidak ada yang menggunakan. Saatnya membuat penerjemah untuk bahasa praktis yang mungkin sudah diketahui sebagian besar pengguna di sini. Ya, ini skrip shell, jika Anda memiliki masalah dalam membaca judul (bukan yang Anda miliki). (ya, saya sengaja membuat tantangan ini, karena saya bosan dengan bahasa seperti GolfScript dan Befunge memenangkan segalanya, jadi saya menaruh beberapa tantangan di mana bahasa pemrograman yang lebih praktis memiliki peluang lebih besar untuk menang)
Namun, skrip shell adalah bahasa yang relatif besar, jadi saya tidak akan meminta Anda untuk mengimplementasikannya. Sebagai gantinya, saya akan membuat sebagian kecil dari fungsionalitas skrip shell.
Subset yang saya putuskan adalah subset berikut:
- Akan tetapi, program yang dijalankan (program hanya akan berisi huruf, bahkan jika tanda kutip tunggal diizinkan)
- Argumen program
- Kutipan tunggal (menerima karakter ASCII yang dapat dicetak, termasuk spasi putih, tidak termasuk kutipan tunggal)
- String yang tidak dikutip (memungkinkan huruf, angka, dan tanda hubung ASCII)
- Pipa
- Pernyataan kosong
- Beberapa pernyataan dipisahkan oleh baris baru
- Mengejar / memimpin / banyak ruang
Dalam tugas ini, Anda harus membaca input dari STDIN, dan menjalankan setiap perintah yang diminta. Anda dapat dengan aman menggunakan sistem operasi yang kompatibel dengan POSIX, jadi tidak perlu portabilitas dengan Windows, atau yang seperti itu. Anda dapat dengan aman berasumsi bahwa program yang tidak disalurkan ke program lain tidak akan membaca dari STDIN. Anda dapat dengan aman berasumsi bahwa perintah akan ada. Anda dapat dengan aman berasumsi bahwa tidak ada lagi yang akan digunakan. Jika beberapa asumsi yang aman rusak, Anda dapat melakukan apa saja. Anda dapat dengan aman mengasumsikan paling banyak 15 argumen, dan baris di bawah 512 karakter (jika Anda membutuhkan alokasi memori eksplisit, atau sesuatu - Saya benar-benar akan memberikan peluang kecil untuk menang untuk C, bahkan jika mereka masih kecil). Anda tidak perlu membersihkan deskriptor file.
Anda diizinkan untuk menjalankan program kapan saja - bahkan setelah menerima baris penuh, atau setelah STDIN berakhir. Pilih pendekatan yang Anda inginkan.
Testcase sederhana yang memungkinkan Anda menguji shell Anda (perhatikan spasi kosong setelah perintah ketiga):
echo hello world
printf '%08X\n' 1234567890
'echo' 'Hello, world!'
echo heeeeeeelllo | sed 's/\(.\)\1\+/\1/g'
yes|head -3
echo '\\'
echo 'foo bar baz' | sed 's/bar/BAR/' | sed 's/baz/zap/'
Program di atas akan menampilkan hasil sebagai berikut:
hello world
499602D2
Hello, world!
helo
y
y
y
\\
foo BAR zap
Anda tidak diizinkan untuk mengeksekusi shell itu sendiri, kecuali jika Anda tidak memiliki argumen untuk perintah (pengecualian ini dibuat untuk Perl, yang menjalankan perintah di shell ketika mengajukan argumen saja system
, tetapi jangan ragu untuk menggunakan pengecualian ini untuk yang lain bahasa juga, jika Anda bisa melakukannya dengan cara yang menghemat karakter), atau perintah yang Anda jalankan adalah shell itu sendiri. Ini mungkin masalah terbesar dalam tantangan ini, karena banyak bahasa memiliki system
fungsi yang mengeksekusi shell. Alih-alih menggunakan API bahasa yang memanggil program secara langsung, seperti subprocess
modul dengan Python. Bagaimanapun, ini adalah ide yang bagus untuk keamanan, dan Anda tidak ingin membuat shell yang tidak aman, bukan? Ini kemungkinan besar menghentikan PHP, tetapi ada bahasa lain yang harus dipilih.
Jika Anda akan membuat program anda dalam shell script, Anda tidak diizinkan untuk menggunakan eval
, source
atau .
(seperti dalam, fungsi, bukan karakter). Itu akan membuat tantangannya terlalu mudah menurut saya.
Pelanggaran aturan pintar diizinkan. Ada banyak hal yang secara eksplisit saya tolak, tetapi saya hampir yakin bahwa Anda masih diperbolehkan melakukan hal-hal yang belum saya lakukan. Terkadang saya terkejut tentang bagaimana orang menafsirkan aturan saya. Juga, ingatlah bahwa Anda dapat melakukan apa saja untuk apa pun yang belum saya sebutkan. Misalnya, jika saya mencoba menggunakan variabel, Anda dapat menghapus hard disk (tapi tolong jangan).
Kode terpendek menang, karena ini adalah codegolf.
sumber
Jawaban:
Bash (92 byte)
Memanfaatkan celah yang sama dengan jawaban ini , berikut adalah solusi yang jauh lebih pendek:
Python (
247241239 bytes)sumber
*
), tetapi selain itu, ini terlihat hebat :-). Saya terkejut bahwa anggota baru membuat solusi yang bagus untuk masalah yang sulit.C (340 byte)
Saya tidak punya pengalaman sama sekali dalam bermain golf, tetapi Anda harus mulai dari suatu tempat, jadi begini:
Saya menambahkan jeda baris sehingga Anda tidak perlu menggulir, tetapi tidak memasukkannya dalam hitungan saya karena tidak memiliki arti semantik. Mereka setelah arahan preprosesor diperlukan dan dihitung.
Versi tidak disatukan
fitur
'ec'ho He'll''o 'world
pekerjaan sebagaimana mestinya. Mungkin saja kodenya akan lebih sederhana tanpa fitur ini, jadi saya akan menerima klarifikasi apakah ini diperlukan.Masalah yang diketahui
execvp
panggilan gagal, misalnya karena nama program salah ketik. Lalu kami memiliki dua proses bermain menjadi shell secara bersamaan.Karakter khusus '|' dan line break mempertahankan makna khusus mereka di dalam string yang dikutip. Ini melanggar persyaratan, jadi saya sedang menyelidiki cara untuk memperbaikinya.Diperbaiki, dengan biaya sekitar 11 byte.Catatan lain
echo 'foo bar baz' | sed 's/bar/BAR/' | sed 's/baz/zap/'
hang. Masalahnya tampaknya adalah pipa tulis yang tidak tertutup, jadi saya harus menambahkan perintah tutup, yang meningkatkan ukuran kode saya sebesar 10 byte. Mungkin ada sistem di mana situasi ini tidak muncul, jadi kode saya mungkin dinilai dengan 10 byte lebih sedikit. Saya tidak tahu?:
dapat disarangkan,
tanpa(…)
.sumber
int c, m, f[3];
luarmain
, untuk menghindari menyatakan jenis. Untuk variabel global, Anda tidak perlu mendeklarasikanint
. Namun umumnya, solusi menarik.yes|head -3
terus berjalan selamanya dan shell keluar setelah setiap perintah. Saya menggunakan versi gcc 4.6.3 (Ubuntu / Linaro 4.6.3-1ubuntu5) tanpa switch.#define B break;case
(break;
sebelumdefault
menjadi)B-1:
) dan 2 dengan mengganticase'\n'
dancase'\''
) dengancase 10
dancase 39
.bash (+ layar) 160
Akan menampilkan sesuatu seperti:
sumber
Faktor (208 karakter)
Karena aturan tidak melarang pembongkaran pekerjaan ke pihak ketiga ( http://www.compileonline.com/execute_bash_online.php ), berikut ini solusinya:
Anda dapat menulis program ini sebagai one-liner yang lebih pendek di repl juga ( 201 karakter):
sumber
Perl, 135 karakter
Shell ini melakukan beberapa hal bodoh. Mulai shell interaktif dengan
perl shell.pl
dan coba:ls
dicetak dalam satu kolom, karena output standar bukan terminal. Shell mengalihkan output standar ke pipa dan membaca dari pipa.perl -E 'say "hi"; sleep 1'
menunggu 1 detik untuk menyapa, karena shell menunda output.dd
membaca 0 byte, kecuali itu adalah perintah pertama ke shell ini. Shell mengalihkan input standar dari pipa kosong, untuk setiap pipa setelah yang pertama.perl -e '$0 = screamer; print "A" x 1000000' | dd of=/dev/null
berhasil diselesaikan.perl -e '$0 = screamer; print "A" x 1000000' | cat | dd of=/dev/null
hang shell!pkill -f screamer
di shell lain), maka shell melanjutkan.perl -e 'fork and exit; $0 = sleeper; sleep'
hang shell!'echo $((2+3))'
menjalankan perintah di / bin / sh. Ini adalah perilaku eksekutif dan sistem Perl dengan satu argumen, tetapi hanya jika argumen tersebut berisi karakter khusus.Versi tidak disatukan
sumber