Decomporre le parole in altre parole (ad es. “Afterglow” = “aft” + “erg” + “low”)


13

Eccone uno per tutti voi parolieri là fuori! Scrivi un programma o una funzione che prende un elenco di parole e produce un elenco di tutte le possibili scomposizioni concatenative per ogni parola. Per esempio:

(Nota: questo è solo un piccolo campionamento a scopo illustrativo. L'output effettivo è molto più voluminoso.)

afterglow = after + glow
afterglow = aft + erg + low
alienation = a + lie + nation
alienation = a + lien + at + i + on
alienation = a + lien + at + ion
alienation = alien + at + i + on
alienation = alien + at + ion
archer = arc + her
assassinate = ass + as + sin + ate
assassinate = ass + ass + in + ate
assassinate = assassin + ate
backpedalled = back + pedal + led
backpedalled = back + pedalled
backpedalled = backpedal + led
goatskin = go + at + skin
goatskin = goat + skin
goatskin = goats + kin
hospitable = ho + spit + able
temporally = tempo + rally
windowed = win + do + wed
windowed = wind + owed
weatherproof = we + at + her + pro + of
yeasty = ye + a + sty

Ok, hai avuto l'idea. :-)

Regole

  • Usa qualsiasi linguaggio di programmazione di tua scelta. Vince il codice più breve per numero di caratteri per ogni lingua . Ciò significa che esiste un vincitore per ogni lingua utilizzata. Il vincitore assoluto sarà semplicemente il codice più breve di tutti i partecipanti.
  • L'elenco di input può essere un file di testo, input standard o qualsiasi struttura di elenco fornita dalla tua lingua (elenco, array, dizionario, set, ecc.). Le parole possono essere inglese o qualsiasi altra lingua naturale. (Se l'elenco è composto da parole inglesi, ti consigliamo di ignorare o pre-filtrare gli elementi a lettera singola tranne "a" e "i". Allo stesso modo, per altre lingue, ti consigliamo di ignorare gli articoli senza senso se appare nel file.)
  • L'elenco di output può essere un file di testo, un output standard o qualsiasi struttura di elenco utilizzata dalla tua lingua.
  • Puoi usare qualsiasi dizionario di input che ti piace, ma probabilmente vorrai usarne uno che fornisca parole sensibili piuttosto che uno che fornisca troppe parole oscure, arcane o obnubilate. Questo è il file che ho usato: L'elenco Corncob di oltre 58000 parole inglesi

Domande

Questa sfida riguarda principalmente la scrittura del codice per eseguire l'attività, ma è anche divertente esaminare i risultati ...

  1. Quali parole chiave si verificano più comunemente?
  2. Quale parola può essere scomposta nel maggior numero di parole chiave?
  3. Quale parola può essere scomposta nei modi più diversi?
  4. Quali parole sono composte dalle più grandi parole chiave?
  5. Quali decomposizioni hai trovato le più divertenti?

@Geobits - Ah, grazie! Ho perso due decomposizioni di alienationquando l'ho tagliato e incollato. Riparato ora. In termini di altri, l'elenco sopra è solo un piccolo campionamento. Il mio programma di test ha generato decine di migliaia di risposte quando è stato fornito l'elenco Corncob.
Todd Lehman,

1
"Quali parole chiave si verificano più comunemente?" Lancerò un'ipotesi selvaggia là fuori e dire che 'a' potrebbe essere vicino alla cima.
Sellyme,

@SebastianLamerichs - Non lo so ... Potrebbe essere, potrebbe non esserlo. :)
Todd Lehman

@ToddLehman quella frase contiene esattamente 0 parole chiave, quindi 'a' è sempre uguale per primo: P
Sellyme

@SebastianLamerichs se ti riferissi alla risposta di Todd a te, "non lo so" può essere diviso in "dun" + "no". ;)
Ho allarmato l'alieno il

Risposte:


3

Python 186

a=open(raw_input()).read().split()
def W(r):
 if r:
    for i in range(1,len(r)+1):
     if r[:i]in a:
        for w in W(r[i:]):yield[r[:i]]+w
 else:yield[]
