Saya ingin mencoba jenis baru tantangan golf regex, yang meminta Anda untuk menyelesaikan tugas komputasi nontrivial dengan apa pun selain penggantian regex. Untuk membuat ini lebih mungkin dan lebih sedikit dari tugas, Anda akan diizinkan untuk menerapkan beberapa pergantian, satu demi satu.
Tantangan
Kami akan mulai dengan sederhana: diberi string yang berisi dua bilangan bulat positif, sebagai angka desimal dipisahkan oleh a ,
, menghasilkan string yang berisi jumlah mereka, juga sebagai angka desimal. Jadi, sangat sederhana
47,987
harus berubah menjadi
1034
Jawaban Anda harus bekerja untuk bilangan bulat positif sewenang-wenang.
Format
Setiap jawaban harus merupakan urutan langkah substitusi, setiap langkah yang terdiri dari regex dan string pengganti. Secara opsional, untuk masing-masing langkah dalam urutan, Anda dapat memilih untuk mengulangi substitusi hingga string berhenti berubah. Ini adalah contoh pengiriman (yang tidak menyelesaikan masalah di atas):
Regex Modifiers Replacement Repeat?
\b(\d) g |$1 No
|\d <none> 1| Yes
\D g <empty> No
Diberikan input 123,456
, pengajuan ini akan memproses input sebagai berikut: substitusi pertama diterapkan sekali dan menghasilkan:
|123,|456
Sekarang substitusi kedua diterapkan dalam satu lingkaran sampai string berhenti berubah:
1|23,|456
11|3,|456
111|,|456
111|,1|56
111|,11|6
111|,111|
Dan terakhir, substitusi ketiga diterapkan sekali:
111111
Perhatikan bahwa kriteria terminasi untuk loop adalah apakah string berubah, bukan apakah regex menemukan kecocokan. (Yaitu, itu mungkin juga berakhir jika Anda menemukan kecocokan tetapi penggantinya identik dengan kecocokan.)
Mencetak gol
Skor utama Anda akan menjadi jumlah langkah substitusi dalam kiriman Anda. Setiap penggantian yang berulang akan dihitung untuk 10 langkah. Jadi contoh di atas akan memberi skor 1 + 10 + 1 = 12
.
Dalam kasus seri (tidak terlalu tidak mungkin), skor sekunder adalah jumlah dari semua langkah. Untuk setiap langkah tambahkan regex ( tanpa pembatas), pengubah dan string substitusi. Untuk contoh di atas ini akan menjadi (6 + 1 + 3) + (3 + 0 + 2) + (2 + 1 + 0) = 18
.
Aturan Lain-lain
Anda dapat menggunakan rasa regex (yang harus Anda tunjukkan), tetapi semua langkah harus menggunakan rasa yang sama. Selain itu, Anda tidak boleh menggunakan fitur apa pun dari bahasa host flavour, seperti callback pengganti atau e
pengubah Perl , yang mengevaluasi kode Perl. Semua manipulasi harus terjadi secara eksklusif melalui penggantian regex.
Perhatikan bahwa itu tergantung pada rasa dan pengubah Anda apakah setiap penggantian tunggal menggantikan semua kejadian atau hanya satu saja. Misalnya jika Anda memilih aroma ECMAScript, satu langkah secara default hanya akan menggantikan satu kejadian, kecuali jika Anda menggunakan g
pengubah. Di sisi lain, jika Anda menggunakan .NET flavor, setiap langkah akan selalu menggantikan semua kejadian.
Untuk bahasa yang memiliki metode substitusi berbeda untuk penggantian tunggal dan global (mis. Ruby sub
vs. gsub
), asumsikan bahwa penggantian tunggal adalah default dan memperlakukan penggantian global seperti g
pengubah.
Pengujian
Jika rasa yang Anda pilih adalah .NET atau ECMAScript, Anda dapat menggunakan Retina untuk menguji kiriman Anda (saya diberitahu, ini juga berfungsi pada Mono). Untuk rasa lain, Anda mungkin harus menulis sebuah program kecil dalam bahasa host yang menggunakan substitusi secara berurutan. Jika ya, harap sertakan program pengujian ini dalam jawaban Anda.
sumber
Jawaban:
.NET flavor, skor: 2
Saya belum terganggu untuk golf itu, dan
x
hanya untuk mengabaikan ruang putih.Pertama-tama masukkan
9876543210
di setiap posisi, lalu hapus karakter asli dan karakter yang bukan digit jumlah saat ini.Regex besar (1346 bytes tanpa spasi putih dan komentar):
Ini membuat saya berpikir tentang tingkat akhir Manufactoria ... Tapi saya pikir .NET regex, yang jelas tidak lagi "biasa", dapat menyelesaikan masalah dalam PH. Dan ini hanya sebuah algoritma dalam L.
sumber
Nilai: 24
Saya pikir ini bekerja ...
Saya belum menghabiskan banyak waktu bermain golf dengan ekspresi reguler individu. Saya akan mencoba memposting penjelasan segera, tetapi sudah terlambat sekarang. Sementara itu, inilah hasil antara setiap langkah:
Program perl penuh:
sumber
Setiap rasa regex, 41
Mari kita coba unary.
d
berfungsi untuk pemisah urutan digit,x
menyimpan nilai. Pertama kita menghapus setiap digit, kemudian kita menekan pengali x10 ke kiri, lalu jatuhkan semua pemisah, lalu masukkan kembali pengali, lalu konversikan setiap urutan kembali ke angka.sumber
.NET Regex, 14
Tidak sebagus solusi user23013, tapi itu menyenangkan. Tidak ada pengganti yang memiliki pengubah.
Alasan untuk. NET regex bukan karena menyeimbangkan kelompok untuk sekali - saya baru saja menguji dengan Retina , yang menggunakan .NET, dan saya juga menemukan bahwa panjang variabel terlihat sangat membantu.
Penggantian 1 (ulangi = tidak)
Regex:
Penggantian
Tukar dua angka, padding untuk memiliki angka nol terkemuka yang sama.
Penggantian 2 (ulangi = tidak)
Regex:
Penggantian:
Tambahkan spasi sebelum setiap nomor
Penggantian 3 (ulangi = tidak)
Penggantian:
Tambahkan carry bit (the
&0
) serta tabel pencarian raksasa<c> <a> <b> <carry of a+b+c> <last digit of a+b+c>
.Penggantian 4 (ulangi = ya)
Regex:
Penggantian:
Terus ambil digit terakhir dari setiap angka, dan temukan (jumlah, bawa). Masukkan jumlah pada awal string dan ganti carry.
Penggantian 5 (ulangi = tidak)
Regex:
Penggantian:
Membersihkan.
Contoh dijalankan
(Dengan menggabungkan beberapa langkah saya bisa mendapatkan 12, tetapi karena itu menjadi sangat berantakan dan tidak akan menang, saya pikir saya akan terus versi yang lebih elegan ini.)
sumber
Nilai:
50403121Terima kasih atas tantangan luar biasa ini. Solusi ini tidak terlalu elegan, tetapi, mengingat batasannya, saya tidak bisa melihat cara untuk menangani angka secara umum di output.
Solusi ini menampilkan grup tangkap yang terkadang tidak cocok dan mengandalkan mereka yang kosong ketika itu terjadi. Ini berfungsi di Perl, meskipun biasanya menghasilkan peringatan.
Contoh kode Perl lengkap, dengan penjelasan dan pencetakan hasil antara:
Pembaruan: Saya dapat menggabungkan dua regex pengulangan bersama, menghemat 10.
Pembaruan 2: Saya berhasil memecahkan konversi digit input dengan regex tunggal.
Pembaruan 3: Saya dikurangi menjadi regex perulangan tunggal.
sumber
${1}
berbeda dari$1
? Juga, Anda mungkin ingin memasukkan jumlah byte jika ada hubungan.\1
, dll, sebagai gantinya, menyimpan beberapa karakter.