프랙탈 시퀀스의 수렴


16

배경

프랙탈 시퀀스 는 모든 정수의 첫 번째 발생을 제거하고 이전과 동일한 순서로 끝날 수있는 정수 시퀀스이다.

이러한 간단한 시퀀스를 Kimberling 's paraphrases 라고 합니다. 양수로 시작하십시오.

1, 2, 3, 4, 5, 6, 7, 8, 9, ...

그런 다음 몇 가지 빈칸으로 리플 링하십시오.

1, _, 2, _, 3, _, 4, _, 5, _, 6, _, 7, _, 8, _, 9, ...

그런 다음 시퀀스 자체 (공백 포함)로 빈칸을 반복적으로 채 웁니다.

1, 1, 2, _, 3, 2, 4, _, 5, 3, 6, _, 7, 4, 8, _, 9, ...
1, 1, 2, 1, 3, 2, 4, _, 5, 3, 6, 2, 7, 4, 8, _, 9, ...
1, 1, 2, 1, 3, 2, 4, 1, 5, 3, 6, 2, 7, 4, 8, _, 9, ...
1, 1, 2, 1, 3, 2, 4, 1, 5, 3, 6, 2, 7, 4, 8, 1, 9, ...

이것이 우리의 프랙탈 시퀀스입니다! 이제 부분 합계를 보자.

1, 2, 4, 5, 8, 10, 14, 15, 20, 23, 29, 31, 38, 42, 50, 51, 60, ...

그러나이 과정을 반복하면 어떻게 될까요? 새 시퀀스를 "실용화"(즉, 위 단계에서 얻은 부분 합) :

1, _, 2, _, 4, _, 5, _, 8, _, 10, _, 14, _, 15, _, 20, _, 23, ...
1, 1, 2, _, 4, 2, 5, _, 8, 4, 10, _, 14, 5, 15, _, 20, 8, 23, ...
1, 1, 2, 1, 4, 2, 5, _, 8, 4, 10, 2, 14, 5, 15, _, 20, 8, 23, ...
1, 1, 2, 1, 4, 2, 5, 1, 8, 4, 10, 2, 14, 5, 15, _, 20, 8, 23, ...
1, 1, 2, 1, 4, 2, 5, 1, 8, 4, 10, 2, 14, 5, 15, 1, 20, 8, 23, ...

그리고 부분 합계를 다시 가져옵니다.

1, 2, 4, 5, 9, 11, 16, 17, 25, 29, 39, 41, 55, 60, 75, 76, 96, ...

헹구고 반복하십시오. 이 과정이 수렴된다는 것이 밝혀졌습니다. 이 프로세스를 반복 할 때마다 시퀀스의 더 큰 접두사가 고정 된 상태로 유지됩니다. 무한 반복 후에는 OEIS A085765로 끝납니다 .

재미있는 사실 : 이 과정은 원래 시퀀스가로 시작하는 한 자연수에서 시작하지 않더라도 동일한 시퀀스로 수렴됩니다 1. 원래 시퀀스가 ​​다른로 시작 x하면 x*A085765대신에 얻을 수 있습니다.

도전

양의 정수가 주어지면 수렴 된 시퀀스 NNth 요소를 출력하십시오 .

STDIN (또는 가장 가까운 대안), 명령 행 인수 또는 함수 인수를 통해 입력을 받고 STDOUT (또는 가장 가까운 대안), 함수 리턴 값 또는 함수 (out) 매개 변수를 통해 결과를 출력하는 프로그램 또는 함수를 작성할 수 있습니다.

색인 N이 0 또는 1을 기준으로 할지 선택할 수 있습니다 .

테스트 사례

순서는 다음과 같이 시작합니다.

1, 2, 4, 5, 9, 11, 16, 17, 26, 30, 41, 43, 59, 64, 81, 82, 108, 117, 147, 151, 192, 203, 246, 248, 307, 323, 387, 392, 473, 490, 572, 573, 681, 707, 824, 833, 980, 1010, 1161, 1165, 1357, 1398, 1601, 1612, 1858, 1901, 2149, 2151, 2458, 2517

따라서 input 5은 output이어야합니다 9.

다음은 첫 번째 N숫자 를 생성 하는 순진한 CJam 참조 구현 입니다 ( NSTDIN에서 제공됨 ). 코드는 N전체 접두사가 아니라 th 요소 만 반환해야 합니다.


그래서 그냥 확인하십시오 : 우리는 A085765의N 용어를 출력하고 있습니까?
GamrCorps

@GamrCorps 예.
Martin Ender

답변:


7