while 1:
 for f in W(raw_input()):print f

Non particolarmente efficiente ma in realtà non terribile lento. È semplicemente ingenuo (suppongo sia possibile, anche se penso che sia improbabile che Python compia alcune ottimizzazioni intelligenti) verifica che le parole secondarie si trovino nel dizionario della pannocchia e trova ricorsivamente quante più parole possibile. Naturalmente questo dizionario è piuttosto esteso e potresti provarne uno che non include varie abbreviazioni e acronimi (che portano a cose del genere bedridden: be dr id den). Inoltre, il dizionario collegato non sembrava avere "A" o "I" elencati come parole, quindi li ho aggiunti manualmente.

Modificare:

Ora il primo input è il nome file del dizionario da usare e ogni ulteriore è una parola.


Vale la pena affermare che si tratta di Python 2, perché il codice non viene eseguito in Python 3, perché print fdovrebbe essereprint(f)

Inoltre, come posso eseguire questo? echo archer|python2 filename.pygenera un errore EOFE per l'ultima riga

Alcune cose che potresti ancora cambiare (non le ho testate, ma sono abbastanza sicuro che funzionerebbe): for f in W(raw_input()):print f=> ''.join(W(raw_input()); a=open('c').read().split('\n')=>a=open('c').readlines()
ɐɔıʇǝɥʇuʎs

@ ɐɔıʇǝɥʇuʎs Il tuo primo funzionerebbe ma readlinesmantiene i caratteri di fine riga alla fine delle righe ed è per questo che l'ho fatto come ho fatto io.
KSab,

@ ɐɔıʇǝɥʇuʎs Oh, in realtà sembra joinche tutti gli elementi siano stringhe e non riesco a ottenerlo in una forma più piccola di quella che già ho.
KSab,

2

Cobra - 160

sig Z(x,y)
def f(b)
    c as Z=do(x,y)
        if x.length<1,print y
        for z in File.readLines('t'),if z==x[:e=z.length].toLower,c(x[e:],y+' '+z)
    for t in b,c(t,'[t]:')

Questa è una funzione (ordinamento di due funzioni) che accetta un List<of String>* e stampa le stringhe contenenti le possibili disposizioni di parole secondarie per ogni stringa nell'elenco degli argomenti.

* il tipo è in realtà List<of dynamic?>, ma fornire qualsiasi cosa diversa da quella List<of String>probabilmente lo romperà.


2

Scala, 132 129

Modifica: leggermente più breve come lettura di loop da stdin rispetto a una funzione

while(true)print(readLine.:\(Seq(List(""))){(c,l)=>l.flatMap{m=>Seq(c+""::m,c+m.head::m.tail)}}filter(_.forall(args contains _)))

correre come

scala decompose.scala aft after erg glow low

(o usa un elenco di parole più lungo :))

Originale:

def f(s:Seq[String])=s.map{_.:\(Seq(List(""))){(c,l)=>l.flatMap{m=>Seq(c+""::m,c+m.head::m.tail)}}filter(_.forall(args contains _))}

Funzione da Seq [String] a Seq [Seq [List [String]]]. Accetta il dizionario come argomento della riga di comando.

Ungolfed:

def decompose(wordList: Seq[String]) =
  wordList.map{ word =>                              // for each word
    word.foldRight(Seq(List(""))){ (char, accum) =>  // for each character
      accum.flatMap{list =>
        Seq(char+""::list,char+list.head::list.tail) // add it as both a new list and 
      }                                              // the to start of the first list
    }.filter(_.forall(args contains _))              // filter out lists w/ invalid words
  }

L'approccio è generare tutti i possibili elenchi di sottostringhe e filtrare quelli che contengono una stringa non presente nel dizionario. Si noti che alcune delle sottostringhe generate contengono una stringa vuota aggiuntiva, suppongo che la stringa vuota non sia presente nel dizionario (non è comunque possibile passarla nella riga di comando).

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.