Спунсерські слова… фінською мовою


19

Цей виклик ґрунтується на тестах з програмування, які я пройшов в університеті Аалто та містить його тестові приклади . Матеріал використовується з дозволу.

Два з половиною роки тому був виклик щодо спонсеризмів англійською мовою . Однак у фінських спонерізми набагато складніші.

Спонсоризми фінською мовою

У фінській aeiouyäöмові голосні є, а приголосні - bcdfghjklmnpqrstvwxz. ( åтехнічно є частиною фінської, але тут не розглядається.)

Найбільш основні спонсеризми приймають лише першу голосну частину кожного слова та будь-які приголосні, що передують їм, та обмінюються частинами:

henri kontinen -> konri hentinen
tarja halonen -> harja talonen
frakki kontti -> kokki frantti
ovi kello -> kevi ollo

Довгі голосні

Деякі слова містять два однакових послідовних голосних. У цих випадках пару голосних потрібно замінити першою голосною іншого слова, скорочуючи або подовжуючи голосні, щоб зберегти однакову довжину.

haamu kontti -> koomu hantti
kisko kaappi -> kasko kiippi

У разі двох різних послідовних голосних це не стосується:

hauva kontti -> kouva hantti
puoskari kontti -> kooskari puntti

Три або більше таких самих послідовних листів не відображатимуться на вводі.

Гармонія голосних

У фінській є ця прекрасна річ, яка називається гармонією голосних . В основному це означає, що задні голосні aou та передні голосні äöy не повинні міститися в одному слові.

Коли заміна передніх або задніх голосних звуків в слові, всі голосні іншого роду в іншій частині слова повинні бути змінені відповідно до нового початок слова ( a <-> ä, o <-> ö, u <-> y):

yhä kontti -> kouha ntti
hauva läähättää -> yvä haahattaa

eі iвони нейтральні і можуть з’являтися з усіма іншими літерами; заміна їх на слово не повинна спричиняти змін до решти слова.

Особливі випадки

Гармонія голосних не поширюється на деякі слова, включаючи багато позитивних слів і складні слова. Ці справи не потрібно розбирати "правильно".

Виклик

Давши два слова, виведіть слова спонсоровані.

Введені слова містять лише символи a-zта äö. Ви можете скористатися великими або малими літерами, але ваш вибір повинен відповідати як словам, так і введенням / вихідним.

Введення / виведення може бути виконано у будь-якому зручному форматі . (Слова слід вважати рядками або масивами символів.)

Це , тому найкоротше рішення в байтах виграє.

Тестові справи


Чи можемо ми вибрати кодування вводу / виводу? Крім того, чи прийнятно вимагати, щоб вхід використовував поєднуючи діакритику замість окремих символів?
Дверна ручка

@Doorknob Ви можете вибрати будь-яке кодування, але текст буде у форматі NFC (тобто відсутні поєднання символів). Кодування може бути випадком сумісності з деякими мовами, але NFC / NFD, ймовірно, не буде. (Все, що може впоратися, U+0308 COMBINING DIAERESISмає справлятися U+00E4 LATIN SMALL LETTER A WITH DIAERESISчудово.)
PurkkaKoodari

1
Так як eі iє нейтральними, є fihus keksy, huvu lehyі lesmä prihtiприйнятні відповіді на kehys fiksu, levy huhuі , prisma lehtiвідповідно?
Арнольд

1
В якості побічного коментаря: через довгі голосні голоси та гармонію голосних фінський спонерізм не є функцією, що займається . Наприклад: puoskari äyskäri --> äöskäri puuskari --> puoskari ääskäri.
Арнольд

@Arnauld Ні. Я оновлю питання; нейтральні голосні не повинні спричиняти змін.
PurkkaKoodari

Відповіді:


9

JavaScript (ES6), 196 175 байт

Сприймає слова як два рядки в синтаксисі currying (a)(b). Повертає масив з двох масивів символів.

a=>b=>[(e=/(.*?)([eiäaöoyu])(\2?)(.*)/,g=(a,[,c,v])=>[...c+v+(a[3]&&v)+a[4]].map(c=>(j=e.search(v),i=e.search(c))>9&j>9?e[i&~1|j&1]:c))(a=e.exec(a),b=e.exec(b),e+=e),g(b,a)]

Спробуйте в Інтернеті!

Як?

Кожне введене слово передається через регулярний вираз e , який має 4 групи захоплення:

e = /(.*?)([eiäaöoyu])(\2?)(.*)/    1: leading consonants (or empty)
     [ 1 ][     2    ][ 3 ][ 4]     2: first vowel
                                    3: doubled first vowel (or empty)
                                    4: all remaining characters

