Spoonerise palabras ... en finlandés

19

Este desafío se basa y contiene casos de prueba de un curso de programación que tomé en la Universidad de Aalto. El material se usa con permiso.

Hace dos años y medio hubo un desafío sobre los cucharares en inglés . Sin embargo, en finlandeses los cucharares son mucho más complicados.

Spoonerisms en finlandés

En finlandés, las vocales son aeiouyäöy las consonantes son bcdfghjklmnpqrstvwxz. ( åtécnicamente es parte del finlandés, pero no se considera aquí).

Los cucharares más básicos solo toman la primera vocal de cada palabra y las consonantes que las preceden, e intercambian las partes:

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

Vocales largas

Algunas palabras contienen dos de la misma vocal consecutiva. En esos casos, el par de vocales debe intercambiarse con la primera vocal de la otra palabra, acortando o alargando las vocales para mantener la misma longitud.

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

En el caso de dos vocales consecutivas diferentes, esto no se aplica:

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

Tres o más de la misma letra consecutiva no aparecerán en la entrada.

Armonía vocal

El finlandés tiene esta cosa encantadora llamada armonía vocal . Básicamente, significa que las vocales posteriores aou y las delanteras äöy no deberían aparecer en la misma palabra.

Cuando el canje de vocales delanteras o traseras en una palabra, todas las vocales de otro tipo en el resto de la palabra debe ser cambiado para que coincida con el nuevo comienzo de la palabra ( a <-> ä, o <-> ö, u <-> y):

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

ey ison neutrales y pueden aparecer con todas las demás letras; intercambiarlos en una palabra no debe causar cambios en el resto de la palabra.

Casos especiales

La armonía vocal no se aplica a algunas palabras, incluidas muchas palabras prestadas y palabras compuestas. No es necesario que estos casos se manejen "correctamente".

Desafío

Dadas dos palabras, da salida a las palabras en cuchara.

Las palabras de entrada solo contendrán los caracteres a-zy äö. Puede elegir usar mayúsculas o minúsculas, pero su elección debe ser coherente entre ambas palabras y entrada / salida.

La E / S se puede hacer en cualquier formato conveniente . (Las palabras deben considerarse cadenas o matrices de caracteres).

Este es el , por lo que gana la solución más corta en bytes.

Casos de prueba

PurkkaKoodari
fuente
¿Podemos elegir una codificación de entrada / salida? Además, ¿es aceptable exigir que la entrada use la combinación de signos diacríticos en lugar de caracteres individuales?
Pomo de la puerta
@Doorknob Puede elegir cualquier codificación, pero el texto estará en NFC (es decir, sin caracteres combinados). Una codificación puede ser un caso de compatibilidad con algunos idiomas, pero NFC / NFD probablemente no. (Cualquier cosa que pueda manejar U+0308 COMBINING DIAERESISdebería funcionar U+00E4 LATIN SMALL LETTER A WITH DIAERESISbien).
PurkkaKoodari
1
Dado ey ison neutros, son fihus keksy, huvu lehyy lesmä prihtirespuestas aceptables para kehys fiksu, levy huhuy prisma lehti, respectivamente?
Arnauld
1
Como comentario adicional : debido a las vocales largas y la armonía de las vocales, el cucharear finlandés no es una función involuntaria . Por ejemplo: puoskari äyskäri --> äöskäri puuskari --> puoskari ääskäri.
Arnauld
@Arnauld No. Actualizaré la pregunta; las vocales neutrales no deberían causar ningún cambio.
PurkkaKoodari

Respuestas:

9

JavaScript (ES6), 196 175 bytes

Toma las palabras como dos cadenas en sintaxis curry (a)(b). Devuelve una matriz de dos matrices de caracteres.

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

Pruébalo en línea!

¿Cómo?

Cada palabra de entrada se pasa a través de la expresión regular e , que tiene 4 grupos de captura:

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 función auxiliar g () toma todos los grupos de captura de la palabra para actualizarse como a [] y el primer y segundo grupos de captura de la otra palabra como c y v .

Aplicamos cuchara principal y cuidamos las vocales largas con:

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

Para aplicar la armonía vocal, primero coaccionamos la expresión regular e a una cadena agregándola a sí misma, lo que da:

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

Las vocales que deben armonizarse tienen una posición superior a 9 en la cadena resultante. Además, la expresión se organizó de tal manera que las vocales delanteras äöy están ubicadas en posiciones pares, mientras que las vocales traseras aou están ubicadas en posiciones impares, al lado de sus contrapartes.

De ahí la siguiente fórmula de traducción que se aplica a cada carácter c de la palabra de salida:

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

Python 3 , 235 231 225 221 217 215 bytes

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

Pruébalo en línea!


Salvado

  • -2 bytes, gracias a Lynn
  • -4 bytes, gracias a Zacharý
TFeld
fuente
2
Ahorre dos bytes con:fr' ?(.*?([ei{B+F}]))(\2)?(\w*)'
Lynn
1
Aún mejor: puede cambiar la segunda línea a S='äöy','aou', luego en la quinta línea: (F,B)=> Sy (B,F)=> S[::-1](Esto es incompatible con la sugerencia que dio @Lynn)
Zacharý
Además, puede cambiar la cuarta línea e,r,Q,W=re.findall(r' ?(.*?([eiaouäöy]))(\2)?(\w*)'*2,a+' '+b)[0][2:5]por unos pocos bytes más guardados.
Zacharý
Lo que quise decir: 2da línea a S=F,B='aöy','aou', y luego en la 4ta línea cambiar (F,B)a S.
Zacharý
S=F,B=...debería reemplazar algunos bytes si lo reemplaza (F,B)conS
Zacharý
0

Pyth, 84 bytes

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

Pruébalo en línea. Banco de pruebas.

Demostrando que no es que duro en idiomas golf. Un lenguaje basado en pila podría funcionar aún mejor.

Pyth usa ISO-8859-1 de forma predeterminada, por lo que äöson un byte cada uno.

Explicación

  • Q, que contiene el par de palabras de entrada, se agrega implícitamente.
  • m: asigna cada palabra den la entrada a:
    • :"^([^A*)([A)(\\2)*(.+)"\A"aeiouyäö]": reemplace Acon aeiouyäö]en la cadena para obtener la expresión regular ^([^aeiouyäö]*)([aeiouyäö])(\2)*(.+).
    • :d: busca todas las coincidencias y devuelve sus grupos de captura.
    • h: toma el primer (y único) partido.
    • t: suelta el primer grupo que contiene toda la coincidencia.
  • _B: emparejar con reverso para obtener [[first, second], [second, first]].
  • .b: asigna cada par de palabras N, Yen eso a:
    • hY: toma las consonantes iniciales de la segunda palabra.
    • @N2: toma la primera vocal larga de la primera palabra, o None.
    • htY: toma la primera vocal de la segunda palabra.
    • J: guardar eso en J.
    • *W2: Si había una vocal larga, duplica la vocal de la segunda palabra.
    • +: añádelo a las consonantes.
    • c2"aouäöy": dividido aouäöyen dos para llegar ["aou", "äöy"].
    • @DJ: ordena el par por intersección con la primera vocal de la segunda palabra. Esto obtiene la mitad con la primera vocal de la segunda palabra al final del par.
    • A: guardar el par en G, H.
    • e: toma la segunda mitad.
    • }J: ver si la primera vocal de la segunda palabra está en la segunda mitad.
    • XW... eNGH: si lo fuera, asignar Ga Hen el sufijo de la primera palabra, de lo contrario mantener el sufijo tal cual.
    • +: agregue el sufijo.
PurkkaKoodari
fuente