Sillabare parole inglesi - tipo di


11

Ti viene assegnato il compito di scrivere un programma che sillaba le parole in una stringa di testo, separandole con un trattino. Sarebbe un sacco di lavoro, quindi vuoi saltare alcune parti, principalmente perché non vuoi avere una tabella delle pronunce richieste per un algoritmo perfetto. Vuoi anche renderlo il più breve possibile (e quindi illeggibile e non realizzabile) come una vendetta per aver ricevuto questo incarico.

Hai due scelte:

  • Scrivi un programma che prende la stringa da STDIN e trasmette il risultato a STDOUT.
  • Scrivi una funzione che accetta la stringa come singolo parametro e restituisce il risultato.

specificazione

  • In questo caso, stringa significa qualsiasi costrutto simile a una stringa nella tua lingua preferita (array di byte, array di caratteri, stringhe ...).
  • Le vocali lo sono a, e, i, o, u
  • La stringa fornita ha 1 <= n <= 10parole, ognuna delle quali ha una lunghezza tra i 1 - 30caratteri, inclusi. Il tuo output dovrebbe essere sillabato.
  • Tutte le lettere sono minuscole e le parole sono sempre separate da spazi. Pertanto, l'input è costituito da caratteri[a-z ]
  • Applica le regole in ordine di importanza.
  • Quando una parola viene divisa, ricominciare con la metà destra della parola.

Regole per la sillabazione , in ordine di importanza

Numero due stesse vocali consecutivi come unico (es. feetHa una sola vocale, ma beate findinghanno due). Ogni sillaba ha esattamente una vocale, quindi c'è una sillaba per ogni vocale.

  1. Se l' intera parola ha solo quattro lettere, restituiscila invariata. (salta questo per il resto della parola)
  2. Se la parola ha solo una vocale, restituisce la parola invariata.
  3. Se la parola ha due vocali consecutive, dividi tra loro (es. diaspora-> di-as-po-ra)
  4. Quando due o più consonanti si trovano tra due vocali (uguali o diverse), dividere dopo la prima consonante (cioè. sis-ter) A meno che non sia la parte consonante ck, nel qual caso dividere la parola dopo di essa. (es. nickel-> nick-el)
  5. Quando una si ytrova tra due vocali, dividi la parola dopo di essa (es. paying-> pay-ing).
  6. Quando una consonante si trova tra due vocali (uguali o diverse), dividere prima della consonante (cioè. dra-gon)
  7. Restituisce la parola invariata se non è stato possibile eseguire alcuna divisione.

Ho scelto queste regole, perché possono essere applicate in modo ricorsivo senza problemi e non richiedono tabelle di pronuncia. Pertanto, non sono accurati e, ad esempio, la regola n. 5 spesso non è corretta. In generale, tuttavia, lo è.

Esempio

In:  hello world
Out: hel-lo world

In:  have a nice day
Out: have a nice day

In:  pour some nickel and xenon there
Out: pour some nick-el and xe-non the-re

Ne sei sicuro x-e-non? Riferimento per la regola n. 4?
John Dvorak,

@JanDvorak "Quando una parola viene divisa, ricomincia dalla metà destra della parola.", Seguita dalla regola # 6.
Seequ,

Voglio dire, la regola n. 4 non dovrebbe essere suddivisa solo tra sillabe?
John Dvorak,

1
La regola n. 1 tratta di parole di quattro lettere. Che dire delle parole con meno di quattro lettere? es.lua
Digital Trauma,

1
@DigitalTrauma Vengono processati normalmente, ma raramente hanno due sillabe.
Seequ,

Risposte:


6

Rubino, 144 byte

Se stiamo andando per irraggiungibile, che ne dici di una singola regex gigante?

puts gets.split.map {|w| w.scan(/(^.{4}$|[^aeiou]*([aeiou])\2?((?=[^aeiouy]?[aeiou])|ck|[^aeiou]((?=.*[aeiou])|.*$)|$))/).map(&:first)*'-'}*' '

qualche uscita:

echo "hello world" | ruby syllable.rb
hel-lo world

echo "have a nice day" | ruby syllable.rb
have a nice day

echo "pour some nickel and xenon in there" | ruby syllable.rb
pour some nick-el and xe-non in the-re

echo "diaspora dragon paying sister hemlock happy quicksilver" | ruby syllable.rb
di-as-po-ra dra-gon pay-ing sis-ter hem-lock happy qu-ick-sil-ver

8

Lua, 292

Lua potrebbe non essere stata la lingua migliore per farlo, ma funziona. Scorre praticamente come la domanda posta. Le regole sono principalmente in ordine con alcune ottimizzazioni: # 2 è saltato (non è necessario a meno che non ci sia una parola vocale con "ck" all'inizio) e le regole ck e y sono passate prima del resto di # 4 e # 6, che sono combinati. Poiché alcune vocali nella parola devono essere catturate due volte (dopo un trattino e prima di un altro), quella ricerca viene eseguita due volte.

i=io.read()v="([aeiou])"for s in i:gfind("%l+ ?")do
if s:len()~=4 then
s=s:gsub(v..v,function(x,y)if x==y then return x..y;end;return x.."-"..y;end)s=s:gsub("ck"..v,"ck-%1")s=s:gsub(v.."y"..v,"%1y-%2")for b=1,2 do
s=s:gsub(v.."([^aeiou\-]?)([^aeiou\-]+)"..v,"%1%2-%3%4")end
end
io.write(s)end

Ungolfed

function checkEquals(x,y)
    if x==y then 
        return x..y
    end
    return x.."-"..y
end
i=io.read()
v="([aeiou])"
for s in i:gfind("%l+ ?") do
    if s:len()~=4 then
        s=s:gsub(v..v,checkEquals)
        s=s:gsub("ck"..v,"ck-%1")
        s=s:gsub(v.."y"..v,"%1y-%2")
        for b=1,2 do
            s=s:gsub(v.."([^aeiou\-]?)([^aeiou\-]+)"..v,"%1%2-%3%4")
        end
    end
    io.write(s)
end

Provalo qui: http://ideone.com/g57TzA


Non ho il rubino, ma sembra davvero a posto.
Seequ,

4

Bash + coreultils, 173 byte

Penso di avere tutte le ultime modifiche alle regole:

v=aeiou
r="[$v])/\1-\2/g"
s=s/\([$v]
e="$s[^$v-])([^$v-]+$r
"
tr \  \\n|sed -r "/^([a-z]{4}|[^$v]*[$v][^$v]*)$/bx
$s)($r
${s}ck)($r
$e$e${s}y)($r
$s)([^$v-]$r
:x"|tr \\n \ 

Nota l'ultimo carattere dell'ultima riga è uno (spazio).

Penso che ciò soddisfi sufficientemente "illeggibile e non mantenibile" ;-)

Riceve input da STDIN.

Sostituzione regex prevalentemente diritta. La prima riga seddell'espressione corrisponde alle regole 1 e 2, quindi passa semplicemente :xall'etichetta alla fine dell'espressione.

Le trs all'inizio e alla fine della pipeline rendono le parole separate da newline, quindi sono più facili sedda gestire. Speravo di fare e sedrispondere a tutti , ma in questo modo è sempre più semplice.

Esempio:

$ ./sylabify.sh <<< "diaspora nickel sister dragon hello world have a nice day pour some nickel and xenon there paying tricks quicksilver"
di-as-po-ra nick-el sis-ter dra-gon hel-lo world have a nice day pour some nick-el and xe-non the-re pay-ing tricks qu-ic-ksil-ver $ 

Argh, continuo a dimenticare che la regola n. 3 è cambiata. Va bene.
Seequ,
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.