Spoonerise mots… en finnois

19

Ce défi est basé sur, et contient des cas de test, d' un cours de programmation que j'ai suivi à l'Université Aalto. Le matériel est utilisé avec permission.

Il y a deux ans et demi, il y avait un défi concernant les spoonerismes en anglais . Cependant, dans les spoonerismes finlandais sont beaucoup plus compliqués.

Spoonerismes en finnois

En finnois, les voyelles sont aeiouyäöet les consonnes le sont bcdfghjklmnpqrstvwxz. ( åfait techniquement partie du finnois, mais n'est pas considéré ici.)

Les cuillerées les plus élémentaires ne prennent que la première voyelle de chaque mot, et toutes les consonnes qui les précèdent, et échangent les parties:

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

Voyelles longues

Certains mots contiennent deux de la même voyelle consécutive. Dans ces cas, la paire de voyelles doit être échangée avec la première voyelle de l'autre mot, raccourcissant ou allongeant les voyelles pour garder la même longueur.

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

Dans le cas de deux voyelles consécutives différentes, cela ne s'applique pas:

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

Trois ou plus de la même lettre consécutive n'apparaîtront pas dans l'entrée.

Harmonie vocalique

Le finnois a cette belle chose appelée harmonie des voyelles . Fondamentalement, cela signifie que les voyelles arrière aou et les voyelles avant äöy ne doivent pas apparaître dans le même mot.

Lorsque la permutation des voyelles avant ou arrière en un mot, toutes les voyelles de l'autre type dans le reste du mot devrait être changé pour correspondre au nouveau début du mot ( a <-> ä, o <-> ö, u <-> y):

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

eet isont neutres et peuvent apparaître avec toutes les autres lettres; les échanger en un mot ne doit pas entraîner de modifications dans le reste du mot.

Cas spéciaux

L'harmonie des voyelles ne s'applique pas à certains mots, y compris de nombreux mots de prêt et mots composés. Ces cas ne doivent pas être traités "correctement".

Défi

Étant donné deux mots, sortez les mots spoonerised.

Les mots saisis ne contiendront que les caractères a-zet äö. Vous pouvez choisir d'utiliser des majuscules ou des minuscules, mais votre choix doit être cohérent entre les mots et les entrées / sorties.

Les E / S peuvent être effectuées dans n'importe quel format pratique . (Les mots doivent être considérés comme des chaînes ou des tableaux de caractères.)

Il s'agit de , donc la solution la plus courte en octets l'emporte.

Cas de test

PurkkaKoodari
la source
Pouvons-nous choisir un encodage d'entrée / sortie? Est-il également acceptable d'exiger que l'entrée utilise la combinaison de signes diacritiques au lieu de caractères uniques?
Poignée de porte
@ Doorknob Vous pouvez choisir n'importe quel encodage, mais le texte sera en NFC (c'est-à-dire pas de combinaison de caractères). Un encodage peut être un cas de compatibilité avec certaines langues, mais NFC / NFD ne le sera probablement pas. (Tout ce qui peut gérer U+0308 COMBINING DIAERESISdevrait U+00E4 LATIN SMALL LETTER A WITH DIAERESIStrès bien fonctionner.)
PurkkaKoodari
1
Depuis eet isont neutres, sont fihus keksy, huvu lehyet des lesmä prihtiréponses acceptables pour kehys fiksu, levy huhuet prisma lehtirespectivement?
Arnauld
1
Comme commentaire secondaire: à cause des voyelles longues et de l'harmonie des voyelles, le spoonerism finlandais n'est pas une fonction involutive . Par exemple: puoskari äyskäri --> äöskäri puuskari --> puoskari ääskäri.
Arnauld
@Arnauld Non. Je mettrai à jour la question; les voyelles neutres ne devraient provoquer aucun changement.
PurkkaKoodari

Réponses:

9

JavaScript (ES6), 196 175 octets

Prend les mots comme deux chaînes dans la syntaxe de curry (a)(b). Renvoie un tableau de deux tableaux de caractères.

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

Essayez-le en ligne!

Comment?

