Kaşık kelimeler… Fince


19

Bu zorluk Aalto Üniversitesi'nde aldığım bir programlama kursuna dayanıyor ve test vakalarını içeriyor . Materyal izin alınarak kullanılır.

İki buçuk yıl önce İngilizcede kaşıkçılık konusunda bir zorluk vardı . Bununla birlikte, Finlandiya'da kaşıkçılık çok daha karmaşıktır.

Kaşıkçılık Fince

Fince, ünlüler aeiouyäöve ünsüzler bcdfghjklmnpqrstvwxz. ( åteknik olarak Fince'nin bir parçasıdır, ancak burada dikkate alınmaz.)

En temel kaşıkçılık sadece her kelimenin ilk sesli harfini ve onlardan önce gelen ünsüzleri alır ve parçaları değiştirir:

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

Uzun sesli harfler

Bazı kelimeler aynı ardışık sesli harflerden ikisini içerir. Bu durumlarda, sesli harf çifti, uzunluğu aynı tutmak için diğer kelimenin ilk sesli harfiyle, kısaltılmış veya uzatılmış sesli harflerle değiştirilmelidir.

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

İki farklı ardışık sesli harf için bu geçerli değildir:

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

Üç veya daha fazla aynı ardışık harfin olacak değil girişine görünür.

Sesli harf uyumu

Fince'nin sesli harf uyumu denen güzel bir şeyi vardır . Temel olarak, arka sesli aou ve ön sesli harflerin äöy aynı kelimede görünmemesi gerektiği anlamına gelir .

Bir kelimenin içine ön ya da arka ünlüleri takas zaman kelimenin geri kalan diğer türden tüm ünlüler kelimenin yeni bir başlangıcı eşleşecek şekilde değiştirilmelidir ( a <-> ä, o <-> ö, u <-> y):

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

eve inötr ve tüm diğer harfler ile görünebilir; bunları bir kelimeye dönüştürmek, kelimenin geri kalanında değişikliklere neden olmamalıdır .

Özel durumlar

Sesli harf uyumu, birçok kredi kelimesi ve bileşik sözcükler de dahil olmak üzere bazı kelimeler için geçerli değildir. Bu vakaların "doğru" ele alınmasına gerek yoktur.

Meydan okuma

İki kelime verildiğinde, kelimesi kelimesine çıktı.

Giriş kelimeler yalnızca karakter olacak a-zve äö. Büyük veya küçük harf kullanmayı seçebilirsiniz, ancak seçiminiz hem kelimeler hem de giriş / çıkış arasında tutarlı olmalıdır.

G / Ç herhangi bir uygun formatta yapılabilir . (Kelimeler dizeler veya karakter dizileri olarak düşünülmelidir.)

Bu , bu nedenle bayttaki en kısa çözüm kazanır.

Test senaryoları


Bir giriş / çıkış kodlaması seçebilir miyiz? Ayrıca, girdinin tek karakter yerine birleştirici aksan kullanmasını zorunlu kılar mı?
Kapı tokmağı

@Doorknob Herhangi bir kodlama seçebilirsiniz, ancak metin NFC'de olacaktır (yani birleştirme karakterleri içermez). Bir kodlama bazı dillerle uyumluluk olabilir, ancak NFC / NFD muhtemelen olmayacaktır. ( U+0308 COMBINING DIAERESISU+00E4 LATIN SMALL LETTER A WITH DIAERESIS
İşleyebilecek

1
Yana eve i, nötr olan fihus keksy, huvu lehyve lesmä prihtikabul edilebilir cevaplar kehys fiksu, levy huhuve prisma lehtisırası ile?
Arnauld

1
Bir yan yorum olarak: uzun ünlüler ve ünlü uyumu nedeniyle, Fin kaşıkçılığı invaziv bir işlev değildir . Örneğin: puoskari äyskäri --> äöskäri puuskari --> puoskari ääskäri.
Arnauld

Soruyu güncelleyeceğim; nötr ünlüler hiçbir değişikliğe neden olmamalıdır.
PurkkaKoodari

Yanıtlar:


9

JavaScript (ES6), 196 175 bayt

Sözdiziminde kelimeleri iki karakter dizisi olarak alır (a)(b). İki karakter dizisinden oluşan bir dizi döndürür.

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)]

Çevrimiçi deneyin!

Nasıl?

