フラクタルシーケンスの収束和


16

バックグラウンド

フラクタルシーケンスは、あなたがすべての整数の最初の発生を削除し、前と同じ配列で終わることができ整数シーケンスです。

このような非常に単純なシーケンスは、キンバリングの言い換えと呼ばれます。正の自然数から始めます。

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ます。元のシーケンスがother xで始まる場合、x*A085765代わりに取得します。

チャレンジ

正の整数を指定すると、収束シーケンスのth番目の要素をN出力しNます。

プログラムまたは関数を作成し、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

したがって、入力5はoutputになります9

これは、最初のN数値(NSTDINで指定)を生成する単純なCJamリファレンス実装です。コードはN、プレフィックス全体ではなく、th要素のみを返すことに注意してください。


確認するだけです:A085765Nth項を出力していますか?
GamrCorps

@GamrCorpsはい。
マーティンエンダー

回答:


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

Python 2、55 49 42

何が起こっているのかわかりませんが、OEISページのMapleの公式に勝つのは難しいようです。これは、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)
ピーターテイラー


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

これは匿名関数です。私のPythonがOEISページのMapleの式に答えるのとほぼ同じですがモジュラスを実装しなかったため、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.