Chaque mot d'entrée passe par l'expression régulière e , qui a 4 groupes de capture:

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

La fonction d'assistance g () prend tous les groupes de capture du mot à mettre à jour en tant que [] et les premier et deuxième groupes de capture de l'autre mot en c et v .

Nous appliquons le spoonerisme de base et prenons soin des voyelles longues avec:

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

Pour appliquer l'harmonie des voyelles, nous contraignons d'abord l'expression régulière e à une chaîne en l'ajoutant à elle-même, ce qui donne:

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

Les voyelles qui doivent être harmonisées ont une position supérieure à 9 dans la chaîne résultante. De plus, l'expression a été arrangée de telle manière que les voyelles avant äöy sont situées à des positions paires, tandis que les voyelles arrières aou sont situées à des positions impaires, à côté de leurs homologues.

D'où la formule de traduction suivante qui s'applique à chaque caractère c du mot de sortie:

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

Python 3 , 235 231 225 221 217 215 octets

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

Essayez-le en ligne!


Enregistré

  • -2 octets, merci à Lynn
  • -4 octets, merci à Zacharý
TFeld
la source
2
Économisez deux octets avec:fr' ?(.*?([ei{B+F}]))(\2)?(\w*)'
Lynn
1
Encore mieux: vous pouvez changer la deuxième ligne en S='äöy','aou', puis sur la cinquième ligne: (F,B)=> Set (B,F)=> S[::-1](Ceci est incompatible avec la suggestion donnée par @Lynn)
Zacharý
En outre, vous pouvez modifier la quatrième ligne e,r,Q,W=re.findall(r' ?(.*?([eiaouäöy]))(\2)?(\w*)'*2,a+' '+b)[0][2:5]pour quelques octets supplémentaires enregistrés.
Zacharý
Ce que je voulais dire: 2e ligne à S=F,B='aöy','aou', puis sur la 4e ligne, changez (F,B)pour S.
Zacharý
S=F,B=...devrait économiser quelques octets si vous remplacez (F,B)parS
Zacharý
0

Pyth, 84 octets

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

Essayez-le en ligne. Suite de tests.

Prouver que ce n'est pas si difficile dans les langues de golf. Un langage basé sur la pile pourrait faire encore mieux.

Pyth utilise ISO-8859-1 par défaut, donc äöun octet chacun.

Explication

  • Q, contenant la paire de mots d'entrée, est ajoutée implicitement.
  • m: mappez chaque mot dde l'entrée sur:
    • :"^([^A*)([A)(\\2)*(.+)"\A"aeiouyäö]": remplacez Apar aeiouyäö]dans la chaîne pour obtenir l'expression régulière ^([^aeiouyäö]*)([aeiouyäö])(\2)*(.+).
    • :d: recherchez tous les matchs et renvoyez leurs groupes de capture.
    • h: prendre le premier (et unique) match.
    • t: supprimer le premier groupe contenant l'intégralité du match.
  • _B: paire avec revers pour obtenir [[first, second], [second, first]].
  • .b: mappez chaque paire de mots N, Ydans celle-ci pour:
    • hY: prenez les consonnes de début du deuxième mot.
    • @N2: prendre la première voyelle longue du premier mot, ou None.
    • htY: prendre la première voyelle du deuxième mot.
    • J: enregistrez-le dans J.
    • *W2: S'il y avait une voyelle longue, dupliquer la voyelle du deuxième mot.
    • +: ajoutez cela aux consonnes.
    • c2"aouäöy": divisé aouäöyen deux pour obtenir ["aou", "äöy"].
    • @DJ: trie la paire par intersection avec la première voyelle du deuxième mot. Cela obtient la moitié avec la première voyelle du deuxième mot à la fin de la paire.
    • A: enregistrer la paire dans G, H.
    • e: prendre la seconde moitié.
    • }J: voir si la première voyelle du deuxième mot est dans la seconde moitié.
    • XWeNGH: Si tel est le cas, mappez- Gle Hdans le suffixe du premier mot, sinon conservez le suffixe tel quel .
    • +: ajoutez le suffixe.
PurkkaKoodari
la source