Ode Golf - Penghapusan Huruf

17

Diberikan file kamus (file teks yang berisi kata atau frasa pada setiap baris, dengan tanda baca yang memungkinkan tetapi tidak ada angka; baris diurutkan menurut abjad), Anda harus menampilkan setiap kombinasi kata di mana satu huruf dapat dihapus dari kata untuk membuat yang lain; surat yang dihapus harus dimasukkan dalam tanda kurung.

Misalnya input

cat
cart
code
golf
ode
verify
versify

harus memberikan output

ca(r)t
(c)ode
ver(s)ify

Berbagai cara untuk mendapatkan pasangan yang sama hanya harus ditampilkan satu kali. Anda dapat menampilkan scra(p)pedatau scrap(p)ed, tetapi tidak keduanya.

Output harus dipesan berdasarkan abjad dengan entri yang lebih panjang;

mart
mar
mat
ma

harus memiliki keluaran

ma(r)
ma(t)
ma(r)t
mar(t)

dan dua yang terakhir bisa dalam urutan mana pun.

File kamus dapat meliputi huruf besar, spasi, tanda hubung, atau apostrof; ini harus diabaikan. Contohnya,

inlay 
in-play

harus menghasilkan in(p)lay. Output Anda semua harus dalam kasus yang sama. Ruang kosong ekstra diizinkan.

Input dapat berupa STDIN atau dari file; dipisahkan oleh baris baru. Output dapat berupa nilai balik fungsi atau STDOUT (atau ditulis ke file jika Anda mau).

Ini adalah , jadi kode terpendek dalam byte menang.

(Ini adalah tantangan pertama saya di PPCG - beri tahu saya jika saya melakukan kesalahan dan saya akan memperbaikinya.)

Deusovi
sumber
3
Untuk apa outputnya mart mar mat ma? Apakah akan mar(t) ma(r)t ma(r) ma(t)?
Sp3000
@Sp: Lupa menentukan urutan - diedit untuk memperjelas.
Deusovi
Dalam contoh pertama kata golf tidak ada dalam output. Apakah itu karena itu kata yang tidak memiliki kombinasi lain?
LukStorms
@ Luk: Ya! Untuk sebagian besar file kamus, akan ada banyak kata yang tidak membuat kata-kata lain sama sekali - kata-kata itu tidak akan muncul di mana pun di output.
Deusovi
2
Bagaimana dengan membiarkan suatu fungsi dengan parameter string (besar), mengembalikan output yang diminta sebagai array string? Ini menempatkan fokus pada algoritma, menghindari kebutuhan untuk mengelola file I / O.
edc65

Jawaban:

1

Perl -an0, 101 + 3 byte