Допоміжна функція g () приймає всі групи захоплення слова для оновлення як [], а першу та другу групи захоплення іншого слова як c і v .

Ми застосовуємо основний спонеризм і піклуємося про довгі голосні з:

c + v + (a[3] && v) + a[4]

Щоб застосувати гармонію голосних, спочатку примушуємо регулярний вираз e до рядка, додаючи його до себе, що дає:

e = "/(.*?)([eiäaöoyu])(\2?)(.*)//(.*?)([eiäaöoyu])(\2?)(.*)/"
     ^^^^^^^^^^^^^^^^
     0123456789ABCDEF (position as hexa)

Голосні голоси, які потрібно узгодити, мають позицію, що перевищує 9, у отриманому рядку. Крім того, вираз було влаштовано таким чином , що передні голосні äöy розташовані на парних позиціях, в той час як назад голосні AOU розташовані на непарних позиціях, поряд зі своїми колегами.

Звідси наступна формула перекладу, яка застосовується до кожного символу c вихідного слова:

(j = e.search(v), i = e.search(c)) > 9 & j > 9 ? e[i & ~1 | j & 1] : c

4

Пітон 3 , 235 231 225 221 217 215 байт

import re
S=F,B='äöy','aou'
def f(a,b,C=1):
 e,r,Q,W=re.findall(fr' ?(.*?([ei{B+F}]))(\2)?(\w*)'*2,a+' '+b)[0][2:6]
 for c in zip(*S*(W in B)+(B,F)*(W in F)):r=r.replace(*c)
 return[Q+W*len(e)+r]+(C and f(b,a,[]))

Спробуйте в Інтернеті!


Збережено

  • -2 байти, завдяки Лінні
  • -4 байти, завдяки Захарі

2
Збережіть два байти за допомогою:fr' ?(.*?([ei{B+F}]))(\2)?(\w*)'
Лінн

1
Ще краще: ви можете змінити другий рядок на S='äöy','aou', потім на п’ятому рядку: (F,B)=> Sі (B,F)=> S[::-1](Це несумісне з пропозицією @Lynn дав)
Zacharý

Крім того, ви можете змінити четвертий рядок на e,r,Q,W=re.findall(r' ?(.*?([eiaouäöy]))(\2)?(\w*)'*2,a+' '+b)[0][2:5]ще кілька збережених байтів.
Zacharý

Що я мав на увазі сказати: 2-й рядок на S=F,B='aöy','aou', а потім на 4-му рядку змінити (F,B)на S.
Zacharý

S=F,B=...Ви повинні заощадити кілька байтів, якщо заміните (F,B)наS
Zacharý

0

Піт, 84 байти

.b++hY*W@N2JhtY2XW}JeA@DJc2"aouäöy"eNGH_Bmth:d:"^([^A*)([A)(\\2)*(.+)"\A"aeiouyäö]"4

Спробуйте в Інтернеті. Тестовий набір.

Доводячи , що це не так, що важко в мовах гольфу. Мова на основі стека може зробити ще краще.

Pyth використовує ISO-8859-1 за замовчуванням, тому äöпо одному байту.

Пояснення

  • Q, що містить вхідну пару слів, додається неявно.
  • m: зіставте кожне слово dу вхідному тексті на:
    • :"^([^A*)([A)(\\2)*(.+)"\A"aeiouyäö]"Замініть Aз aeiouyäö]в рядку , щоб отримати регулярний вираз ^([^aeiouyäö]*)([aeiouyäö])(\2)*(.+).
    • :d: знайти всі матчі та повернути свої групи захоплення.
    • h: взяти перший (і єдиний) матч.
    • t: киньте першу групу, що містить всю відповідність.
  • _B: пари з реверсом, щоб отримати [[first, second], [second, first]].
  • .b: картографуйте кожну пару слів N, Yу цьому:
    • hY: прийміть початкові приголосні другого слова.
    • @N2: візьміть довгий перший голосний першого слова, або None.
    • htY: взяти перший голосний другого слова.
    • J: зберегти це в J.
    • *W2: Якщо був голосний довгий, дублюйте голосний другий слово.
    • +: додайте це до приголосних.
    • c2"aouäöy": розділити aouäöyна два, щоб отримати ["aou", "äöy"].
    • @DJ: сортуйте пару за перетином з першою голосною другого слова. Це отримує половину з першою голосною другого слова в кінці пари.
    • A: збережіть пару до G, H.
    • e: взяти другу половину.
    • }J: подивіться, чи є перший голосний другого слова у другій половині.
    • XWeNGH: Якщо це було, переведіть Gна Hсуфікс першого слова, інакше збережіть суфікс як є.
    • +: додайте суфікс.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.