정규식 (ECMAScript를 풍미) 392 358 328 224 206 165 바이트
피보나치 수를 ECMAScript 정규식 (단항)과 일치시키기 위해 필요한 기술은 대부분의 다른 정규식에서 가장 잘 수행되는 방법과는 거리가 멀습니다. 순방향 / 중복 역 참조 또는 재귀가 없으면 총계를 직접 계산하거나 유지하는 것이 불가능합니다. 뒤돌아보기가 부족하여 작업하기에 충분한 공간을 확보해야하는 경우가 많습니다.
많은 문제는 완전히 다른 관점에서 접근해야하며, 중요한 통찰력이 도착할 때까지는 해결할 수없는 것처럼 보입니다. 작업중 인 숫자의 수학적 속성을 사용하여 특정 문제를 해결할 수있게하는 데 더 넓은 그물을 캐스트해야합니다.
2014 년 3 월에 피보나치 수에 대해 이런 일이 발생했습니다. Wikipedia 페이지를 살펴보면 처음에는 방법을 알아낼 수 없었지만 특정 속성 하나가 열광적으로 가깝게 보였습니다. 그런 다음 수학자 teukon 은 그 속성을 다른 속성과 함께 사용하여 가능하다는 것을 분명히하는 방법을 설명했습니다. 그는 실제로 정규 표현식을 만드는 것을 꺼려했습니다. 내가 가서 그것을했을 때 그의 반응 :
넌 미쳤어! ... 나는 당신이 이것을 할 것이라고 생각했습니다.
다른 ECMAScript 단항 수학 정규 표현식 게시물과 마찬가지로 경고를 표시합니다. ECMAScript 정규 표현식에서 단항 수학 문제를 해결하는 방법을 배우는 것이 좋습니다. 그것은 나를 위해 매혹적인 여행이었고, 나는 그것을 스스로 시도하고 싶을지도 모르는 사람, 특히 수 이론에 관심이있는 사람들을 위해 그것을 망치고 싶지 않습니다. 스포일러 태그가 붙은 권장 문제를 하나씩 해결하는 데 대한 목록은 해당 게시물 을 참조하십시오 .
따라서 단항 정규식 마술이 당신을 망치고 싶지 않다면 더 이상 읽지 마십시오 . 이 마법을 스스로 파악하는 데 총력을 기울이고 싶다면 위에 링크 된 게시물에 요약 된 ECMAScript 정규식의 일부 문제를 해결하는 것이 좋습니다.
내가 처음 직면 한 도전은 : 양의 정수 X는 피보나치 번호 만 배 경우 경우 2 + 4 및 / 또는 5 배 2 - 4 완벽한 광장입니다. 그러나 정규 표현식에서는 이것을 계산할 여지가 없습니다. 우리가 작업해야하는 유일한 공간은 숫자 자체입니다. 우리는 5를 곱 하거나 정사각형을 취할 공간이 충분하지 않습니다 .
그것을 해결하는 방법에 대한 teukon의 아이디어 ( 원래 여기에 게시 됨 ) :
정규식은 ^x*$
z 형식의 문자열로 표시되며 z는 길이입니다. z가 손으로 처음 몇 피보나치 수 중 하나인지 여부를 확인하십시오 (최대 21 개). 그렇지 않은 경우 :
- b가 2a보다 크지 않도록 두 개의 숫자 a <b를 읽습니다.
- 전방 예측을 사용하여 a 2 , ab 및 b 2를 작성하십시오 .
- 하나 5A 주장 2 + 4 또는 5A 2 4 완벽한 사각형 (그래서이 F이어야합니다 -는 N-1 일부 N)입니다.
- 5b 2 + 4 또는 5b 2 + 4가 완전 제곱 임을 가정하십시오 (따라서 b는 F n 이어야합니다 ).
- 이전에 빌드 한 a 2 , ab 및 b 2 와 ID 를 사용하여 z = F 2n + 3 또는 z = F 2n + 4인지 확인하십시오.
- F 2n-1 = F n 2 + F n-1 2
- F 2n = (2F n-1 + F n ) F n
간단히 말해서, 이러한 정체성들은 우리가 주어진 숫자가 피보나치인지 확인하는 문제를 훨씬 더 작은 숫자 쌍이 피보나치인지 확인하는 문제를 줄일 수있게합니다 . 작은 대수는 충분히 큰 n (n = 3 이해 야 함), F 2n + 3 > F n + 5F n 2 + 4에 대해 항상 충분한 공간이 있어야 함을 보여줍니다.
그리고 여기 에 정규식에서 구현하기 전에 테스트로 작성한 C의 알고리즘 모형이 있습니다.
따라서 더 이상 고민하지 말고 여기에 정규식이 있습니다.
^((?=(x*).*(?=x{4}(x{5}(\2{5}))(?=\3*$)\4+$)(|x{4})(?=xx(x*)(\6x?))\5(x(x*))(?=(\8*)\9+$)(?=\8*$\10)\8*(?=(x\2\9+$))(x*)\12)\7\11(\6\11|\12)|x{0,3}|x{5}|x{8}|x{21})$
온라인으로 사용해보십시오!
그리고 잘 인쇄되고 주석이 달린 버전 :
^(
(?=
(x*) # \2+1 = potential number for which 5*(\2+1)^2 ± 4
# is a perfect square; this is true iff \2+1 is a Fibonacci
# number. Outside the surrounding lookahead block, \2+1 is
# guaranteed to be the largest number for which this is true
# such that \2 + 5*(\2+1)^2 + 4 fits into the main number.
.*
(?= # tail = (\2+1) * (\2+1) * 5 + 4
x{4}
( # \3 = (\2+1) * 5
x{5}
(\2{5}) # \4 = \2 * 5
)
(?=\3*$)
\4+$
)
(|x{4}) # \5 = parity - determined by whether the index of Fibonacci
# number \2+1 is odd or even
(?=xx (x*)(\6 x?)) # \6 = arithmetic mean of (\2+1) * (\2+1) * 5 and \8 * \8,
# divided by 2
# \7 = the other half, including remainder
\5
# require that the current tail is a perfect square
(x(x*)) # \8 = potential square root, which will be the square root
# outside the surrounding lookahead; \9 = \8-1
(?=(\8*)\9+$) # \10 = must be zero for \8 to be a valid square root
(?=\8*$\10)
\8*
(?=(x\2\9+$)) # \11 = result of multiplying \8 * (\2+1), where \8 is larger
(x*)\12 # \12 = \11 / 2; the remainder will always be the same as it
# is in \7, because \8 is odd iff \2+1 is odd
)
\7\11
(
\6\11
|
\12
)
|
x{0,3}|x{5}|x{8}|x{21} # The Fibonacci numbers 0, 1, 2, 3, 5, 8, 21 cannot be handled
# by our main algorithm, so match them here; note, as it so
# happens the main algorithm does match 13, so that doesn't
# need to be handled here.
)$
곱셈 알고리즘은 그 의견에 설명되어 있지 않지만 풍부한 숫자 regex post 의 단락에 간단히 설명되어 있습니다.
나는 피보나치 정규식의 여섯 가지 버전을 유지하고 있었다. 가장 짧은 길이에서 가장 빠른 속도로 래칫하고 위에서 설명한 알고리즘을 사용하는 네 가지 버전과 다른, 훨씬 더 빠르지 만 훨씬 더 긴 알고리즘을 사용하는 두 가지 버전을 실제로 유지했다. 일치하는 피보나치 인덱스 (여기서는 알고리즘이이 게시물의 범위를 벗어나지 만 설명 은 원래 토론 Gist )에 설명 되어 있습니다. 나는 PCRE와 Perl에서 모든 테스트를 수행 할 때 정규식의 많은 비슷한 버전의 정규식을 다시 유지하지 않을 것이라고 생각하지만 내 정규식 엔진 속도에 대한 관심이 더 이상 중요하지 않을 정도로 충분히 빠릅니다 (특정 구조가 병목 현상을 일으키는 경우 최적화를 추가 할 수 있습니다) – 아마도 하나의 가장 빠른 버전과 하나의 가장 짧은 버전을 다시 유지해야 할 것입니다. 속도가 충분히 컸습니다.
"피보나치 지수에서 1을 뺀 값을 일치로 반환"버전 (심하게 골프를 치지 않음) :
온라인으로 사용해보십시오!
모든 버전은 골프 최적화의 전체 커밋 히스토리와 함께 github에 있습니다.
피보나치 수 일치에 대한 정규식 - 짧은 속도 0.txt (포스트와 같이 최단하지만 최저 하나)
피보나치 수 일치에 대한 정규식 - 짧은 속도 1.TXT의
정규식 피보나치 수를 일치시키기 위해 - 짧은 속도 2.txt에
대한 정규식 피보나치 수와 일치-짧고 속도
피보나치 수 와 일치하는 3.txt 정규식 -fast.txt 피보나치 수와 일치하는 정규식 -return
index.txt