CJam ( 23 22 바이트)

부분 합은 프랙탈 시퀀스의 짝수 색인 ( A086450)에 제공 됩니다. A086450의 정의로 제공된 반복은 이러한 구현의 기초입니다.

명시적인 "스택"사용 (LIFO가 아니기 때문에 따옴표로 표시) :

{),){2md~)\),>+$)}h+,}

온라인 데모

해부

{         e# Anonymous function body; for clarify, pretend it's f(x)
          e# We use a stack [x_0 ... x_i] with invariant: the result is sum_j f(x_j)
  ),      e# Initialise the stack to [0 ... x]
  )       e# Uncons x, because our loop wants one value outside the stack
  {       e# Loop. Stack holds [x_0 ... x_{i-1}] x_i
    2md   e# Split x_i into (x_i)/2 and (x_i)%2
    ~)\   e# Negate (x_i)%2 and flip under (x_i)/2
    ),>   e# If x_i was even, stack now holds [x_0 ... x_{i-1}] [0 1 ... (x_i)/2]
          e# If x_i was odd, stack now holds [x_0 ... x_{i-1}] [(x_i)/2]
    +     e# Append the two arrays
    $     e# Sort to get the new stack
    )     e# Uncons the greatest element in the new stack
  }h      e# If it is non-zero, loop
          e# We now have a stack of zeroes and a loose zero
  +,      e# Count the total number of zeroes, which is equivalent to sum_j f(0)
}

23 바이트에서는 메모를 사용하여 훨씬 효율적인 접근 방식이 있습니다.

{2*1a{2md~)\){j}%>:+}j}

온라인 데모


1
로 구현하는 것이 더 짧은 언어가 있다고 확신 f(0) = 1; f(n) = f(n/2) + (n % 2 ? 0 : f(n-2)); return f(2*x)하지만 CJam에서 그러한 접근 방식으로 비용을 절약 할 수있는 방법을 찾을 수 없습니다.
피터 테일러

9

파이썬 2, 55 49 42

무슨 일이 일어나고 있는지 모르겠지만 OEIS 페이지에서 메이플 공식을이기는 것은 어려워 보입니다. 0 기반 인덱싱을 사용합니다.

f=lambda n,t=0:n<1or f(n/2,n%2)-~-t*f(n-1)

-6 바이트의 @PeterTaylor에게 감사합니다.


성능에 신경 쓰지 않으면 6 자씩 쉽게 최적화 할 수 있습니다. 첫 번째 이후 부분 or은 효과적으로 g(n,1) = f(n/2,n%2); g(n,0) = f(n-1) + g(n,1); 그래서 당신은 g(n,1)얻을 공통점 을 꺼내 수 있습니다f=lambda n,t=0:n<1or f(n/2,n%2)+0**t*f(n-1)
피터 테일러

3

하스켈, 65

s l=[0..]>>=(\i->[l!!i,s l!!i])
r=1:(tail$scanl1(+)$s r)
f n=r!!n

2

유해한 템플릿 , 124

Fun<If<A<1>,Add<Ap<Fun<Ap<If<Sub<A<1>,Mul<I<2>,Div<A<1>,I<2>>>>,A<0>,A<0,1>>,Div<A<1>,I<2>>>>,A<1>>,Ap<A<0>,Sub<A<1>,T>>>,T>>

이것은 익명의 기능입니다. 모듈러스를 구현하지 않았다는 점을 제외하면 파이썬 이 OEIS 페이지의 메이플 공식에 응답 하는 것과 거의 비슷합니다. 따라서 n % 2 대신 nn / 2 * 2를 사용해야했습니다.

넓히는:

Fun<If<
    A<1>,
    Add<
        Ap<
            Fun<Ap<
                If<
                    Sub<
                        A<1>,
                        Mul<
                            I<2>,
                            Div<A<1>,I<2> >
                        >
                    >,
                    A<0>,
                    A<0,1>
                >,
                Div<A<1>,I<2>>
            >>,
            A<1>
        >,
        Ap<
            A<0>,
            Sub<A<1>, T>
        >
    >,
    T
>> 


0

MATLAB 108 103

원하는 시리즈가 https://oeis.org/A086450 의 부분 합이라는 사실을 사용하고 있습니다.

그러나이 간단한 재발에도 불구하고 구현의 계산 복잡성은 최적과는 거리가 멀습니다.

n=input('')+1;
z=zeros(1,n);z(1)=1;
for k=1:n;
z(2*k)=z(k);
z(2*k+1)=sum(z(1:k+1));
end;
disp(sum(z(1:n)))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.