Ode Golf - Suppression de lettres

17

Étant donné un fichier de dictionnaire (un fichier texte contenant un mot ou une phrase sur chaque ligne, avec une ponctuation possible mais pas de chiffres; les lignes sont alphabétisées), vous devez sortir chaque combinaison de mots où une lettre peut être supprimée d'un mot pour en faire une autre; la lettre supprimée doit être placée entre parenthèses.

Par exemple, l'entrée

cat
cart
code
golf
ode
verify
versify

devrait donner une sortie de

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

Plusieurs façons d'obtenir la même paire ne doivent être affichées qu'une seule fois. Vous pouvez sortir scra(p)pedou scrap(p)ed, mais pas les deux.

La sortie doit être classée par ordre alphabétique par l'entrée la plus longue;

mart
mar
mat
ma

devrait avoir une sortie de

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

et les deux derniers pourraient être dans l'un ou l'autre ordre.

Le fichier de dictionnaire peut inclure des majuscules, des espaces, des tirets ou des apostrophes; ceux-ci doivent être ignorés. Par exemple,

inlay 
in-play

devrait produire in(p)lay. Votre sortie doit être dans le même cas. Des espaces supplémentaires sont autorisés.

L'entrée peut être STDIN ou à partir d'un fichier; il est séparé par des retours à la ligne. La sortie peut être la valeur de retour d'une fonction ou STDOUT (ou écrite dans un fichier si vous le souhaitez).

Il s'agit de , donc le code le plus court en octets l'emporte.

(C'est mon premier défi sur PPCG - faites-moi savoir si j'ai fait quelque chose de mal et je le corrigerai.)

Deusovi
la source
3
Quelle devrait être la sortie mart mar mat ma? Serait-ce mar(t) ma(r)t ma(r) ma(t)?
Sp3000
@Sp: oublié de spécifier la commande - modifié pour clarifier.
Deusovi
Dans le premier exemple, le mot golf n'est pas dans la sortie. Est-ce parce que c'est un mot qui n'a pas d'autres combinaisons?
LukStorms
@Luk: Ouais! Pour la plupart des fichiers de dictionnaire, il y aura beaucoup de mots qui ne font pas du tout d'autres mots - ceux-ci ne devraient apparaître nulle part dans la sortie.
Deusovi
2
Qu'en est-il de l'autorisation d'une fonction avec un (gros) paramètre de chaîne, renvoyant la sortie demandée sous forme de tableau de chaînes? Cela a mis l'accent sur l'algorithme, évitant d'avoir à gérer les E / S de fichiers.
edc65

Réponses:

1

Perl -an0, 101 + 3 octets

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

  • @Fest le dictionnaire, stocké dans un tableau, fourni par la magie du drapeau d'exécution. (b-oost, BoO # @% @ # $% $ # @ T)
  • map{s/\W//g;lc}@Fsupprime tous les symboles des mots et transforme tout en minuscules. (boost, boot)
  • sort{length$b<=>length$a}trie sur la longueur. (démarrage, boost)
  • map{ (...) while/(.)(?!\1)/g}@Fcorrespond à tous les caractères qui ne sont pas suivis par le même caractère ([b] oot, bo [o] t, boo [t], ...)
  • print"$`($1)$'\n"imprime les parties qui précèdent, mettent entre parenthèses et réussissent une correspondance ... (boo (s) t)
  • if $`.$'~~@F... si la concaténation de tout avant et après le match est dans le dictionnaire. ([renforcer])
bopjesvla
la source
5

JavaScript (ES6), 225

Une fonction avec un paramètre de chaîne, aucune entrée du fichier. J'ai demandé à OP si cela pouvait être valable.

Testez l'exécution de l'extrait dans un navigateur compatible EcmaScript 6 (implémentation des fonctions fléchées, chaîne de modèle, opérateur de propagation - Firefox, peut-être Safari ou MS Edge, pas 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
la source
@ETHproductions right, thx
edc65
3

Rubis, 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}

Testez-le ici: http://ideone.com/86avbe

Version lisible ici: http://ideone.com/ynFItB

Cristian Lupascu
la source
Sur mobile, je ne peux pas tester pour le moment - pourriez-vous ajouter un cas de test pour le SCRAPPED / SCRAPED one?
Deusovi
@Deusovi Cette affaire ne fonctionne pas correctement. Je le répare maintenant ...
Cristian Lupascu
@Deusovi mis à jour!
Cristian Lupascu
Cette réponse ne fournit pas une sortie correcte pour par exemple le ['jacklantern','jackslantern','jack-o-lantern']dict.
14mRh4X0r
1
@ 14mRh4X0r ne trouve pas cette demande dans la question ... The output should be ordered by the longer entry;...and the latter two could be in either order.
edc65
1

Rubis, 211

J'ai décidé d'adopter une approche différente pour résoudre ce problème, en utilisant l'expression régulière.

->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
la source
0

Perl 5, 210

Le code charge l'entrée dans un tableau trié et vérifie chaque valeur par rapport à toutes les valeurs du tableau qui ont 1 octet de plus.

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}<>)

Tester

$ 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
la source
0

Haskell, 201 octets

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)

Je ne sais pas quel format d'entrée est autorisé. fprend une liste de chaînes. Si une seule chaîne (avec nl mots séparés) est autorisée, ajoutez .linesà f(+6 octets).

Exemple d'utilisation:

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

Comment ça marche: mettez chaque mot en minuscule et ne gardez que les lettres. Divisez chaque mot xen deux parties à chaque position possible et faites des triplets (i,j,k)où se itrouve la première partie, jle premier caractère de la deuxième partie et kla queue de la deuxième partie. Gardez les triplets où i++kapparaît également dans la liste de mots. Si cette liste n'est pas vide, prenez le premier élément, appelez-le (l,m,n). Transformez toutes ces têtes de liste dans le format de sortie requis en entourant mavec ()et en le plaçant entre let n.

nimi
la source