Syllabify angielskie słowa - w pewnym sensie

11

Twoim zadaniem jest napisanie programu, który sylabuje słowa w ciągu tekstu, oddzielając je myślnikiem. To byłoby dużo pracy, więc chcesz pominąć niektóre części, głównie dlatego, że nie chcesz mieć tabeli wymowy wymaganej dla idealnego algorytmu. Chcesz również, aby był on tak krótki (a przez to nieczytelny i niemożliwy do utrzymania), jak to możliwe, jako zemsta za otrzymanie tego zadania.

Masz dwie możliwości:

  • Napisz program, który pobiera ciąg ze STDIN i przekazuje wynik do STDOUT.
  • Napisz funkcję, która bierze ciąg jako pojedynczy parametr i zwraca wynik.

Specyfikacja

  • W tym przypadku łańcuch oznacza dowolną konstrukcję podobną do łańcucha w wybranym języku (tablice bajtów, tablice znaków, łańcuchy ...).
  • Samogłoski są a, e, i, o, u
  • Podany ciąg ma 1 <= n <= 10słowa, przy czym każdy ma długość między 1 - 30znakami, włącznie. Twoje dane wyjściowe powinny być wyrazami dzielonymi.
  • Wszystkie litery są pisane małymi literami, a słowa zawsze są oddzielane spacjami. Zatem dane wejściowe składają się ze znaków[a-z ]
  • Zastosuj reguły według ważności.
  • Kiedy słowo jest podzielone, zacznij od prawej połowy słowa.

Reguły sylabizacji , w kolejności ich ważności

Dwa kolejne same samogłoski liczyć jako jeden (tj. feetPosiada tylko jedną samogłoskę, ale beati findingmają dwa). Każda sylaba ma dokładnie jedną samogłoskę, dlatego dla każdej samogłoski jest jedna sylaba.

  1. Jeśli całe słowo ma tylko cztery litery, zwróć je bez zmian. (pomiń to do końca słowa)
  2. Jeśli słowo ma tylko jedną samogłoskę, zwróć słowo bez zmian.
  3. Jeśli słowo ma dwie kolejne samogłoski, podziel je między sobą (tj. diaspora-> di-as-po-ra)
  4. Kiedy dwie lub więcej spółgłosek występuje między dwiema samogłoskami (ta sama lub inna), podziel po pierwszej spółgłosce (tj. sis-ter), Chyba że część spółgłoski jest ck, w takim przypadku podziel słowo po niej. (tj. nickel-> nick-el)
  5. Kiedy a ywystępuje między dwiema samogłoskami, podziel słowo po nim (np. paying-> pay-ing).
  6. Gdy jedna spółgłoska występuje między dwiema samogłoskami (ta sama lub inna), podziel się przed spółgłoską (tj. dra-gon)
  7. Zwróć słowo bez zmian, jeśli nie można wykonać podziału.

Wybrałem te reguły, ponieważ można je stosować rekurencyjnie bez problemów i nie wymagają tabel wymowy. Dlatego nie są one dokładne i na przykład reguła nr 5 często nie jest poprawna. Jednak w ogólnym przypadku tak jest.

Przykład

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
patrz
źródło
Jesteś tego pewien x-e-non? Odniesienie do reguły nr 4?
John Dvorak
@JanDvorak „Kiedy słowo jest podzielone, zacznij od prawej połowy słowa.”, Po czym następuje reguła # 6.
patrz
To znaczy, czy zasada nr 4 nie powinna rozdzielać tylko sylab?
John Dvorak
1
Zasada nr 1 dotyczy czterech liter. Co powiesz na słowa zawierające mniej niż cztery litery? np.lua
Digital Trauma
1
@DigitalTrauma Zwykle są prozowani, ale rzadko mają dwie sylaby.
patrz

Odpowiedzi:

6

Rubin, 144 bajty

Jeśli dążymy do niemożliwego do utrzymania, co powiesz o pojedynczym wyrażeniu regularnym?

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

niektóre dane wyjściowe:

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
źródło
8

Lua, 292

Lua może nie był najlepszym językiem do zrobienia tego, ale działa. Prawie płynie jak zadane pytanie. Reguły są głównie w porządku z pewnymi optymalizacjami: # 2 jest pomijane (nie jest potrzebne, chyba że na początku jest jedno samogłoskowe słowo z "ck"), a reguły ck i y są przestrzegane przed resztą # 4 i # 6, które są połączone. Ponieważ niektóre samogłoski w tym słowie muszą zostać przechwycone dwukrotnie (po jednym łączniku i przed drugim), wyszukiwanie jest wykonywane dwukrotnie.

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

Nie golfił

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

Przetestuj tutaj: http://ideone.com/g57TzA

Ogniwo
źródło
Nie mam rubinu, ale rzeczywiście wydaje się w porządku.
patrz
4

Bash + coreultils, 173 bajty

Myślę, że mam wszystkie najnowsze zmiany zasad:

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 \ 

Zauważ, że ostatnim znakiem ostatniego wiersza jest (spacja).

Myślę, że to wystarczająco spełnia „nieczytelne i nie do utrzymania” ;-)

Pobiera dane wejściowe ze STDIN.

Głównie proste podstawienie wyrażenia regularnego. Pierwszy wiersz sedwyrażenia pasuje do reguł 1 i 2, a następnie po prostu przeskakuje do :xetykiety na końcu wyrażenia.

Litery „ trs” na początku i na końcu potoku powodują, że słowa są oddzielone znakiem nowej linii, dzięki czemu łatwiej sedsobie z nimi poradzić. Miałem nadzieję, że to zrobię i wszyscy sedodpowiedzą, ale ten sposób jest prostszy i łatwiejszy.

Przykład:

$ ./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 $ 
Cyfrowa trauma
źródło
Argh, ciągle zapominam o zmianie zasady nr 3. W porządku.
patrz