Spoonerise words… em finlandês

19

Esse desafio é baseado e contém casos de teste de um curso de programação que fiz na Universidade de Aalto. O material é usado com permissão.

Dois anos e meio atrás, havia um desafio sobre os Spoerisms em inglês . No entanto, em Spoerisms finlandeses são muito mais complicados.

Spoonerisms em finlandês

Em finlandês, as vogais são aeiouyäöe as consoantes são bcdfghjklmnpqrstvwxz. ( åé tecnicamente parte do finlandês, mas não é considerado aqui.)

Os colheristas mais básicos usam apenas a primeira vogal de cada palavra e as consoantes que as precedem e trocam as partes:

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

Vogais longas

Algumas palavras contêm duas da mesma vogal consecutiva. Nesses casos, o par de vogais deve ser trocado pela primeira vogal da outra palavra, encurtando ou alongando vogais para manter o mesmo comprimento.

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

No caso de duas vogais consecutivas diferentes, isso não se aplica:

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

Três ou mais da mesma letra consecutiva não aparecerão na entrada.

Harmonia da vogal

O finlandês tem essa coisa adorável chamada harmonia de vogais . Basicamente, isso significa que as vogais traseiras aou e vogais frontais äöy não devem aparecer na mesma palavra.

Quando trocar dianteiras ou traseiras vogais em uma palavra, todas as vogais de outro tipo no resto da palavra deve ser alterada para coincidir com o novo início da palavra ( a <-> ä, o <-> ö, u <-> y):

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

ee isão neutros e podem aparecer com todas as outras letras; trocá-los por uma palavra não deve causar alterações no restante da palavra.

Casos especiais

A harmonia da vogal não se aplica a algumas palavras, incluindo muitas palavras de empréstimo e palavras compostas. Esses casos não precisam ser tratados "corretamente".

Desafio

Dadas duas palavras, produza as palavras misturadas.

As palavras de entrada conterão apenas os caracteres a-ze äö. Você pode optar por usar maiúsculas ou minúsculas, mas sua escolha deve ser consistente entre as palavras e a entrada / saída.

A E / S pode ser feita em qualquer formato conveniente . (As palavras devem ser consideradas cadeias ou matrizes de caracteres.)

Isso é , então a solução mais curta em bytes vence.

Casos de teste

PurkkaKoodari
fonte
Podemos escolher uma codificação de entrada / saída? Além disso, é aceitável exigir que a entrada use diacríticos combinados em vez de caracteres únicos?
Maçaneta
@ Doorknob Você pode escolher qualquer codificação, mas o texto estará em NFC (ou seja, sem caracteres combinados). Uma codificação pode ser um caso de compatibilidade com alguns idiomas, mas NFC / NFD provavelmente não. (Qualquer coisa que pode lidar U+0308 COMBINING DIAERESISdeve lidar U+00E4 LATIN SMALL LETTER A WITH DIAERESISmuito bem.)
PurkkaKoodari
1
Desde ee isão neutros, são fihus keksy, huvu lehye lesmä prihtirespostas aceitáveis para kehys fiksu, levy huhue prisma lehti, respectivamente?
precisa
1
Como comentário lateral: por causa das vogais longas e da harmonia das vogais, o Spoerism finlandês não é uma função involutória . Por exemplo: puoskari äyskäri --> äöskäri puuskari --> puoskari ääskäri.
Arnauld
@ Arnauld No. Vou atualizar a pergunta; vogais neutras não devem causar alterações.
PurkkaKoodari 28/06

Respostas:

9

JavaScript (ES6), 196 175 bytes

Pega as palavras como duas strings na sintaxe de currying (a)(b). Retorna uma matriz de duas matrizes 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)]

Experimente online!

Quão?

Cada palavra de entrada é passada pela expressão regular e , que possui 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

A função auxiliar g () leva todos os grupos de captura da palavra a serem atualizados como [] e o primeiro e o segundo grupos de captura da palavra como c e v .

Aplicamos o Spoerism básico e cuidamos de vogais longas com:

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

Para aplicar a harmonia das vogais, primeiro coagimos a expressão regular e a uma string, adicionando-a a ela mesma, o que fornece:

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

As vogais que precisam ser harmonizadas têm uma posição maior que 9 na sequência resultante. Além disso, a expressão foi organizada de tal maneira que as vogais dianteiras estão localizadas em posições pares, enquanto as vogais traseiras também estão localizadas em posições ímpares, próximas às suas contrapartes.

Daí a seguinte fórmula de conversão que é aplicada a cada caractere c da palavra de saída:

(j = e.search(v), i = e.search(c)) > 9 & j > 9 ? e[i & ~1 | j & 1] : c
Arnauld
fonte
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,[]))

Experimente online!


Salvou

  • -2 bytes, graças a Lynn
  • -4 bytes, graças a Zacharý
TFeld
fonte
2
Salve dois bytes com:fr' ?(.*?([ei{B+F}]))(\2)?(\w*)'
Lynn
1
Ainda melhor: você pode mudar a segunda linha para S='äöy','aou', em seguida, na quinta linha: (F,B)=> Se (B,F)=> S[::-1](Isto é incompatível com a sugestão @Lynn deu)
Zachary
Além disso, você pode alterar a quarta linha para e,r,Q,W=re.findall(r' ?(.*?([eiaouäöy]))(\2)?(\w*)'*2,a+' '+b)[0][2:5]por mais alguns bytes salvos.
Zachary
O que eu quis dizer: 2ª linha para S=F,B='aöy','aou', e depois na 4ª linha, mude (F,B)para S.
Zachary
S=F,B=...deve economizar alguns bytes se você substituir (F,B)comS
Zachary
0

Pitão, 84 bytes

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

Experimente online. Suíte de teste.

Provando que não é que difícil em linguagens de golfe. Um idioma baseado em pilha pode se sair ainda melhor.

Pyth usa ISO-8859-1 por padrão, assim äöcomo um byte cada.

Explicação

  • Q, contendo o par de palavras de entrada, é anexado implicitamente.
  • m: mapeie cada palavra dna entrada para:
    • :"^([^A*)([A)(\\2)*(.+)"\A"aeiouyäö]": substitua Apor aeiouyäö]na sequência para obter a regex ^([^aeiouyäö]*)([aeiouyäö])(\2)*(.+).
    • :d: encontre todas as correspondências e retorne seus grupos de captura.
    • h: faça a primeira (e única) partida.
    • t: solta o primeiro grupo que contém a correspondência inteira.
  • _B: emparelhe com o reverso para obter [[first, second], [second, first]].
  • .b: mapeie cada par de palavras N, Ypara:
    • hY: pegue as consoantes iniciais da segunda palavra.
    • @N2: faça a primeira vogal longa da primeira palavra ou None.
    • htY: faça a primeira vogal da segunda palavra.
    • J: salve isso em J.
    • *W2: Se houver uma vogal longa, duplique a vogal da segunda palavra.
    • +: acrescente isso às consoantes.
    • c2"aouäöy": dividido aouäöyem dois para obter ["aou", "äöy"].
    • @DJ: classifique o par por interseção com a primeira vogal da segunda palavra. Isso chega à metade com a primeira vogal da segunda palavra no final do par.
    • A: salve o par em G, H.
    • e: pegue a segunda metade.
    • }J: veja se a primeira vogal da segunda palavra está na segunda metade.
    • XWeNGH: Se foi, mapeie Gpara Hno sufixo da primeira palavra, caso contrário, mantenha o sufixo como está.
    • +: acrescente o sufixo.
PurkkaKoodari
fonte