해파리 , 45 바이트
p
\Ai
\&
>(&]&|0
<*&d
&~bN
10
( )/+
/*
온라인으로 사용해보십시오!
설명
이것은 지금까지 내가 해파리에서 작성한 가장 정교한 (그리고 가장 긴) 프로그램입니다. 이해할 수있는 방식으로 이것을 분해 할 수 있을지 모르겠지만 시도해야 할 것 같습니다.
Jellyfish는 상당히 일반적인 반복 연산자를 제공하여 \
"Nth 무언가 찾기"에 많은 도움이됩니다 . 그 의미 중 하나는 "별도의 테스트 함수가 진실한 것을 줄 때까지 값에 함수를 인용"입니다 (실제로 테스트 함수는 현재 요소와 마지막 요소를 모두 받지만 현재 요소 만 보도록합니다) . 이것을 사용하여 "다음 유효한 숫자"기능을 구현할 수 있습니다. 또 다른 과부하 \
는 "시작 값에 N 번 함수를 반복"입니다. 이전 함수를 사용하여 0
N 번 반복 할 수 있습니다 . 여기서 N은 입력입니다. 이 모든 것은 코드 의이 부분과 상당히 간결하게 설정됩니다.
p
\Ai
\&
> 0
( 0
결과 함수에 대한 실제 입력 인 이유 는 약간 복잡하기 때문에 여기서 다루지 않겠습니다.)
이 모든 문제는 현재 값을 테스트 기능에 수동으로 전달하지 않는다는 것입니다. \
운영자는 우리를 위해이 작업을 수행 할 것입니다. 이제 우리는 하나의 단항 함수 (구성, 후크, 포크 및 카레를 통해)를 구성하여 숫자를 가져 와서 유효한 숫자인지 여부를 알려줍니다 (즉, 숫자 합계와 숫자 제품으로 나눈 함수). 인수를 참조 할 수없는 경우 이는 사소한 것이 아닙니다. 이제까지. 이 아름다움입니다.
(&]&|
<*&d
&~bN
10
( )/+
/*
은 (
단항이며 후크 는 아래의 기능 (호출하는 수단과, f
그 입력에) (현재 값 x
), 및 그 오른쪽 (상기 테스트 기능에 모두 전달 g
이 연산이다) g(f(x), x)
.
우리의 경우, f(x)
숫자 곱과 숫자 합과 쌍을 얻는 또 다른 복합 함수입니다 x
. 즉 g
, x
유효한지 확인하기 위해 세 가지 값이 모두있는 함수가 됩니다.
f
자릿수와 자릿수 곱을 계산하는 방법부터 살펴 보겠습니다 . 이것은 f
:
&~b
10
( )/*
/+
&
또한 구성입니다 (그러나 다른 방향으로). ~
currying 10~b
은 숫자의 십진수를 계산하는 함수를 제공합니다. 우리는 그것을 &
오른쪽에서 전달 하기 때문에 입력에서 일어날 첫 번째 일입니다 x
. 나머지는이 자릿수 목록을 사용하여 합계와 곱을 계산합니다.
합을 계산하기 위해, 우리는 수 배 이다, 그 위에 추가 /+
. 마찬가지로 곱을 계산하기 위해 곱셈을 접습니다 /*
. 한 쌍으로 이러한 결과를 모두 결합하려면, 우리는 한 쌍의 후크를 사용 (
하고 )
. 이것의 구조는 다음과 같습니다.
()g
f
(어디 f
와 g
각각 제품과 합입니다.)이 우리에게 한 쌍을 제공하는 이유하자의 시도는 파악 f(x)
하고 g(x)
. 오른쪽 후크 )
에는 하나의 인수 만 있습니다. 이 경우 다른 인수는 ;
인수를 한 쌍으로 묶는 것으로 간주됩니다. 또한 후크는 이진 함수 (여기서는 여기에 해당)로도 사용할 수 있으며,이 경우 내부 함수를 하나의 인수에만 적용합니다. 따라서 실제로 )
하나 g
의 함수에서 계산하는 함수를 제공합니다 [x, g(y)]
. 이것을 왼쪽 고리에 사용하여 f
를 얻습니다 [f(x), g(y)]
. 이것은 차례로 단항 컨텍스트에서 사용 x == y
되므로 실제로 호출 [f(x), g(x)]
되어 필요에 따라 끝납니다 . 휴
그것은 우리의 초기 테스트 기능인 한 가지만 남습니다 g
. 이를이라한다 리콜 g([p, s], x)
여기서 x
여전히 현재의 입력 값은 p
그 자리 제품 및 s
그 자리 합이다. 이것은 g
:
&]&|
<*&d
N
분할 성을 테스트하기 위해 |
Jellyfish에 있는 모듈로를 사용 합니다. 다소 특이하게, 그것은 오른쪽 피연산자 모듈로 왼쪽 피연산자를 취합니다. 즉, 인수가 g
올바른 순서로 이미 있음을 의미합니다 (이와 같은 산술 함수는 목록을 자동으로 스레드하므로 두 개의 개별 모듈러스를 무료로 계산합니다) . 결과가 0의 쌍이면 우리의 숫자는 곱과 합으로 나눌 수 있습니다. 이러한 경우인지 확인하기 위해 쌍을 기본 2 자리 ( d
) 목록으로 취급합니다 . 쌍의 두 요소가 모두 0 인 경우에만이 결과가 0이므로 N
두 값이 입력을 나누는 지 여부에 대한 정확한 값을 얻기 위해이 결과를 무시할 수 있습니다. 그 주 |
, d
및N
단순히 모두 &
s 쌍으로 구성됩니다 .
불행히도, 그것은 전체 이야기가 아닙니다. 숫자 곱이 0이면 어떻게 되나요? 0으로 나누기와 모듈로는 해파리에서 0을 반환합니다. 이것은 다소 이상한 규칙처럼 보일지 모르지만 실제로는 다소 유용합니다 (모듈로를 수행하기 전에 0을 확인할 필요가 없기 때문에). 그러나 또한 숫자 합이 입력을 나누지 만 숫자 곱이 0이면 (예 : input 10
) 오 탐지를 얻을 수 있음을 의미 합니다.
우리는이 분산 결과에 숫자 곱을 곱하여이 문제를 해결할 수 있습니다 (따라서 숫자 곱이 0이면 진솔한 값도 0이됩니다). 나누기 결과에 곱과 합을 곱하고 나중에 그 결과를 추출하는 것이 더 간단합니다.
결과에 쌍을 곱하려면 이전 값 (쌍)으로 돌아와야합니다. 이것은 포크 ( ]
)로 수행됩니다 . 포크는 일종의 스테로이드 고리입니다. 당신이 그 (것)들에게 두 가지 기능을 제공하는 경우 f
와 g
, 그들은 계산하는 이항 함수를 나타냅니다 f(a, g(a, b))
. 우리의 경우, a
제품 / 합계 쌍이고 b
, 현재 입력 값이며, g
우리의 분할 성 테스트이며 f
곱셈입니다. 따라서이 모든 것이 계산 [p, s] * ([p, s] % x == [0, 0])
됩니다.
이제 남은 것은 이터레이터에서 사용 된 테스트 함수의 최종 값인 첫 번째 값을 추출하는 것입니다. 이것은 head 함수로 &
포크를 작성 ( )하는 것만 큼 간단 합니다.리스트의 첫 번째 값을 리턴합니다.<