Bahasa pemrograman pertama yang saya kenal adalah Sinclair BASIC . Seperti banyak dialek BASIC, semua baris kode sumber harus diberi nomor .
Akibatnya, penggunaan GO TO
perintah itu idiomatis dan melompat eksekusi ke nomor baris yang diberikan (tidak ada label).
Juga ada GO SUB
perintah terkait yang dapat digunakan sebagai panggilan fungsi yang belum sempurna. Sekali lagi, eksekusi melompat ke nomor baris yang diberikan, tetapi ketika aRETURN
perintah tercapai, eksekusi melompat kembali ke instruksi berikutnya setelah GO SUB
.
Demikian pula dengan RUN
perintah akan memulai kembali eksekusi program pada baris yang diberikan.
Siapa pun yang telah menghabiskan waktu dalam juru bahasa BASIC bernomor garis akan belajar menggunakan skema penomoran dengan celah di dalamnya. Ini agar lebih mudah untuk menyisipkan baris kode baru. Namun demikian, Anda mungkin masih perlu memasukkan garis baru di antara garis yang diberi nomor secara berurutan.
Diberikan daftar BASIC bernomor garis sebagai input, output program yang sama tetapi dinomori ulang sehingga nomor baris mulai dari 10 dan bertambah dengan langkah 10. Daftar input mungkin memiliki GO TO
atau GO SUB
perintah, sehingga angka yang terkait dengan ini juga harus disesuaikan.
GO TO
danGO SUB
perintah ada di baris mereka sendiri atau di ujungIF
THEN
baris. Aman untuk dikatakan^(\d+) .*GO (TO|SUB) (\d+)$
sudah cukup untuk mencocokkan garis tersebut. Perintah dalam tanda kutip ini harus diabaikan.RUN
perintah akan selalu berada di jalur mereka sendiri. Dalam hal ini nomor baris adalah opsional. Jika tidak ada, maka juru bahasa hanya memulai di bagian atas program.Jika a
GO TO
,GO SUB
atauRUN
perintah mereferensikan baris yang tidak ada, maka ia akan melompat ke baris yang didefinisikan berikutnya. Entri Anda harus berurusan dengan ini dan memastikan referensi garis tersebut diperbaiki sehingga mengarah ke baris yang benar. Perilaku mungkin tidak terdefinisi jika nomor baris setelah akhir program diberikan dalam salah satu dari perintah ini.Nomor baris akan selalu berupa bilangan bulat positif 1 hingga 9999 (sesuai manual). Ini berarti bahwa program input tidak akan pernah memiliki lebih dari 999 baris.
Baris input akan selalu diberi nomor dalam urutan menaik secara numerik.
Untuk keperluan tantangan ini, daftar masukan hanya akan berisi ASCII yang dapat dicetak. Anda tidak perlu khawatir tentang set karakter ZX. Karena itu, jika entri Anda sebenarnya ditulis dalam ZX BASIC atau kode perakitan / mesin z80 yang sesuai (dan ada emulator di luar sana ), maka Anda dapat memilih input Anda untuk dikodekan dalam set karakter ZX sebagai gantinya.
Anda tidak boleh menggunakan perpustakaan atau utilitas nomor baru yang khusus dirancang untuk tujuan ini.
Input Contoh:
1 REM "A rearranged guessing game"
2 INPUT A: CLS
3 INPUT "Guess the number ", B
10 IF A=B THEN PRINT "Correct": STOP
100 IF A<B THEN GO SUB 125
120 IF A>B THEN GO SUB 122
121 GO TO 3
125 PRINT "Try again"
126 RETURN
127 REM "An example of GO TO 7 and GO SUB 13 in quotes"
Contoh Output:
10 REM "A rearranged guessing game"
20 INPUT A: CLS
30 INPUT "Guess the number ", B
40 IF A=B THEN PRINT "Correct": STOP
50 IF A<B THEN GO SUB 80
60 IF A>B THEN GO SUB 80
70 GO TO 30
80 PRINT "Try again"
90 RETURN
100 REM "An example of GO TO 7 and GO SUB 13 in quotes"
Saya ingin menautkan ke manual ZX BASIC. Yang terbaik yang bisa saya temukan tampaknya adalah http://www.worldofspectrum.org/ZXBasicManual/index.html tetapi ini tampaknya merupakan tautan mati. Mesin wayback memiliki salinan .
GOTO 100 + A*10
, dan Lampiran C dari ZX Spectrum Pedoman daftarGO TO
sebagai menerima ekspresi numerik (tidak ada pembatasan untuk konstanta). Berikut ini adalah diskusi tentang manfaat yang dihitungGOTO
pada ZX80 dan ZX81. BTW, saya tidak tahu mengapa ruang ditambahkan dalam versi Spectrum.Jawaban:
JavaScript (ES6) 177
Edit Menambahkan pemindaian (mahal) untuk nomor baris yang valid berikutnya
UJI
sumber
Perl 6,
147145144142 byteIni mungkin bisa diturunkan sedikit lebih.
Diperluas
sumber
.min
. gunakan{min %line-map.keys».Num.grep:*>=$1
sebagai gantinyaVisual Basic for Applications, 288 byte
Saya tidak bisa menolak memberikan solusi dalam dialek BASIC. Mungkin berfungsi dengan Visual Basic 6 / .NET atau varian modern lainnya dengan perubahan kecil.
Saya menggunakan banyak variabel satu huruf untuk keringkasan. Juga, saya menekan semua spasi putih yang tidak perlu (VBE memperluasnya secara otomatis saat impor). Hitungan byte untuk file .BAS final, dengan CHR (10) sebagai baris baru.
Subrutin, yang dapat dipanggil dari jendela langsung VBE, membuka program Sinclair BASIC (parameter pertama adalah path ke file ASCII - dengan CHR (10) sebagai baris baru - yang berisi program), memberi nomor baru baris dan menulis hasil ke variabel Variant (parameter kedua).
Idenya adalah untuk beralih pada semua nomor baris sumber yang mungkin, urutan naik, dan untuk masing-masing, ganti sekaligus semua nomor baris yang cocok juga
GO TO
,GO SUB
danRUN
referensi dengan nomor baris target berikutnya yang tersedia. Dengan menggunakan pendekatan ini kita tidak perlu tabel terjemahan apa pun. Nomor baris target bertambah setiap kali ditemukan kecocokan dalam nomor baris sumber, sehingga referensi baris "salah" disesuaikan secara otomatis ke nomor valid berikutnya. Karakter baris baru digunakan sebagai penanda awal dan akhir garis, dan CHR (0) - tidak pernah digunakan dalam program karena tidak dapat dicetak - digunakan sebagai penanda sementara, untuk menghindari pemberian nomor baru pada baris yang sama beberapa kali.Beberapa komentar:
Untuk keringkasan, kami menggunakan string yang lebih kecil untuk pertandingan dengan pernyataan melompat. Menggunakan end-of-line pada string pencarian kami, kami tidak mengalami risiko memasukkan kejadian-kejadian yang dikutip atau fungsi pengguna (yang selalu menggunakan tanda kurung di Sinclair).
GO TO
membutuhkan string yang lebih besar karenaFOR ... TO
konstruknya (mis. bandingkan50 FOR X=AGO TO 100
dan50 GO TO 100
)Kode tidak mendukung pernyataan dalam bentuk
GO TO200
(tanpa spasi), meskipun manual ZX menyiratkan bahwa itu adalah kode yang valid pada beberapa contoh (Akan membutuhkan selusin byte lebih banyak untuk menghadapinya).Kode menambahkan baris baru di awal dan lainnya di akhir program. Saya bisa membersihkan ini pada akhirnya (selusin byte lebih) tetapi angka bahwa ZX mungkin akan mengabaikan garis kosong.
Di bawah, versi yang lebih mudah dibaca:
sumber
Pip
-rn
, 63 byteCobalah online!
Penjelasan
Mempersiapkan
The
-r
Bendera membaca semua stdin dan menyimpannya sebagai daftar baris dalam variabel lokalg
. Variabel globalt
diinisialisasi menjadi 10, dan variabel globals
diinisialisasi ke" "
.Tarik daftar baris
g
ke dalam variabel globaly
, sehingga tersedia di dalam fungsi yang akan kita definisikan.Fungsi terjemahan nomor baris
Kami membangun fungsi yang memetakan dari nomor baris apa pun dalam skema penomoran asli (termasuk yang tidak ada) ke nomor baris yang sesuai dalam skema penomoran yang baru.
Misalkan kita memiliki garis-garis ini:
Kami ingin memetakan 1 hingga 10, 2-4 hingga 20, dan 5-9 hingga 30. Jika kami memiliki daftar nomor baris asli (
[1; 4; 9]
), kami dapat menggunakan operasi filter untuk mengetahui berapa banyak dari angka-angka ini yang kurang daripada nomor baris yang kami coba konversi. Lipat gandakan hasilnya dengan 10 dan tambahkan 10, dan kami memiliki jawaban yang diinginkan.Misalnya, saat mengonversi 9, ada dua nomor baris (1 dan 4) kurang dari 9. 2 * 10 + 10 memberi 30. Saat mengonversi 3, ada satu nomor baris (1) kurang dari 3. 1 * 10 + 10 memberi 20.
Berikut kodenya (sedikit dimodifikasi agar lebih mudah dibaca):
Pengganti Pertama:
GO TO
,GO SUB
, danRUN
Sisa dari program ini adalah ekspresi tunggal yang mengambil
g
dan melakukan beberapa penggantian regex (yang membuat vektor, berlaku untuk setiap baris dalamg
).Inilah penggantian pertama:
Regex cocok dengan salah satu dari
RUN
,GO SUB
danGO TO
, diikuti oleh angka, diikuti oleh akhir baris. Ini memastikan tidak cocok dengan string dalam, juga tidak cocokRUN
tanpa nomor baris.Urutan kelompok penangkap penting. Kelompok pertama menangkap perintah (salah
RUN
,GO SUB
atauGO TO
). Grup kedua, jika digunakan, menangkap salah satuSUB
atauTO
. Kami tidak perlu menangkap bagian ini, tetapi grup yang tidak menangkap akan membutuhkan byte tambahan. Kemudian kelompok ketiga menangkap nomor baris.Kami menggunakan fungsi panggilan balik untuk penggantian. Dengan fungsi callback di Pip, seluruh pertandingan adalah argumen pertama
a
, dan kelompok-kelompok capture agar adalah argumen berikutnyab
,c
,d
, dane
. Jadi kita memiliki perintah di grup pertama, yang masukb
, dan nomor baris di grup ketiga, yang masukd
. Satu-satunya perubahan yang kita butuhkan untuk membuat adalah untuk lulus nomor baris melalui fungsi konversi kami, yang disebut Lisp gaya:(nd)
. Kemudian kami menggabungkannya bersamab
dan spasi dan mengembalikannya.Penggantian kedua: nomor baris
Yang tersisa untuk dikonversi adalah nomor baris di awal baris.
Regex cocok dengan angka di awal garis. Sekali lagi kami menggunakan fungsi callback; kali ini, fungsi konversi
n
itu sendiri sudah cukup, karena seluruh kecocokan (argumen pertama,a
) adalah angka yang ingin kita konversi.Karena ini adalah ekspresi terakhir dalam program, Pip mencetak ulang hasilnya. The
-n
bendera memisahkan daftar hasil dengan baris baru.sumber