Saling mengisi bagian yang kosong

11

Diberikan input dari dua string dengan urutan garis bawah yang mewakili kata-kata yang sesuai, output kalimat dengan "kosong" diisi.

Cara terbaik untuk menggambarkan tantangan ini adalah dengan contoh. Berikut ini contoh input:

programming _____________ and code golf
programming puzzles ______ code ____

Dan inilah output yang sesuai:

programming ___puzzles___ and code golf
programming puzzles _and__ code golf

Untuk keperluan tantangan ini, "kata" didefinisikan sebagai urutan satu atau lebih huruf kecil, dan "kosong" didefinisikan sebagai satu atau lebih garis bawah (input akan selalu hanya berisi huruf kecil, spasi, dan garis bawah) . Kata dan blank dalam string input dipisahkan oleh spasi tunggal, dan jumlah dari jumlah kata dan blank dalam kalimat akan selalu sama.

Tujuan dari tantangan ini adalah untuk mengisi semua bagian yang kosong dengan kata-kata yang benar , yang merupakan kata-kata yang menempati indeks yang sama di string lain ketika dibagi dengan spasi.

  • Kata harus dipusatkan di tempat kosong, seperti yang ditunjukkan dengan kata "puzzle" dalam contoh di atas — jumlah garis bawah yang sama tetap berada di kedua sisi.

  • Jika kata tidak dapat tepat berada di tengah, garis bawah ekstra dapat mengarah ke kiri atau kanan (mis. Kata "dan" pada contoh di atas).

  • Akan selalu ada garis bawah yang cukup untuk kata yang pas, tetapi mungkin ada persis sebanyak panjang kata (mis. Kata "golf" pada contoh di atas).

  • Tidak akan pernah ada posisi kosong di posisi yang sama di kedua string.

Input / output mungkin salah satu dari yang berikut ini (input / output tidak harus melalui metode yang sama):

  • string tunggal yang dipisahkan oleh karakter apa pun yang tidak alfabet, spasi, atau garis bawah (mis. baris baru atau string yang dipisahkan koma)

  • sebuah array / daftar / etc. dari dua string

  • dua argumen fungsi / perintah (hanya input)

Karena ini adalah , kode terpendek dalam byte akan menang.

Contoh di atas dapat digunakan sebagai test case. Ini adalah test case yang lebih besar (string kedua dalam output mungkin sedikit berbeda karena perilaku pemusatan yang berbeda):

lorem _____ dolor _____ amet _______________ adipiscing elit mauris dapibus tincidunt _____________________________ accumsan fringilla proin vulputate viverra lorem fermentum dictum
lorem ipsum ______ sit _______ consectetur _______________ elit mauris dapibus tincidunt metus accumsan fringilla proin vulputate viverra lorem ____________________________ dictum

lorem ipsum dolor _sit_ amet __consectetur__ adipiscing elit mauris dapibus tincidunt ____________metus____________ accumsan fringilla proin vulputate viverra lorem fermentum dictum
lorem ipsum dolor_ sit _amet__ consectetur __adipiscing___ elit mauris dapibus tincidunt metus accumsan fringilla proin vulputate viverra lorem _________fermentum__________ dictum
Gagang pintu
sumber
Tantangan bidiurnal yang bagus.
Rɪᴋᴇʀ

Jawaban:

5

Pyth, 30