@F=sort{length$a<=>length$b}map{s/\W//g;lc}@F;map{$`.$'~~@F?print"$`($1)$'\n":$\while/(.)(?!\1)/g}@F;

dimana

  • @Fadalah kamus, disimpan dalam larik, disediakan oleh sihir bendera runtime. (b-oost, BoO # @% @ # $% $ # @ T)
  • map{s/\W//g;lc}@Fmenghapus semua simbol dari kata-kata dan mengubah semuanya menjadi huruf kecil. (boost, boot)
  • sort{length$b<=>length$a}macam panjangnya. (boot, boost)
  • map{ (...) while/(.)(?!\1)/g}@Fcocok dengan semua karakter yang tidak ditindaklanjuti dengan karakter yang sama ([b] oot, bo [o] t, boo [t], ...)
  • print"$`($1)$'\n"mencetak bagian-bagian yang mendahului, kurung, dan menyukseskan pertandingan ... (boo t)
  • if $`.$'~~@F... jika rangkuman dari semuanya sebelum dan sesudah pertandingan ada di kamus. ([dorongan])
bopjesvla
sumber
5

JavaScript (ES6), 225

Fungsi dengan parameter string, tidak ada input dari file. Saya bertanya kepada OP apakah ini bisa valid.

Tes menjalankan cuplikan di peramban yang mendukung EcmaScript 6 (menerapkan fungsi panah, string templat, operator sebar - Firefox, mungkin Safari atau MS Edge, bukan Chrome)

f=t=>t.split`
`.map(w=>(d[k=w.replace(/\W/g,'').toLowerCase()]={},k),d={},r=[]).map(w=>[...w].map((c,i,v)=>(d[v[i]='',x=v.join``]&&!d[x][w]&&r.push(d[x][w]=(v[i]=`(${c})`,v.join``)),v[i]=c)))&&r.sort((a,b)=>a.length-b.length)

// LESS GOLFED

Q=t=>{
  // convert to canonical form and put in a dictionary
  // each value in the dictionary is an hashtable tha will store the list
  // of words that can generate the current word, removing a letter
  d={},
  t=t.split`\n`.map(w=>(k=w.replace(/\W/g,'').toLowerCase(),d[k]={},k))
  r=[], // result array 
  t.forEach(w =>
    [...w].forEach((c,i,v)=>( // for each letter in word, try to remove
      v[i]='', x=v.join``, // build string with missing letter
      v[i]='('+c+')', y=v.join``, // and build string with brackets
      v[i]=c, // restore the current letter
      d[x] && // if the word with removed letter is present in the dictionary
      !d[x][w] && // and not already from the same generating word
         r.push(d[x][w]=y) // update dictionary and add word to result array
    ))
  )
  return r.sort((a,b)=>a.length-b.length) // sort result by length
}  

// TEST
function test() { R.innerHTML=f(I.value) }
textarea { height: 20em }
Test <button onclick="test()">-></button>
<span id=R></span>
<br><textarea id=I>cat
cart
code
golf
node
scraped
scrapped
verify
versify
mart
mar
mat
ma</textarea>

edc65
sumber
@ EHProduk kanan, thx
edc65
3

Ruby, 173

->d{o=[]
c={}
d=d.sort_by{|w|[w.size,w]}.map{|w|w=w.upcase.gsub /[^A-Z]/,''
c[w]=l=1
w.size.times{|i|p,x,s=w[0...i],w[i],w[i+1..-1]
c[p+s]&&l!=x&&o<<p+"(#{w[i]})"+s
l=x}}
o}

Uji di sini: http://ideone.com/86avbe

Versi yang dapat dibaca di sini: http://ideone.com/ynFItB

Cristian Lupascu
sumber
Di ponsel, jadi saya tidak bisa menguji sekarang - dapatkah Anda menambahkan test case untuk yang SCRAPPED / SCRAPED?
Deusovi
@Deusovi Kasing itu tidak berfungsi dengan benar. Saya memperbaikinya sekarang ...
Cristian Lupascu
@Deusovi Diperbarui!
Cristian Lupascu
Jawaban ini tidak memberikan hasil yang benar untuk mis ['jacklantern','jackslantern','jack-o-lantern']. Dikt.
14mRh4X0r
1
@ 14mRh4X0r tidak dapat menemukan permintaan itu dalam pertanyaan ... The output should be ordered by the longer entry;...and the latter two could be in either order.
edc65
1

Ruby, 211

Saya memutuskan untuk mengambil pendekatan berbeda untuk menyelesaikan ini, menggunakan regex.

->d{o=[]
d.map{|x|x.upcase!.gsub! /[-' ]/,''}
d.map{|x|(x.size+1).times{|i|o+=d.map{|w|w.b.sub! /(#{x[0...i]})(.)(#{x[i..-1]})/,'\1(\2)\3'if w[i]!=w[i+1]}}}
o.compact.sort_by{|w|[w.size,w.gsub(/[()]/,'')]}.uniq}
14mRh4X0r
sumber
0

Perl 5, 210

Kode memuat input dalam array yang diurutkan, dan memeriksa setiap nilai terhadap semua nilai dalam array yang lebih panjang 1 byte.

map{@W=split//,$w=$_;map{@X=split//,$x=$_;if(@W+1==@X){$i=0;while($W[$i]eq$X[$i]&&$i<@W){$i++}$c=$X[$i];$e=substr($w,$i);print substr($w,0,$i)."($c)$e\n",if substr($x,$i+1)eq$e}}@D}@D=sort(map{s/[^\w]//g;lc}<>)

Uji

$ perl dictionairy_same_words.pl dictionairywords.txt
ca(r)t
in(p)lay
ma(r)
ma(t)
mar(t)
ma(r)t
(c)ode
ver(s)ify
LukStorms
sumber
0

Haskell, 201 byte

import Data.List
import Data.Char
a#(b:c)=(a,b,c)
g a=[l++'(':m:')':n|x<-a,((l,m,n):_)<-[[o|o@(i,j,k)<-zipWith(#)(inits x)$init$tails x,elem(i++k)a]]]
f=sortOn length.g.map(filter isLetter.map toLower)

Saya tidak yakin format input apa yang diizinkan. fmengambil daftar string. Jika hanya satu string (dengan kata-kata yang dipisahkan nl) yang diizinkan, tambahkan .lineskef (+6 byte).

Contoh penggunaan:

f ["cat","cart","code","golf","od-e","verify","versify","on","s-o-n","Scrapped","scraped"]

["(s)on","ca(r)t","(c)ode","ver(s)ify","scra(p)ped"]

Cara kerjanya: ubah setiap kata menjadi huruf kecil dan simpan hanya huruf-hurufnya. Bagi setiap kata xmenjadi dua bagian pada setiap posisi yang memungkinkan dan buatlah tiga kali lipat di (i,j,k)mana ibagian pertama, jadalah karakter pertama dari bagian kedua dan kmerupakan ekor dari bagian kedua. Simpan tiga kali lipat di tempat yang i++kjuga muncul dalam daftar kata. Jika daftar ini tidak kosong, ambil elemen pertama, sebut saja (l,m,n). Mengubah semua daftar kepala ke dalam format output yang dibutuhkan oleh sekitarnya mdengan ()dan meletakkan antara ldan n.

nimi
sumber