Подпишите слова… по-фински


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 байт

Принимает слова как две строки в синтаксисе карри (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 () принимает все группы захвата слова, которые должны быть обновлены как a [], а первую и вторую группы захвата другого слова - как 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

Python 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]сохранить еще несколько байтов.
Захари

Что я хотел сказать: 2-я строка S=F,B='aöy','aou', а затем на 4-й строке изменить (F,B)на S.
Захари

S=F,B=...следует сохранить несколько байтов, если заменить (F,B)наS
Zacharý

0

Pyth, 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: посмотреть, если первый гласный второго слова во второй половине.
    • XW... eNGH: если она была, карта Gс Hсуффиксом первого слова, в противном случае держать суффикс как есть.
    • +: добавьте суффикс.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.