Ode Golf - Cancellazioni di lettere


17

Dato un file di dizionario (un file di testo contenente una parola o una frase su ciascuna riga, con possibile punteggiatura ma senza numeri; le linee sono alfabetizzate), devi generare ogni combinazione di parole in cui una lettera può essere rimossa da una parola per farne un'altra; la lettera rimossa deve essere racchiusa tra parentesi.

Ad esempio, l'input

cat
cart
code
golf
ode
verify
versify

dovrebbe dare un output di

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

Diversi modi per ottenere la stessa coppia devono essere visualizzati solo una volta. È possibile generare scra(p)pedo scrap(p)ed, ma non entrambi.

L'output deve essere ordinato in ordine alfabetico per la voce più lunga;

mart
mar
mat
ma

dovrebbe avere un output di

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

e gli ultimi due potrebbero essere in entrambi gli ordini.

Il file del dizionario può includere lettere maiuscole, spazi, trattini o apostrofi; questi dovrebbero essere ignorati. Per esempio,

inlay 
in-play

dovrebbe produrre in(p)lay. L'output dovrebbe essere nello stesso caso. È consentito uno spazio extra.

L'input può essere STDIN o da un file; è separato da newline. L'output può essere il valore di ritorno di una funzione o STDOUT (o scritto in un file se lo si desidera).

Questo è , quindi vince il codice più breve in byte.

(Questa è la mia prima sfida su PPCG - fammi sapere se ho fatto qualcosa di sbagliato e lo risolverò.)


3
Quale dovrebbe essere l'output per mart mar mat ma? Sarebbe mar(t) ma(r)t ma(r) ma(t)?
Sp3000,

@Sp: dimenticato di specificare l'ordine - modificato per chiarire.
Deusovi,

Nel primo esempio la parola golf non è nell'output. È perché è una parola che non ha altre combinazioni?
LukStorms,

@Luk: Sì! Per la maggior parte dei file di dizionario, ci saranno molte parole che non ne fanno affatto altre, che non dovrebbero apparire in nessun punto dell'output.
Deusovi,

2
Che dire di consentire una funzione con un parametro (grande) stringa, restituendo l'output richiesto come array di stringhe? Ciò pone l'attenzione sull'algoritmo, evitando la necessità di gestire l'I / O dei file.
edc65,

Risposte:


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;

dove

  • @Fè il dizionario, memorizzato in un array, fornito dalla magia del flag di runtime. (tra l'altro, BoO # @% @ # $% $ # @ T)
  • map{s/\W//g;lc}@Frimuove tutti i simboli dalle parole e trasforma tutto in minuscolo. (boost, avvio)
  • sort{length$b<=>length$a}ordina per lunghezza. (avvio, boost)
  • map{ (...) while/(.)(?!\1)/g}@Fcorrisponde a tutti i personaggi che non sono seguiti dallo stesso personaggio ([b] oot, bo [o] t, boo [t], ...)
  • print"$`($1)$'\n"stampa le parti che precedono, sono tra parentesi e hanno successo in una partita ... (boo (s) t)
  • if $`.$'~~@F... se la concatenazione di tutto prima e dopo la partita è nel dizionario. ([Incremento])

5

JavaScript (ES6), 225

Una funzione con un parametro stringa, nessun input dal file. Ho chiesto a OP se questo poteva essere valido.

Prova a eseguire lo snippet in un browser compatibile con EcmaScript 6 (implementando funzioni freccia, stringa di modello, operatore di diffusione - Firefox, forse Safari o MS Edge, non 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>


@ETHproductions right, 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}

Provalo qui: http://ideone.com/86avbe

Versione leggibile qui: http://ideone.com/ynFItB


Sui dispositivi mobili, quindi non posso eseguire il test adesso - potresti aggiungere un caso di test per quello SCRAPPED / SCRAPED?
Deusovi,

@Deusovi Quel caso non funziona correttamente. Lo sto sistemando ora ...
Cristian Lupascu,

@Deusovi Aggiornato!
Cristian Lupascu,

Questa risposta non fornisce un output corretto, ad esempio il ['jacklantern','jackslantern','jack-o-lantern']dict.
14mRh4X0r

1
@ 14mRh4X0r non riesco a trovare quella richiesta nella domanda ... The output should be ordered by the longer entry;...and the latter two could be in either order.
edc65,

1

Ruby, 211

Ho deciso di adottare un approccio diverso per risolvere questo problema, usando 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}

0

Perl 5, 210

Il codice carica l'input in un array ordinato e controlla ogni valore rispetto a tutti i valori nell'array che sono più lunghi di 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}<>)

Test

$ 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

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)

Non sono sicuro del formato di input consentito. fprende un elenco di stringhe. Se è consentita una sola stringa (con nl parole separate), aggiungi .linesa f(+6 byte).

Esempio di utilizzo:

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"]

Come funziona: trasforma ogni parola in minuscolo e conserva solo le lettere. Dividi ogni parola xin due parti in ogni posizione possibile e fai triple (i,j,k)dove iè la prima parte, jè il primo carattere della seconda parte ed kè la coda della seconda parte. Mantieni le triple dove i++kappare anche nell'elenco delle parole. Se questo elenco non è vuoto, prendi il primo elemento, chiamalo (l,m,n). Girare tutte quelle teste di elenco nel formato di output richiesto dal circostante mcon ()e metterlo tra i le n.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.