Складові англійські слова - вид


11

Вам доручено написати програму, яка зводить слова в рядку тексту, відокремлюючи їх дефісом. Це було б багато роботи, тому ви хочете пропустити деякі частини, головним чином тому, що ви не хочете мати таблицю вимов, необхідних для досконалого алгоритму. Ви також хочете зробити його якомога коротшим (і, таким чином, нечитабельним та нездійсненним), як помсту за те, що отримали це завдання.

У вас є два варіанти:

  • Напишіть програму, яка бере рядок від STDIN і виводить результат на STDOUT.
  • Напишіть функцію, яка приймає рядок як єдиний параметр і повертає результат.

Специфікація

  • У цьому випадку рядок означає будь-яку структуру, схожу на рядок у вибраній вами мові (масиви байтів, масиви символів, рядки ...).
  • Голосні звуки є a, e, i, o, u
  • Наведений рядок має 1 <= n <= 10слова, де кожен має довжину між 1 - 30символами, включно. У вашому висновку повинні бути слова з дефісом.
  • Усі букви мають малі літери, а слова завжди розділені пробілами. Таким чином, вхід складається з символів[a-z ]
  • Застосовуйте правила в порядку важливості.
  • Коли слово розділиться, почніть знову з правої половини слова.

Правила конспектування в порядку важливості

Підраховувати два послідовних ж голосні , як один (тобто. feetЄ тільки один голосний, але beatі findingмати два). Кожен склад має рівно один голосний, таким чином, є один склад для кожного голосного.

  1. Якщо все слово має лише чотири літери, поверніть його без змін. (пропустіть це для решти слова)
  2. Якщо слово має лише одну голосну, поверніть слово без змін.
  3. Якщо слово має дві послідовні голосні, розділіть їх (тобто. diaspora-> di-as-po-ra)
  4. Коли два або більше приголосних знаходяться між двома голосними (однаковими чи різними), діліться після першого приголосного (тобто sis-ter), якщо не є приголосна частина ck, в цьому випадку розділіть слово після нього. (тобто. nickel-> nick-el)
  5. Коли а yбуває між двома голосними, розділіть слово після нього (наприклад paying-> pay-ing).
  6. Коли один приголосний приходить між двома голосними (однаковими чи різними), діліть перед приголосним (тобто dra-gon)
  7. Повертайте слово без змін, якщо жодного поділу не вдалося зробити.

Я вибрав ці правила, оскільки вони можуть застосовуватися рекурсивно без проблем і не потребують таблиць вимови. Таким чином, вони не точні, і, наприклад, правило №5 часто не є правильним. У загальному випадку все-таки є.

Приклад

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

Ви впевнені x-e-non? Посилання на правило №4?
Джон Дворак

@JanDvorak "Коли слово розділене, почніть знову з правої половини слова", після чого слід правило 6.
seequ

Я маю на увазі, чи не повинен правило №4 розділяти лише склади?
Джон Дворак

1
Правило №1 стосується чотирьох літер слів. А як щодо слів, які мають менше чотирьох літер? наприкладlua
Digital Trauma

1
@DigitalTrauma Зазвичай вони оживають, але рідко мають два склади.
seequ

Відповіді:


6

Рубін, 144 байти

Якщо ми будемо робити немислимі, як щодо єдиного гігантського виразка?

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

деякий вихід:

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

Луа, 292

Луа, можливо, не була найкращою мовою для цього, але це працює. Це в значній мірі тече, як поставлене питання. Правила в основному в порядку з деякими оптимізаціями: №2 пропускається (вона не потрібна, якщо на початку немає одного голосного слова з "ck"), і правила ck і y проходять раніше, ніж решта # 4 і №6, які поєднуються. Оскільки деякі голосні слова мають захоплюватися двічі (після однієї дефісу та перед іншою), цей пошук виконується двічі.

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

Безумовно

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

Перевірте це тут: http://ideone.com/g57TzA


У мене немає рубіну, але, здається, справді добре.
seequ

4

Bash + coreultils, 173 байт

Я думаю, що я змінив усі останні правила:

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 \ 

Зверніть увагу, що останнім символом останнього рядка є (пробіл).

Я думаю, що це достатньо задовольняє "нечитабельне та неможливе" ;-)

Бере вхід від STDIN.

Переважно прямі заміни регулярного виразка. Перший рядок sedвиразу відповідає правилам 1 і 2, потім просто переходить до :xмітки в кінці виразу.

В trи на початку і кінці трубопроводу робить слова Newline розділеними, тому вони легше sedмати справу. Я сподівався зробити і всі sedвідповісти, але цей спосіб простіший і легший.

Приклад:

$ ./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, я постійно забуваю, що правило №3 було змінено. Все добре.
seequ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.