Spoonerise words… 핀란드어


19

이 과제는 Aalto University에서 수강 한 프로그래밍 과정을 기반으로하며 테스트 사례를 포함 합니다. 재료는 허가를 받아 사용됩니다.

2 년 반 전에 영어로 된 숟가락에 대한 도전이있었습니다 . 그러나 핀란드어에서는 sperisms가 훨씬 더 복잡합니다.

핀란드의 숟가락

핀란드어에서는 모음이 aeiouyäö있고 자음은 bcdfghjklmnpqrstvwxz입니다. ( å기술적으로 핀란드의 일부이지만 여기서는 고려되지 않습니다.)

가장 기본적인 숟가락은 각 단어의 첫 모음과 그 앞에 나오는 자음을 가져 와서 그 부분을 교환합니다.

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

긴 모음

일부 단어에는 동일한 연속 모음 중 두 개가 포함되어 있습니다. 이 경우 모음 쌍을 다른 단어의 첫 모음과 바꾸어 모음을 줄이거 나 길게하여 길이를 동일하게 유지해야합니다.

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

두 개의 다른 연속 모음 의 경우 에는 적용되지 않습니다.

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

동일한 연속 문자 중 3 개 이상이 입력에 나타나지 않습니다 .

모음 조화

핀란드어는 모음 조화 라는이 사랑스러운 것을 가지고 있습니다. 기본적으로 뒷 모음 aou앞 모음 äöy 이 같은 단어로 나타나지 않아야 함을 의미합니다 .

단어로 전면 또는 후면 모음을 교환 할 때, 단어의 나머지 부분에서 다른 종류의 모든 모음은 단어의 새로운 시작에 맞게 변경해야합니다 ( a <-> ä, o <-> ö, u <-> y) :

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

e그리고 i중립적 모든 다른 문자로 표시 될 수 있습니다; 그것들을 단어로 바꾸어도 나머지 단어 변경되어서 는 안됩니다 .

특수한 상황들

모음 대출은 많은 대출 단어와 복합 단어를 포함하여 일부 단어에는 적용되지 않습니다. 이러한 경우를 "올바로"처리 할 필요는 없습니다.

도전

두 단어가 주어지면, 그 단어는 깎아서 나옵니다.

입력 단어에는 문자 a-z와 만 포함됩니다 äö. 대문자 또는 소문자를 사용하도록 선택할 수 있지만 단어와 입력 / 출력 모두에서 선택해야합니다.

I / O는 편리한 형식 으로 수행 할 수 있습니다 . 단어는 문자열 또는 문자 배열로 간주해야합니다.

이것은 이므로 바이트 단위의 최단 솔루션이 이깁니다.

테스트 사례


입력 / 출력 인코딩을 선택할 수 있습니까? 또한 입력에 단일 문자 대신 분음 부호를 결합하도록 요구할 수 있습니까?
Doorknob

@Doorknob 어떤 인코딩이든 선택할 수 있지만 텍스트는 NFC로 표시됩니다 (예 : 결합 문자 없음). 인코딩은 일부 언어와 호환되는 경우가 있지만 NFC / NFD는 그렇지 않을 수 있습니다. (처리 U+0308 COMBINING DIAERESIS할 수있는 모든 것이 U+00E4 LATIN SMALL LETTER A WITH DIAERESIS잘 처리 해야 합니다.)
PurkkaKoodari

1
사람 ei, 중성이다 fihus keksy, huvu lehylesmä prihti허용 응답 kehys fiksu, levy huhuprisma lehti각각?
Arnauld

1
부수적 인 의견으로 : 모음과 모음의 조화가 길기 때문에 핀란드어 스페셜 리즘은 관여 하지 않습니다 . 예를 들면 다음과 같습니다 puoskari äyskäri --> äöskäri puuskari --> puoskari ääskäri.
Arnauld

@Arnauld 아니요. 질문을 업데이트하겠습니다. 중립 모음은 변경되지 않아야합니다.
PurkkaKoodari

답변:


9

자바 스크립트 (ES6), 196 175 바이트

카레 구문에서 단어를 두 개의 문자열로 사용합니다 (a)(b). 두 문자 배열로 구성된 배열을 반환합니다.

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

온라인으로 사용해보십시오!

어떻게?

