Kata-kata spoonerise ... dalam bahasa Finlandia

19

Tantangan ini didasarkan pada, dan berisi uji kasus dari, kursus pemrograman yang saya ikuti di Universitas Aalto. Materi digunakan dengan izin.

Dua setengah tahun yang lalu ada tantangan tentang spoonerisme dalam bahasa Inggris . Namun, dalam spoonerisme Finlandia jauh lebih rumit.

Spoonerisme dalam bahasa Finlandia

Dalam bahasa Finlandia, vokal adalah aeiouyäödan konsonan adalah bcdfghjklmnpqrstvwxz. ( åsecara teknis bagian dari bahasa Finlandia, tetapi tidak dipertimbangkan di sini.)

Spoonerisme paling dasar hanya mengambil vokal pertama dari setiap kata, dan setiap konsonan yang mendahuluinya, dan menukar bagian-bagiannya:

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

Vokal panjang

Beberapa kata mengandung dua vokal berturut-turut yang sama. Dalam kasus tersebut, pasangan vokal harus ditukar dengan vokal pertama kata lain, memperpendek atau memperpanjang vokal agar panjangnya tetap sama.

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

Dalam hal dua vokal berturut-turut yang berbeda ini tidak berlaku:

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

Tiga atau lebih huruf berturut-turut yang sama tidak akan muncul di input.

Harmoni vokal

Bahasa Finlandia memiliki hal yang indah yang disebut harmoni vokal . Pada dasarnya, ini berarti bahwa vokal belakang aou dan vokal depan äöy tidak boleh muncul dengan kata yang sama.

Ketika swapping depan atau belakang vokal dalam kata, semua vokal dari jenis lain di sisa kata harus diubah agar sesuai dengan awal baru dari kata ( a <-> ä, o <-> ö, u <-> y):

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

edan inetral dan dapat muncul dengan semua surat lainnya; menukarnya dengan kata tidak boleh menyebabkan perubahan pada kata lainnya.

Kasus khusus

Harmoni vokal tidak berlaku untuk beberapa kata, termasuk banyak kata pinjaman dan kata majemuk. Kasus-kasus ini tidak perlu ditangani "dengan benar".

Tantangan

Diberi dua kata, tampilkan kata-kata spoonerised.

Kata-kata input hanya akan berisi karakter a-zdan äö. Anda dapat memilih untuk menggunakan huruf besar atau kecil, tetapi pilihan Anda harus konsisten antara kata dan input / output.

I / O dapat dilakukan dalam format yang mudah . (Kata-kata harus dianggap string atau array karakter.)

Ini adalah , jadi solusi terpendek dalam byte menang.

Uji kasus

PurkkaKoodari
sumber
Bisakah kita memilih pengkodean input / output? Juga, apakah dapat diterima untuk meminta agar input menggunakan kombinasi diakritik alih-alih karakter tunggal?
Gagang Pintu
@ Doorknob Anda dapat memilih pengodean apa pun, tetapi teks akan menggunakan NFC (yaitu tidak ada kombinasi karakter). Pengkodean mungkin merupakan kasus kompatibilitas dengan beberapa bahasa, tetapi NFC / NFD mungkin tidak. (Apa pun yang dapat menangani U+0308 COMBINING DIAERESISharus ditangani dengan U+00E4 LATIN SMALL LETTER A WITH DIAERESISbaik-baik saja.)
PurkkaKoodari
1
Karena edan inetral, apakah fihus keksy, huvu lehydan lesmä prihtijawaban yang dapat diterima kehys fiksu, levy huhudan prisma lehtimasing - masing?
Arnauld
1
Sebagai komentar sampingan: karena vokal yang panjang dan harmoni vokal, spoonerisme Finlandia bukanlah fungsi yang disengaja . Misalnya: puoskari äyskäri --> äöskäri puuskari --> puoskari ääskäri.
Arnauld
@Arnauld Tidak. Saya akan memperbarui pertanyaan; vokal netral seharusnya tidak menyebabkan perubahan.
PurkkaKoodari

Jawaban:

9

JavaScript (ES6), 196 175 byte

Mengambil kata sebagai dua string dalam sintaks currying (a)(b). Mengembalikan array dua array karakter.

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

Cobalah online!

Bagaimana?

