CJam (69 바이트)
]qi:X,{1e|,:):N{N\f{1$%!*}W$.*:+}%1$W%.*:+N,/+}/W\+_1,*X=\_W%.*:+-Y/z
온라인 데모
설명
기본 아이디어는 OEIS에 설명 된 생성 기능을 구현하는 것입니다. 입력 은 불쾌한 특별한 경우이지만, 마지막으로 조정 한 결과 이 생성 되어 (절대 값의 경우)가 정리됩니다. 이것이 가장 이상한 트릭입니다.0−1z
.*:+
를 세 번 반복하고로 추출하면 바이트를 절약 할 수있는 것처럼 보입니다 {.*:+}:F~
. 그러나 이것은 외부 루프를 전혀 실행하지 않기 때문에 특별한 경우 중단됩니다 .0
항이 반복되는 A000081 의 보조 생성 기능을 사용합니다.
a[0] = 0
a[1] = 1
For n >= 1, a[n+1] = (sum_{k=1}^n a[n-k+1] * sum_{d|k} d * a[d]) / n
일부 언어에는 역 뫼비우스 변환 내장 된 언어가 있지만 CJam은 그렇지 않습니다. 내가 찾은 가장 좋은 방법은 배열 매핑 구축하는 것입니다 에 다음으로 점별 곱셈을 할 사용 . 편리 여기 참고 쌓아합니다 가중치를 설정할 때 우리가 0으로 피할 부문에 원하기 때문에, 인덱스 1부터 시작. 또한 포인트 단위 연산에 제공된 두 배열의 길이가 동일하지 않으면 더 긴 배열의 값은 그대로 유지됩니다. 따라서 우리는 의 첫 번째 항을 취 하거나 가중치 배열을 이동시켜야합니다∑d∣kd×a[d]dk % d == 0 ? d : 0
a.*
akan. 후자는 더 짧아 보입니다. 따라서이 역 뫼비우스 변환은N\f{1$%!*}W$.*:+
역모 비우스 변환의 결과를 호출하면 M
이제
a[n+1]=1n∑k=1na[n−k+1]×M[k]
분자는 분명히 컨볼 루션의 용어이므로 또는 의 사본을 뒤집은 다음 점별 곱셈과 합산을 통해 처리 할 수 있습니다 . 다시, 우리의 인덱스는 에서 까지 다양 하며, 또한 에 하는 인덱스를 쌍으로 묶기를 원 하므로 0이 아닌 1에서 를 인덱스 것이 편리합니다. 이제 우리는 설명했습니다.aM1nn+1a
qi:X,{ ,:):N{N\f{1$%!*}W$.*:+}%1$W%.*:+N,/+}/
보조 생성 기능의 포인트는 A000055의 공식 섹션에 의해 제공됩니다.
G.f.: A(x) = 1 + T(x) - T^2(x)/2 + T(x^2)/2,
where T(x) = x + x^2 + 2*x^3 + ... is the g.f. for A000081.
와 관련 , 우리가 찾는 출력은a
[x=0]+a[x]+12(a[x/2]−∑i=0na[i]×a[n−i])
여기서위한 홀수 우리 0. 얻을 I 그렇게 발견 한 최단의 방법은 제로 (함께 팽창한다 ), 그리고, x 번째의 요소를 가지고 ( ).a[x/2]x1,*
X=
합계는 또 다른 컨볼 루션이지만 이번에는 0부터 색인을 작성하는 것이 편리합니다. 확실한 해결책은 0\+
이지만 여기에는 약간의 최적화가 있습니다. 이후 , 회선의 두 조건이 보장 제로한다. 이것을 1부터 색인 할 수있는 기회로 삼을 수 있지만 특별한 경우 은 추악합니다. 대신 에 컨볼 루션을 사용하면 되며 빼기 및 나눈 후 항을 처리했습니다 합계 밖에서도.a[0]=0X=0W\+
−2a[x]+∑ni=0a[i]×a[n−i]2a[x]
그래서 우리는 설명했습니다
qi:X,{ ,:):N{N\f{1$%!*}W$.*:+}%1$W%.*:+N,/+}/W\+_1,*X=\_W%.*:+-Y/
나머지 세부 사항은 특별한 경우와 관련이 있습니다. I 원래 함께 시작하여 더 엄격 재발 하였다 1]
로부터 반복 로N=1
1]qi:X,1>{ ... }/
그 결과, 우리가 계산이다 으로 우리가 필요로하는 것보다 더 한 학기를 :. 인플레이션과 컨벌루션은 의 결과를 제공합니다 . (아마도 우리가 바라는 것보다 낫습니다. 우리가 이라는 용어에 대해 아무 것도하지 않았기 때문에 우리가 가져야 할 것 입니다.) 그래서 우리는 최종적으로 또는 표준 "대체"기술을 사용하여 세 개의 문자를 수정합니다 .X=0a[-1 1]
0[x=0]X!+
1e|
의 "오른쪽"길이 얻으려면 우리는 초기 공급 피할 필요가 로 메인 루프에서 생산하는 대신에, 그리고 . 완전히 간단한a1N=0
]qi:X,{ ... /+}/
분명히 0으로 나누기를 제공합니다. 그러나 우리가 시도하면
]qi:X,{1e| ... /+}/
그런 다음 작동합니다. 우리는 얻는다
e# Stack: [] 0
1e| e# Stack: [] 1
,:):N e# Stack: [] [1]
{ e# We only execute this loop once
N\f{1$%!*} e# 1 divides 1, so stack: [] [1]
W$.* e# Remember: if the two arrays supplied to the pointwise operation
e# are not the same length then the values from the longer one are
e# left untouched. Stack: [] [1]
:+ e# Fold over a singleton. Stack: [] 1
}% e# And that was a map, so stack: [] [1]
1$W%.*:+ e# Another [1] [] .*:+, giving the same result: 1
N,/ e# 1 / 1 = 1
+ e# And we append 1 to a giving [1]
필요한 값을 정확하게 생성합니다
이제 이면 주 루프가 실행되지 않으므로 맨 아래에 을 해킹 한 후 우리는를 얻습니다 . 우리는 컴퓨팅 끝내는데 , 이는 올바르지 않습니다. 그러나 수정하는 동안X=0−1[-1]
(−1−12(−1×−1))=−101−11z