sed, 367 (byte kode sumber) + 532 (jumlah batang korek api untuk kode sumber) = 899
s/[^0-9a-jln-suxyz]//Ig;/^$/{s/.*/0/;b};s/.+/&; %1ir %%7lnu %%%4cfhjoy %%%%235bdegpqsxz %%%%%069a %%%%%%8/;:1;s/([^% ])(.+ (%+)[^ ]*\1)/%\3 \2/I;/ ;/!b1;s/;.+//;s/^/,;/;:2;s/(;[^%]*)(%+)/\2\1/;:3;s/,%{10}/%,/;s/^%/,&/;/%{10}/b3;/;.*%/b2;:4;s/,[;,]/,0,/;/,[;,]/b4;s/%{9}/9/g;s/%{8}/8/g;s/%{7}/7/g;s/%{6}/6/g;s/%{5}/5/g;s/%%%%/4/g;s/%%%/3/g;s/%%/2/g;s/%/1/g;s/[^0-9]//g
Cobalah secara Online
Versi multi-baris:
s/[^0-9a-jln-suxyz]//Ig
/^$/{s/.*/0/;b}
s/.+/&; %1ir %%7lnu %%%4cfhjoy %%%%235bdegpqsxz %%%%%069a %%%%%%8/
:1
s/([^% ])(.+ (%+)[^ ]*\1)/%\3 \2/I
/ ;/!b1
s/;.+//
s/^/,;/
:2
s/(;[^%]*)(%+)/\2\1/
:3
s/,%{10}/%,/
s/^%/,&/
/%{10}/b3
/;.*%/b2
:4
s/,[;,]/,0,/
/,[;,]/b4
s/%{9}/9/g
s/%{8}/8/g
s/%{7}/7/g
s/%{6}/6/g
s/%{5}/5/g
s/%%%%/4/g
s/%%%/3/g
s/%%/2/g
s/%/1/g
s/[^0-9]//g
Penjelasan:
Script di atas membaca input standar baris demi baris (ke dalam ruang pola - "cara sed" yang biasa) dan, untuk setiap baris, output jumlah korek api yang diperlukan untuk mewakili semua karakter yang dapat diwakili batang korek api di baris itu. Perhitungan untuk setiap jalur input terjadi sebagai berikut:
s/[^0-9a-jln-suxyz]//Ig
Pertama, kami menghapus setiap karakter yang kami tidak memiliki representasi batang korek api yang sesuai (seperti yang diberikan pada pertanyaan) dari ruang pola. Yaitu, kami menghapus setiap karakter yang bukan merupakan angka dari "0" hingga "9", surat dari "a" ke "j", "n" ke "s", "l", "u", "x", "y" atau "z". Huruf besar dan kecil diperlakukan sama.
/^$/{s/.*/0/;b}
Jika kita berakhir dengan ruang pola kosong, kita mencetak 0 (secara otomatis diikuti oleh baris baru, seperti yang selalu dilakukan kecuali Anda melewati bendera khusus untuk itu), lewati semua garis posterior naskah dan lanjutkan ke "siklus sed" berikutnya ( yaitu, baca baris input berikutnya dan ulangi pemrosesan lagi dari perintah pertama hingga tidak ada lagi baris input yang akan diproses).
s/.+/&; %1ir %%7lnu %%%4cfhjoy %%%%235bdegpqsxz %%%%%069a %%%%%%8/
Jika tidak, jika ruang pola tidak kosong, kami sekarang membaginya menjadi dua "sub-ruang" yang dipisahkan oleh tanda titik koma: pertama muncul ruang input , yang awalnya dibentuk oleh semua karakter yang tidak dihapus dari ruang pola setelah pelaksanaan baris 1; selanjutnya adalah titik koma, dan setelah itu ruang peta .
Ruang peta memberi tahu kami berapa korek api di sebelah 1 yang diperlukan untuk mewakili setiap karakter alfanumerik yang relevan. Jika kami ingin tahu berapa banyak korek api yang diperlukan untuk mewakili karakter alfanumerik di ruang peta, kami mencari urutan pertama dari% yang berdekatan di sebelah kiri karakter itu, dan jawabannya akan menjadi jumlah% di urutan itu ditambah 1. Jadi, misalnya, jumlah korek api yang diperlukan untuk mewakili "b" adalah 4 + 1 = 5; untuk mewakili "4", 3 + 1 = 4, untuk mewakili "y", 3 + 1 = 4; dan seterusnya.
:1
s/([^% ])(.+ (%+)[^ ]*\1)/%\3 \2/I
/ ;/!b1
Ini sebuah loop. Sekarang kita akan mengganti setiap karakter dalam ruang input dengan urutan (lengkap) dari% 's yang jumlahnya menunjukkan jumlah korek api yang diperlukan untuk mewakili karakter itu, dan mengikuti urutan itu dengan karakter spasi putih (sekali lagi, huruf besar dan huruf kecil adalah diberikan perlakuan yang sama). Kriteria untuk menentukan apakah loop harus diakhiri adalah untuk memeriksa apakah ada karakter spasi putih di sebelah kiri langsung titik koma dalam ruang pola: jika kondisi itu berlaku, kami mengakhiri loop dan melanjutkan ke baris berikutnya.
s/;.+//
s/^/,;/
Kedua garis menghapus titik koma dan semuanya setelahnya dari ruang pola dan kemudian memasukkan koma dan titik koma ke awal ruang pola. Kami sekarang memiliki ruang pola dibagi lagi menjadi dua sub-ruang baru: ruang hasil analog sebelum titik koma, dan ruang input analog setelah itu.
Ruang input analog adalah apa yang sebelumnya kita sebut "ruang input", tetapi dalam bentuk yang berbeda: sekarang berisi urutan% yang dipisahkan oleh ruang putih. Jumlah total% seperti itu dalam ruang input analog adalah jumlah korek api yang sama yang diperlukan untuk merepresentasikan string karakter input awal, yaitu angka tersebut adalah hasilnya. Tetapi kita harus mencetak yang menghasilkan notasi desimal, bukan sebagai urutan tanda persen. Tujuan dari ruang hasil analog adalah untuk memegang representasi analog dari setiap digit hasil sementara kami menghitung hasilnya dengan menjumlahkan setiap urutan yang berdekatan dari% di ruang input analog satu per satu. Loop berikutnya melakukan penjumlahan itu:
:2
s/(;[^%]*)(%+)/\2\1/
:3
s/,%{10}/%,/
s/^%/,&/
/%{10}/b3
/;.*%/b2
Pertama, setelah label 2 , kami memindahkan urutan berdekatan berikutnya dari% setelah titik koma dari ruang input analog ke kiri langsung dari titik koma, dalam ruang hasil analog;
Selanjutnya, kami melangkah ke sub-loop (label 3 ) yang melakukan perhitungan berikut:
Jika ada urutan yang berdekatan dari sepuluh% setelah koma di ruang hasil analog, kami menghapus% itu dan menempatkan% tunggal segera di sebelah kiri koma. Sederhananya, ini menunjukkan bahwa salah satu tempat desimal dalam hasil telah memperoleh lebih dari 9 unit, jadi kami mengambil 10 unit dari tempat desimal itu dan menambahkan 1 unit ke tempat desimal yang lebih besar berikutnya;
Jika "%" adalah karakter pertama dalam ruang pola, kami menyisipkan koma baru tepat sebelum itu. Ini menunjukkan bahwa jumlah telah mencapai nilai yang representasi desimalnya memiliki satu tempat desimal lebih di sebelah kiri daripada nilai sebelumnya;
Jika masih ada urutan yang berdekatan dari sepuluh% di ruang hasil analog, kami kembali ke label 3 dan ulangi proses ini. Kalau tidak, kita keluar dari sub-loop ini dan melangkah ke baris berikutnya.
Sekarang, jika masih ada "%" di ruang input analog (yaitu, setelah titik koma), itu berarti bahwa masih ada beberapa jumlah korek api yang akan ditambahkan ke jumlah total - jadi kami kembali ke label 2 .
Setelah penjumlahan selesai, kita masuk ke loop terakhir dari kode:
:4
s/,[;,]/,0,/
/,[;,]/b4
Di sini, kami memeriksa setiap pasangan karakter yang dibentuk oleh koma di sebelah kiri dan baik titik koma atau koma di sebelah kanan. Kami mengganti semua pasangan karakter dengan "0" di dalam dua koma.
s/%{9}/9/g
s/%{8}/8/g
s/%{7}/7/g
s/%{6}/6/g
s/%{5}/5/g
s/%%%%/4/g
s/%%%/3/g
s/%%/2/g
s/%/1/g
Sepotong kode di atas cukup sederhana: kami mengganti setiap urutan berdekatan dari% di ruang hasil analog dengan karakter angka desimal yang sesuai dengan jumlah% di setiap urutan tertentu.
s/[^0-9]//g
Akhirnya, kami menghapus setiap karakter non-angka dari ruang pola dan yang tersisa adalah hasil akhir dalam notasi desimal yang sudah dikenal. Nilai itu dicetak pada output standar dan siklus sed berikutnya dimulai, jika ada lagi jalur input yang akan diproses.
|_\n|_
(huruf kecilt
)