Setiap kata input dilewatkan melalui ekspresi reguler e , yang memiliki 4 grup penangkap:

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

Fungsi helper g () mengambil semua grup penangkap kata untuk diperbarui sebagai [] dan grup penangkap pertama dan kedua dari kata lain sebagai c dan v .

Kami menerapkan spoonerisme dasar dan menangani vokal panjang dengan:

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

Untuk menerapkan harmoni vokal, pertama-tama kita memaksa ekspresi reguler e ke string dengan menambahkannya sendiri, yang memberikan:

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

Vokal yang perlu diselaraskan memiliki posisi lebih besar dari 9 pada string yang dihasilkan. Lebih jauh, ekspresi diatur sedemikian rupa sehingga vokal depan äöy berada di posisi genap, sedangkan vokal belakang Anda berada di posisi ganjil, di sebelah rekan-rekan mereka.

Maka rumus terjemahan berikut yang diterapkan pada setiap karakter c dari kata keluaran:

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

Python 3 , 235 231 225 221 217 215 byte

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

Cobalah online!


Diselamatkan

  • -2 byte, terima kasih untuk Lynn
  • -4 byte, terima kasih kepada Zacharý
TFeld
sumber
2
Simpan dua byte dengan:fr' ?(.*?([ei{B+F}]))(\2)?(\w*)'
Lynn
1
Lebih baik lagi: Anda dapat mengubah baris kedua menjadi S='äöy','aou', kemudian pada baris kelima: (F,B)=> Sdan (B,F)=> S[::-1](Ini tidak sesuai dengan saran yang diberikan @Lynn)
Zacharý
Anda juga dapat mengubah baris keempat e,r,Q,W=re.findall(r' ?(.*?([eiaouäöy]))(\2)?(\w*)'*2,a+' '+b)[0][2:5]untuk menyimpan beberapa byte lagi.
Zacharý
Apa yang ingin saya katakan: baris ke-2 S=F,B='aöy','aou', dan kemudian pada baris ke-4 ubah (F,B)menjadi S.
Zacharý
S=F,B=...harus menyimpan beberapa byte jika Anda ganti (F,B)denganS
Zacharý
0

Pyth, 84 byte

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

Cobalah online. Suite uji.

Membuktikan bahwa itu tidak yang keras dalam bahasa golf. Bahasa berbasis tumpukan mungkin lebih baik.

Pyth menggunakan ISO-8859-1 secara default, jadi äömasing-masing satu byte.

Penjelasan

  • Q, yang mengandung pasangan input kata, ditambahkan secara implisit.
  • m: memetakan setiap kata ddalam input ke:
    • :"^([^A*)([A)(\\2)*(.+)"\A"aeiouyäö]": ganti Adengan aeiouyäö]dalam string untuk mendapatkan regex ^([^aeiouyäö]*)([aeiouyäö])(\2)*(.+).
    • :d: temukan semua kecocokan dan kembalikan grup penangkapnya.
    • h: ambil pertandingan pertama (dan satu-satunya).
    • t: jatuhkan grup pertama yang berisi seluruh pertandingan.
  • _B: pasangkan dengan terbalik untuk mendapatkan [[first, second], [second, first]].
  • .b: memetakan setiap pasangan kata N, Yke:
    • hY: ambil konsonan awal kata kedua.
    • @N2: ambil vokal pertama panjang dari kata pertama, atau None.
    • htY: ambil vokal pertama dari kata kedua.
    • J: simpan itu di J.
    • *W... 2: jika ada vokal panjang, duplikat vokal kata kedua.
    • +: menambahkan itu ke konsonan.
    • c2"aouäöy": dibagi aouäöydua untuk mendapatkan ["aou", "äöy"].
    • @DJ: urutkan pasangan berdasarkan persimpangan dengan vokal pertama dari kata kedua. Ini mendapat setengah dengan vokal pertama kata kedua di akhir pasangan.
    • A: simpan pasangan ke G, H.
    • e: ambil babak kedua.
    • }J: lihat apakah vokal pertama kata kedua ada di babak kedua.
    • XWeNGH: Jika ya, petakan Gke Hdalam akhiran kata pertama, jika tidak biarkan sufiks apa adanya.
    • +: tambahkan akhiran.
PurkkaKoodari
sumber