Silbe englische Wörter - Art von

11

Sie müssen ein Programm schreiben, das Wörter in einer Textfolge silbiert, indem Sie sie durch einen Bindestrich trennen. Das wäre eine Menge Arbeit, daher möchten Sie einige Teile überspringen, hauptsächlich, weil Sie keine Tabelle mit den Aussprachen haben möchten, die für einen perfekten Algorithmus erforderlich sind. Sie möchten es auch so kurz (und damit unlesbar und nicht wartbar) wie möglich machen, um sich für diesen Auftrag zu rächen.

Sie haben zwei Möglichkeiten:

  • Schreiben Sie ein Programm, das die Zeichenfolge von STDIN übernimmt und das Ergebnis an STDOUT ausgibt.
  • Schreiben Sie eine Funktion, die die Zeichenfolge als einzelnen Parameter verwendet und das Ergebnis zurückgibt.

Spezifikation

  • In diesem Fall bedeutet Zeichenfolge ein beliebiges Zeichenfolgen-ähnliches Konstrukt in der Sprache Ihrer Wahl (Byte-Arrays, Zeichen-Arrays, Zeichenfolgen ...).
  • Vokale sind a, e, i, o, u
  • Die angegebene Zeichenfolge enthält 1 <= n <= 10Wörter, wobei jedes 1 - 30Zeichen eine Länge zwischen Zeichen einschließlich enthält. Ihre Ausgabe sollte aus Wörtern bestehen, die mit einem Bindestrich versehen sind.
  • Alle Buchstaben sind Kleinbuchstaben und Wörter werden immer durch Leerzeichen getrennt. Somit besteht die Eingabe aus Zeichen[a-z ]
  • Wenden Sie Regeln in der Reihenfolge ihrer Wichtigkeit an.
  • Wenn ein Wort geteilt wird, beginnen Sie erneut mit der rechten Worthälfte.

Regeln für die Silbenbildung in der Reihenfolge ihrer Wichtigkeit

Zwei aufeinanderfolgende gleiche Vokale zählen als ein (dh. feetNur ein Vokal, sondern beatund findinghaben zwei). Jede Silbe hat genau einen Vokal, daher gibt es für jeden Vokal eine Silbe.

  1. Wenn das ganze Wort nur vier Buchstaben hat, geben Sie es unverändert zurück. (Überspringen Sie dies für den Rest des Wortes)
  2. Wenn das Wort nur einen Vokal hat, geben Sie das Wort unverändert zurück.
  3. Wenn das Wort zwei aufeinanderfolgende Vokale hat, teilen Sie zwischen ihnen (dh diaspora-> di-as-po-ra)
  4. Wenn zwei oder mehr Konsonanten zwischen zwei Vokalen (gleich oder verschieden) stehen, teilen Sie nach dem ersten Konsonanten (dh sis-ter), es sei denn, der Konsonantenteil ist ck. In diesem Fall teilen Sie das Wort danach. (dh nickel-> nick-el)
  5. Wenn a yzwischen zwei Vokalen steht, teilen Sie das Wort danach (zB paying-> pay-ing).
  6. Wenn ein Konsonant zwischen zwei Vokale (gleich oder verschieden) kommt, teilen Sie vor dem Konsonanten (dh dra-gon).
  7. Geben Sie das Wort unverändert zurück, wenn keine Unterteilung möglich ist.

Ich habe diese Regeln gewählt, weil sie problemlos rekursiv angewendet werden können und keine Aussprache-Tabellen erfordern. Daher sind sie nicht genau und zum Beispiel ist Regel 5 oft nicht korrekt. Im Allgemeinen ist es jedoch so.

Beispiel

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
seequ
quelle
Bist du dir sicher x-e-non? Referenz für Regel 4?
John Dvorak
@JanDvorak "Wenn ein Wort geteilt wird, beginnen Sie erneut mit der rechten Hälfte des Wortes.", Gefolgt von Regel 6.
siehe
Ich meine, sollte Regel Nr. 4 nicht nur zwischen Silben aufgeteilt werden?
John Dvorak
1
Regel Nr. 1 behandelt Wörter mit vier Buchstaben. Was ist mit Wörtern mit weniger als vier Buchstaben? zBlua
Digitales Trauma
1
@DigitalTrauma Sie werden normal gepresst, haben aber selten zwei Silben.
siehe

Antworten:

6

Ruby, 144 Bytes

Wie wäre es mit einer einzigen riesigen Regex, wenn wir uns nicht halten wollen?

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

einige Ausgabe:

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
YenTheFirst
quelle
8

Lua, 292

Lua war vielleicht nicht die beste Sprache, um dies zu tun, aber es funktioniert. Es fließt so ziemlich wie die gestellte Frage. Die Regeln sind hauptsächlich in Ordnung mit einigen Optimierungen: # 2 wird übersprungen (es wird nicht benötigt, es sei denn, es gibt ein Ein-Vokal-Wort mit "ck" am Anfang), und die ck- und y-Regeln werden vor dem Rest von # durchlaufen. 4 und # 6, die kombiniert werden. Da einige Vokale im Wort zweimal erfasst werden müssen (nach einem Bindestrich und vor einem anderen), wird diese Suche zweimal durchgeführt.

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

Testen Sie es hier: http://ideone.com/g57TzA

Nexus
quelle
Ich habe keinen Rubin, aber es scheint in der Tat in Ordnung zu sein.
siehe
4

Bash + Coreultils, 173 Bytes

Ich glaube, ich habe die neuesten Regeländerungen:

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 \ 

Beachten Sie, dass das letzte Zeichen der letzten Zeile ein (Leerzeichen) ist.

Ich denke das befriedigt ausreichend "unlesbar und nicht wartbar" ;-)

Nimmt Eingaben von STDIN entgegen.

Meistens reine Regex-Substitution. Die erste Zeile des sedAusdrucks entspricht den Regeln 1 und 2 und springt dann einfach zur :xBeschriftung am Ende des Ausdrucks.

Durch die trs am Anfang und am Ende der Pipeline werden die Wörter durch Zeilenumbrüche getrennt, sodass sie leichter sedzu handhaben sind . Ich hatte gehofft und alle sedantworten, aber dieser Weg ist einfacher und einfacher.

Beispiel:

$ ./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 $ 
Digitales Trauma
quelle
Argh, ich vergesse immer wieder, dass sich Regel 3 geändert hat. Das ist gut.
siehe