jL;Cmm|*}J\_k.[lkhx#JdJkdCcR;Q

Mengambil input dan output sebagai daftar dua string. Menggunakan pendekatan split-zip-double map-center-zip-join yang cukup mendasar.

Coba di sini

Diperluas:

jL;Cmm|*}J\_k.[lkhx#JdJkdCcR;Q   ##
                          cR;Q   ##  split
                         C       ##  zip
    mm                           ##  double map
      |*}J\_k.[lkhx#JdJkd        ##  centre
   C                             ##  zip
jL;                              ##  join

Saya akan menjelaskan lebih banyak setelah saya benar-benar puas bahwa saya tidak bisa bermain golf ini lagi, meskipun harus cukup jelas, mengingat di mana-mana pendekatan split-zip-double map-center-zip-join dan sebagainya.

FryAmTheEggman
sumber
8
Ahhh, pendekatan split-zip-double map-center-zip-join klasik. Saya ingat itu digunakan sebagai contoh pengantar dalam kuliah Algoritma 101 saya.
Martin Ender
3
@ MartinBüttner Ya, saya punya beberapa kenangan buruk karena saya tidur di kelas itu, harus menyelesaikan masalah pada ujian menggunakan pendekatan duplikat-tambahkan-lihat-kembali-pertandingan-tambahkan-pusat-gantinya.
FryAmTheEggman
4
Saya akan menerapkan air dingin ke luka bakar.
Martin Ender
7

Retina , 102 100 93 88 byte

Hitungan byte mengasumsikan penyandian ISO 8859-1.

$
!¶$`
m`(?<=^(\w+ )*)(?=_.*¶(?<-1>\w+ )*(\w+))
$2
(([a-z])+)(?<-2>_)*(_*)\3|!\D+
$3$1$3

String akan dipisahkan oleh umpan baris. Jika ada jumlah garis bawah ganjil yang tersisa, yang asing akan menjadi setelah kata.

Cobalah online!

Penjelasan

Saya kira ini adalah "pendekatan duplikat-append-lookback-match-add-center", atau sesuatu yang dekat ...

$
!¶$`

Kami mulai dengan menduplikasi input (dipisahkan dengan a !dan linefeed). Tujuannya adalah agar kita dapat memproses kedua baris dengan mengambil kata dari baris berikutnya (alih-alih harus memperlakukan baris kedua secara terpisah).

m`(?<=^(\w+ )*)(?=_.*¶(?<-1>\w+ )*(\w+))
$2

Ini mengawali kata yang benar untuk setiap celah. Kami mulai dengan menghitung posisi kata saat ini dengan tampilan di belakang (?<=^(\w+ )*)(posisi disimpan sebagai kedalaman grup 1). Kemudian lookahead a) memastikan bahwa kita berada di awal celah dengan mencocokkan _, lalu melompat ke baris berikutnya dengan .*¶, mencocokkan jumlah kata yang tepat dengan (?<-1>\w+ )*untuk sampai ke posisi yang tepat, dan kemudian mencocokkan kata yang ditemukan di sana dengan (\w+)ke grup 2.

(([a-z])+)(?<-2>_)*(_*)\3|!\D+
$3$1$3

Tahap ini melakukan tiga hal:

  • Ini menghapus garis bawah yang sesuai dengan setiap panjang kata. Ini dilakukan dengan menghitung panjang kata ke dalam grup 2dengan ([a-z])+dan kemudian mencocokkan banyak garis bawah (yang tidak pernah ditulis kembali).
  • Ini menggeser kata ke tengah celah dengan menangkap setengah dari garis bawah yang tersisa dengan (_*)\3dan menulis $3$1$3kembali.
  • Ini menghapus input yang digandakan dengan mencocokkan !\D+dan menggantinya dengan apa pun.
Martin Ender
sumber
4

Python 2, 109

def f(a,b):exec"print' '.join([x,y][x<'`'].center(len(x),'_')for x,y in zip(a.split(),b.split()));a,b=b,a;"*2

Fungsi mengambil dua string sebagai argumen dan mencetak output seperti pada contoh. Ini menggunakan pendekatan yang membosankan, dengan str.center(width, fillchar)melakukan sebagian besar pekerjaan.

Cobalah online .

grc
sumber
1
Saya tidak berpikir Anda perlu z, kecuali jika saya melewatkan sesuatu Anda hanya dapat melakukan swap setelah cetak dan inline z.
FryAmTheEggman
@FryAmTheEggman ya, Anda benar. Terima kasih :)
grc
2

Ruby, 111 109 karakter

->l{l.map(&:split).transpose.map{|c|c[m=c[0]<c[1]?0:1]=c[1-m].center c[m].size,?_
c}.transpose.map{|s|s*' '}}

Input: array 2 string; output: array 2 string.

Contoh dijalankan:

2.1.5 :001 > puts ->l{l.map(&:split).transpose.map{|c|c[m=c[0]<c[1]?0:1]=c[1-m].center c[m].size,?_;c}.transpose.map{|s|s*' '}}[[
2.1.5 :002 >       'programming _____________ and code golf',
2.1.5 :003 >       'programming puzzles ______ code ____',
2.1.5 :004 >       ]]
programming ___puzzles___ and code golf
programming puzzles _and__ code golf
manatwork
sumber
1

