Ode Golf - Löschen von Buchstaben

17

Bei einer Wörterbuchdatei (eine Textdatei, die ein Wort oder eine Phrase in jeder Zeile enthält, mit möglicher Interpunktion, aber ohne Zahlen; Zeilen sind alphabetisch sortiert) müssen Sie jede Kombination von Wörtern ausgeben, bei der ein Buchstabe aus einem Wort entfernt werden kann, um ein anderes zu bilden. Der entfernte Buchstabe sollte in Klammern gesetzt werden.

Zum Beispiel die Eingabe

cat
cart
code
golf
ode
verify
versify

sollte eine Ausgabe von geben

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

Mehrere Möglichkeiten, um dasselbe Paar zu erhalten, müssen nur einmal angezeigt werden. Sie können scra(p)pedoder ausgeben scrap(p)ed, aber nicht beide.

Die Ausgabe sollte alphabetisch nach dem längeren Eintrag sortiert sein .

mart
mar
mat
ma

sollte eine Ausgabe von haben

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

und die beiden letzteren könnten in jeder Reihenfolge sein.

Die Wörterbuchdatei kann Großbuchstaben, Leerzeichen, Bindestriche oder Apostrophe enthalten. diese sollten ignoriert werden. Zum Beispiel,

inlay 
in-play

sollte produzieren in(p)lay. Ihre Ausgabe sollte alle im selben Fall sein. Zusätzliches Leerzeichen ist zulässig.

Die Eingabe kann STDIN oder aus einer Datei erfolgen. Es wird durch Zeilenumbrüche getrennt. Die Ausgabe kann der Rückgabewert einer Funktion oder von STDOUT sein (oder, falls gewünscht, in eine Datei geschrieben werden).

Das ist , also gewinnt der kürzeste Code in Bytes.

(Dies ist meine erste Herausforderung bei PPCG - lassen Sie mich wissen, wenn ich etwas falsch gemacht habe und ich werde es beheben.)

Deusovi
quelle
3
Wofür soll die Ausgabe sein mart mar mat ma? Wäre es mar(t) ma(r)t ma(r) ma(t)?
Sp3000,
@Sp: Vergessen, die Reihenfolge anzugeben - bearbeitet, um zu klären.
Deusovi
Im ersten Beispiel steht das Wort Golf nicht in der Ausgabe. Ist das so, weil es ein Wort ist, das keine anderen Kombinationen hat?
LukStorms
@ Luk: Ja! Für die meisten Wörterbuchdateien gibt es eine Menge Wörter, die keine anderen Wörter ergeben - diese sollten nirgendwo in der Ausgabe erscheinen.
Deusovi
2
Wie wäre es, eine Funktion mit einem (großen) String-Parameter zuzulassen und die angeforderte Ausgabe als String-Array zurückzugeben? Dadurch wurde der Fokus auf den Algorithmus gelegt, und die Verwaltung der Datei-E / A entfällt.
Edc65

Antworten:

1

Perl -an0, 101 + 3 Bytes

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

wo

  • @Fist das in einem Array gespeicherte Wörterbuch, das von Runtime Flag Magic bereitgestellt wird. (b-oost, BoO # @% @ # $% $ # @ T)
  • map{s/\W//g;lc}@FEntfernt alle Symbole aus den Wörtern und dreht alles in Kleinbuchstaben. (Boost, Boot)
  • sort{length$b<=>length$a}sortiert nach Länge. (Booten, Boosten)
  • map{ (...) while/(.)(?!\1)/g}@Fstimmt mit allen Zeichen überein, denen nicht dasselbe Zeichen folgt ([b] oot, bo [o] t, boo [t], ...)
  • print"$`($1)$'\n" druckt die Teile, die vor, in Klammern und nach einer Übereinstimmung stehen ... (boo (s) t)
  • if $`.$'~~@F... wenn die Verkettung von allem vor und nach dem Match im Wörterbuch steht. ([boo] s [t])
bopjesvla
quelle
5

JavaScript (ES6), 225

Eine Funktion mit einem Zeichenfolgenparameter, keine Eingabe aus der Datei. Ich fragte OP, ob dies gültig sein könnte.

Testausführung des Snippets in einem EcmaScript 6-kompatiblen Browser (Implementierung von Pfeilfunktionen, Vorlagenzeichenfolge, Verteilungsoperator - Firefox, möglicherweise Safari oder MS Edge, nicht 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
quelle
@ETHproductions richtig, 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}

Testen Sie es hier: http://ideone.com/86avbe

Lesbare Version hier: http://ideone.com/ynFItB

Cristian Lupascu
quelle
Auf dem Handy kann ich nicht testen. Können Sie einen Testfall für SCRAPPED / SCRAPED hinzufügen?
Deusovi
@ Deusovi Dieser Fall funktioniert nicht richtig. Ich repariere es jetzt ...
Cristian Lupascu
@ Deusovi Aktualisiert!
Cristian Lupascu
Diese Antwort liefert keine korrekte Ausgabe für zB das ['jacklantern','jackslantern','jack-o-lantern']Diktat.
14mRh4X0r
1
@ 14mRh4X0r kann diese Anfrage in der Frage nicht finden ... The output should be ordered by the longer entry; ...and the latter two could be in either order.
edc65
1

Rubin, 211

Ich entschied mich für einen anderen Lösungsansatz mit 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
quelle
0

Perl 5, 210

Der Code lädt die Eingabe in ein sortiertes Array und vergleicht jeden Wert mit allen Werten im Array, die 1 Byte länger sind.

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

Prüfung

$ 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
quelle
0

Haskell, 201 Bytes

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)

Ich bin nicht sicher, welches Eingabeformat zulässig ist. fNimmt eine Liste von Zeichenfolgen. Wenn nur eine einzige Zeichenfolge (mit nl getrennten Wörtern) zulässig ist, fügen Sie hinzu.lines Sie zu f(6 Bytes).

Anwendungsbeispiel:

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

So funktioniert es: Verwandle jedes Wort in Kleinbuchstaben und behalte nur die Buchstaben. xTeilen Sie jedes Wort an jeder möglichen Stelle in zwei Teile und verdreifachen Sie, (i,j,k)wobei ider erste Teil, jder erste Buchstabe des zweiten Teils und kder Schwanz des zweiten Teils ist. Bewahren Sie die Tripel dort auf, wo sie i++kauch in der Wortliste erscheinen. Wenn diese Liste nicht leer ist, nehmen Sie das erste Element und rufen Sie es auf (l,m,n). Stellen Sie alle diese Listenköpfe in das gewünschte Ausgabeformat, indem Sie sie mmit ()und umgeben und zwischen lund setzen n.

nimi
quelle