Masalah
Saya memiliki banyak ekspresi reguler yang perlu saya gunakan dalam beberapa kode, tapi saya menggunakan bahasa pemrograman yang tidak mendukung regex! Untungnya, saya tahu bahwa string uji akan memiliki panjang maksimum dan hanya akan terdiri dari ASCII yang dapat dicetak.
Tantangan
Anda harus memasukkan regex dan angka n
, dan mengeluarkan setiap string yang terdiri dari ASCII yang dapat dicetak (kode ASCII 32 hingga 126 inklusif, hingga
~
, tanpa tab atau baris baru) dengan panjang kurang dari atau sama dengan n
yang cocok dengan regex tersebut. Anda tidak boleh menggunakan persamaan reguler bawaan atau fungsi pencocokan regex dalam kode Anda sama sekali. Ekspresi reguler akan dibatasi sebagai berikut:
- Karakter literal (dan lolos, yang memaksa karakter menjadi literal, demikian
\.
juga literal.
,\n
adalah literaln
(setara dengan adiln
), dan\w
setara denganw
. Anda tidak perlu mendukung urutan pelarian.) .
- wildcard (karakter apa saja)- Kelas karakter,
[abc]
berarti "a atau b atau c" dan[d-f]
berarti apa saja dari d ke f (jadi, d atau e atau f). Satu-satunya karakter yang memiliki arti khusus dalam kelas karakter adalah[
dan]
(yang akan selalu lolos, jadi jangan khawatir tentang itu),\
(karakter pelarian, tentu saja),^
di awal kelas karakter (yang merupakan negasi ), dan-
(yang merupakan kisaran). |
- operator ATAU, bergantian.foo|bar
berarti salahfoo
ataubar
, dan(ab|cd)e
cocok denganabe
ataucde
.*
- cocok dengan token sebelumnya yang diulang nol atau lebih, serakah (mencoba untuk mengulang sebanyak mungkin)+
- Diulang satu atau lebih kali, serakah?
- nol atau satu kali- Pengelompokan dengan tanda kurung, untuk token kelompok untuk
|
,*
.+
, atau?
Input regex akan selalu valid (yaitu, Anda tidak harus menangani input seperti ?abc
atau (foo
atau input yang tidak valid). Anda dapat menampilkan string dalam urutan apa pun yang Anda inginkan, tetapi setiap string harus muncul hanya sekali (jangan hasilkan duplikat).
Kasus Uji
Input: .*
, 1
Output: (string kosong), ,
!
, "
, ..., }
,~
Input: w\w+
, 3
Output: ww
,www
Input: [abx-z][^ -}][\\]
, 3
Output: a~\
, b~\
, x~\
, y~\
,z~\
Input: ab*a|c[de]*
, 3
Output: c
, cd
, ce
, aa
, cde
, ced
, cdd
, cee
,aba
Input: (foo)+(bar)?!?
, 6
Output: foo
, foo!
, foofoo
,foobar
Input: (a+|b*c)d
, 4
Output: ad
, cd
, aad
, bcd
, aaad
,bbcd
Input: p+cg
, 4
Output: pcg
,ppcg
Input: a{3}
, 4
Output:a{3}
Pemenang
Ini adalah kode-golf , jadi kode terpendek dalam byte akan menang!
sumber
|
sangat tidak masuk akal. Tampaknya tidak menangani grup bersarang ataua|b|c
. Apa yang salah dengan menggunakan penjelasan standar dalam hal seberapa kuat penggabungan dan pergantian mengikat? (Dan Anda tidak punya alasan untuk tidak menggunakan kotak pasir)Jawaban:
Haskell
757 705 700 692 679667keluaran:
Penjelasan: ini adalah implementasi regex buku teks. R adalah tipe regex, dengan konstruktor A (alternatif), L (literal), T (lalu) dan E (kosong / epsilon). 'Bintang' yang biasa tidak muncul karena saya sebariskan sebagai alternatif selama parse (lihat '%'). 'm' menjalankan simulasi. Parser (mulai dari 'rs = ....') hanyalah turunan rekursif; rentang k 'p'. Fungsi '#' memperluas rentang menjadi bergantian.
sumber
Python v2.7
10691036950925897884871833822Jawaban ini sepertinya agak panjang untuk kode golf, tetapi ada banyak operator yang perlu ditangani dan saya tahu apa tujuan setiap byte dalam jawaban ini. Karena tidak ada jawaban yang ada, saya mengirimkan ini sebagai target untuk dikalahkan oleh pengguna lain. Lihat apakah Anda dapat membuat jawaban yang lebih pendek :).
Dua fungsi utama adalah
f
mem-parsing regex mulai darii
karakter th, dand
yang menghasilkan string yang cocok, menggunakanr
sub-regex yang dapat kita rekur ulang menjadi, 'a' array yang mewakili bagian dari sub-regex saat ini yang belum diproses, dan akhiran strings
yang mewakili bagian dari string yang dihasilkan sejauh ini.Periksa juga keluaran sampel dan alat uji .
Perhatikan bahwa tab dalam solusi asli telah
expand
diedit. Untuk menghitung jumlah karakter dalam penggunaan aslinyaunexpand < regex.py | wc
.sumber
def E(a,b):c=a[:];c.extend(b);return c
menjadiE=lambda a,b:a[:].extend(b)
, untuk:A
elif isinstance(e,str):
, saya yakin Anda dapat mengubah kode di dalamnya menjadi:exec{'.':'for c in C:d(r,p,s+chr(c))','?':'d(r,p,s);d(r,p[:z],s)','*':'''c=p[:z]#newline for i in R(0,n+1):d(r,c,s);c+=[p[z]]''','+':"d(r,p+['*',p[z]],s)",'\\':'d(r,p,e[1]+s)'}.get(e,'d(r,p,e+s)')
(perhatikan bahwa#newline
ini adalah baris baru) (sumber: stackoverflow.com/a/103081/1896169 )