Her giriş kelimesi 4 yakalama grubuna sahip olan normal ifade e'den geçirilir :

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 () yardımcı işlevi , [] olarak güncellenecek sözcüğün tüm yakalama gruplarını ve diğer sözcüğün birinci ve ikinci yakalama gruplarını c ve v olarak alır .

Temel kaşıkçılık uyguluyoruz ve uzun sesli harflerle ilgileniyoruz:

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

Sesli harf uyumunu uygulamak için, önce düzenli ifadeyi e bir dizeye kendisine ekleyerek zorlarız:

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

Uyumlaştırılması gereken sesli harflerin sonuç dizesinde 9'dan büyük bir konumu vardır. Ayrıca, ifade şekilde düzenlenmiş ön sesli harf Aoy geri sesli harflerin ise, daha pozisyonlarda bulunan AOU karşılıkları yanında, tek pozisyonlarında yer alırlar.

Bu nedenle, çıktı kelimesinin her c karakterine uygulanan aşağıdaki çeviri formülü :

(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 bayt

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,[]))

Çevrimiçi deneyin!


Kayıtlı

  • -2 bayt, Lynn sayesinde
  • -4 bayt, Zacharý sayesinde

2
İki bayt ile şunları kaydedin:fr' ?(.*?([ei{B+F}]))(\2)?(\w*)'
Lynn

1
Daha da iyisi: İkinci satırı S='äöy','aou', daha sonra beşinci satır olarak değiştirebilirsiniz: (F,B)=> Sve (B,F)=> S[::-1](@Lynn'in verdiği öneriyle uyumsuzdur)
Zacharý

Ayrıca, e,r,Q,W=re.findall(r' ?(.*?([eiaouäöy]))(\2)?(\w*)'*2,a+' '+b)[0][2:5]kaydedilen birkaç bayt için dördüncü satırı değiştirebilirsiniz .
Zacharý

Ne demek istedi: 2 çizgi için S=F,B='aöy','aou', ve sonra 4 hat değişikliği (F,B)için S.
Eylül'de Zacharý

S=F,B=...(F,B)ile değiştirirseniz birkaç bayt kaydetmelisinizS
Zacharý

0

Pyth, 84 bayt

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

Çevrimiçi deneyin. Test odası.

Golf dillerinde bu kadar zor olmadığını kanıtlamak . Yığın tabanlı bir dil daha da iyi olabilir.

Pyth, varsayılan olarak ISO-8859-1 kullanır, äöher biri bir bayttır.

açıklama

  • Q, giriş kelimelerini içeren örtük olarak eklenir.
  • m: dgirişteki her kelimeyi şuna eşle:
    • :"^([^A*)([A)(\\2)*(.+)"\A"aeiouyäö]": normal ifadeyi almak için dizede Aile değiştirin .aeiouyäö]^([^aeiouyäö]*)([aeiouyäö])(\2)*(.+)
    • :d: tüm eşleşmeleri bulun ve yakalama gruplarını döndürün.
    • h: ilk (ve sadece) maçı yapın.
    • t: tüm eşleşmeyi içeren ilk grubu bırakma.
  • _B: almak için ters ile eşleyin [[first, second], [second, first]].
  • .b: içindeki her bir kelime çiftini şununla eşle N, Y:
    • hY: ikinci kelimenin başlangıç ​​ünsüzlerini al.
    • @N2: ilk kelimenin uzun ilk sesli harfini al veya None.
    • htY: ikinci kelimenin ilk sesli harfini al.
    • J: içine kaydedin J.
    • *W2: Uzun sesli bir harf varsa, ikinci kelimenin sesli harfini çoğaltın.
    • +: ünsüzlere ekleyin.
    • c2"aouäöy": aouäöyalmak için ikiye bölün ["aou", "äöy"].
    • @DJ: ikinci sözcüğün ilk sesli harfiyle kesişim noktasına göre çifti sıralayın. Bu, çiftin sonunda ikinci sözcüğün ilk sesli harfinin yarısını alır.
    • A: çifti kaydedin G, H.
    • e: ikinci yarıyı al.
    • }J: ikinci kelimenin ilk sesli harfinin ikinci yarıda olup olmadığına bakın.
    • XW... eNGH: o olsaydı, harita Giçin H, ilk kelimenin son eki olduğu gibi aksi eki tutun.
    • +: soneki ekle.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.