각 입력 단어는 4 개의 캡처 그룹이있는 정규식 e를 통해 전달됩니다 .

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 () 는 단어의 모든 캡처 그룹을 a [] 로 업데이트 하고 다른 단어의 첫 번째 및 두 번째 캡처 그룹을 cv 로 가져옵니다 .

기본 숟가락을 사용하고 긴 모음을 다음과 같이 관리합니다.

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

모음 조화를 적용하려면 먼저 정규식 e 를 문자열에 추가 하여 정규 표현식 e 를 강요 합니다.

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

조화되어야하는 모음은 결과 문자열에서 9보다 큰 위치를 갖습니다. 또한이 표현은 앞 모음 äöy 가 짝수 위치에 있고 뒷 모음 aou 가 상대방 옆의 홀수 위치 에 있도록 배열되었습니다 .

따라서 다음 단어는 출력 단어의 각 문자 c 에 적용됩니다 .

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

4

파이썬 (3) , 235 (231) 225 221 217 215 바이트

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

온라인으로 사용해보십시오!


저장되었습니다

  • Lynn 덕분에 -2 바이트
  • Zacharý 덕분에 -4 바이트

2
다음을 사용하여 두 바이트를 저장하십시오.fr' ?(.*?([ei{B+F}]))(\2)?(\w*)'
Lynn

1
더 나은 : 당신은 두 번째 라인을 변경할 수 있습니다 S='äöy','aou'다섯 번째 줄에 다음 : (F,B)=> S(B,F)=> S[::-1](이 @Lynn 준 제안과 호환되지 않습니다)
재커리

또한 e,r,Q,W=re.findall(r' ?(.*?([eiaouäöy]))(\2)?(\w*)'*2,a+' '+b)[0][2:5]몇 바이트를 더 절약 하기 위해 네 번째 줄을 변경할 수 있습니다 .
Zacharý

내가 말하고자하는 것 : 두 번째 줄에서로 S=F,B='aöy','aou', 네 번째 줄에서로 변경 (F,B)되었습니다 S.
Zacharý

S=F,B=...당신이 대체 할 경우 몇 바이트를 저장해야합니다 (F,B)으로S
재커리

0

Pyth, 84 바이트

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

온라인으로 사용해보십시오. 테스트 스위트.

골프 언어가 그렇게 어렵지 않다는 것을 증명 . 스택 기반 언어가 더 좋습니다.

Pyth는 기본적으로 ISO-8859-1을 사용하므로 äö각각 1 바이트입니다.

설명

  • Q입력 단어 쌍을 포함하는에는 암시 적으로 추가됩니다.
  • m: d입력의 각 단어 를 다음에 맵핑 하십시오.
    • :"^([^A*)([A)(\\2)*(.+)"\A"aeiouyäö]": 대체 Aaeiouyäö]정규 표현식을 얻을 수있는 문자열 ^([^aeiouyäö]*)([aeiouyäö])(\2)*(.+).
    • :d: 모든 경기를 찾아 그들의 캡처 그룹을 반환합니다.
    • h: 첫 번째 (및 유일한) 일치를 가져옵니다.
    • t: 전체 경기가 포함 된 첫 번째 그룹을 삭제합니다.
  • _B: 리버스와 페어링하여 가져옵니다 [[first, second], [second, first]].
  • .b: 각 단어 쌍을 다음에 맵핑하십시오 N, Y.
    • hY: 두 번째 단어의 시작 자음을 가져갑니다.
    • @N2: 첫 단어의 첫 번째 모음을 가져 오거나 None.
    • htY: 두 번째 단어의 첫 번째 모음을 가져옵니다.
    • J:에 저장하십시오 J.
    • *W2: 모음이 긴 경우 두 번째 단어 모음을 복제합니다.
    • +: 자음에 추가하십시오.
    • c2"aouäöy": aouäöy두 개로 나누면 얻을 수 ["aou", "äöy"]있습니다.
    • @DJ: 두 번째 단어의 첫 번째 모음과 교차하여 쌍을 정렬합니다. 이것은 쌍의 끝에 두 번째 단어의 첫 번째 모음으로 절반을 얻습니다.
    • A: 쌍을에 저장합니다 G, H.
    • e: 후반전.
    • }J: 두 번째 단어의 첫 번째 모음이 후반에 있는지 확인하십시오.
    • XWeNGH:있는 경우 첫 단어의 접미사에 매핑 G하고 H, 그렇지 않으면 접미사를 그대로 유지합니다.
    • +: 접미사를 추가하십시오.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.