JavaScript, 194 185 byte

f=(m,n)=>(m=m.split` `,n=n.split` `,G=(x,i,a)=>x[0]!='_'?x:(b=(a?n:m)[i],s=x.length-b.length,(k='_'.repeat(s/2))+b+k+(s%2?'_':'')),H=(e,y)=>e.map((x,i)=>G(x,i,y)).join` `,[H(m,1),H(n)])

Mengambil dua string sebagai parameter dan menghasilkan dua string sebagai array / daftar

dihapus
sumber
1

Mathematica 223

Harus ada cara yang lebih singkat untuk melakukan ini.

k=StringLength;m=StringSplit;
g=Partition[Riffle[m@#,m@#2],2]/.{{a_,a_}:> a<>" ",{a_,b_/; StringTake[b,1]=="_"}:> a<>" ",
{a_,b_}:>Table["_",Ceiling[z=(k@a-k@b)/2]]<>b<>""<>Table["_",Floor@z]<>" "}&;
s_~h~t_:={""<>g[s,t],""<>g[t,s]}

Contoh dijalankan

h["programming _____________ and code golf", "programming puzzles ______ code ____"]

masukkan deskripsi gambar di sini

DavidC
sumber
0

Gema, 208 203 karakter

\B=@set{i;0}
<I>=@push{${v;f};$0}@incr{i}
\n=@set{v;s}@set{i;0}
 =
\E=@repeat{$i;@cmps{$f;$s;@set{f;@fill-center{$f;$s}};;@set{s;@fill-center{$s;$f}}}@set{F;$f ${F;}}@set{S;$s ${S;}}@pop{f}@pop{s}}$F\n$S

Hanya karena Gema memiliki fungsi yang sempurna untuk tugas ini: .@fill-center{background;value}

Input: 2 baris yang dipisahkan baris baru (tidak ada baris baru final); output: 2 baris yang dipisahkan oleh baris baru (dengan spasi tambahan - tampaknya tidak dilarang).

Contoh dijalankan:

bash-4.3$ echo -ne 'programming _____________ and code golf\nprogramming puzzles ______ code ____' |
> gema '\B=@set{i;0};<I>=@push{${v;f};$0}@incr{i};\n=@set{v;s}@set{i;0}; =;\E=@repeat{$i;@cmps{$f;$s;@set{f;@fill-center{$f;$s}};;@set{s;@fill-center{$s;$f}}}@set{F;$f ${F;}}@set{S;$s ${S;}}@pop{f}@pop{s}}$F\n$S'
programming ___puzzles___ and code golf 
programming puzzles _and__ code golf 
manatwork
sumber
0

C, 197 byte

#define c(w,y)l=strspn(w,"_"),r=strcspn(y," "),memcpy(w+(l-r)/2,y,r),w+=l,y+=r;
main(l,v,w,y,r)char**v,*w,*y;{for(w=v[1],y=v[2];*w;w++,y++)if(*w^*y)if(*w^95)c(y,w)else c(w,y)puts(v[1]);puts(v[2]);}

Keluaran

$ ./a.out "lorem _____ dolor _____ amet _______________ adipiscing elit mauris dapibus tincidunt _____________________________ accumsan fringilla proin vulputate viverra lorem fermentum dictum" "lorem ipsum ______ sit _______ consectetur _______________ elit mauris dapibus tincidunt metus accumsan fringilla proin vulputate viverra lorem ____________________________ dictum"
lorem ipsum dolor _sit_ amet __consectetur__ adipiscing elit mauris dapibus tincidunt ____________metus____________ accumsan fringilla proin vulputate viverra lorem fermentum dictum
lorem ipsum dolor_ sit _amet__ consectetur __adipiscing___ elit mauris dapibus tincidunt metus accumsan fringilla proin vulputate viverra lorem _________fermentum__________ dictum
Cole Cameron
sumber
0

ES6, 122 byte

a=>a.map(s=>s.split` `).map((s,n,a)=>s.map((w,i)=>w<'a'?(l=w.length,t=w+a[n^1][i]+w,t.substr(t.length-l>>1,l)):w).join` `)

Mengambil array dari dua string sebagai parameter tunggal dan mengembalikan array lain dari dua string.

Neil
sumber