Tổng hợp các chuỗi Fractal


16

Lý lịch

Một chuỗi fractal là một chuỗi số nguyên, nơi bạn có thể loại bỏ sự xuất hiện đầu tiên của mỗi số nguyên và kết thúc với cùng một chuỗi như trước đây.

Một chuỗi rất đơn giản như vậy được gọi là paraph cụm của Kimberling . Bạn bắt đầu với các số tự nhiên tích cực:

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

Sau đó, bạn riffle trong một số khoảng trống:

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

Và sau đó bạn liên tục điền vào chỗ trống bằng chính chuỗi đó (bao gồm cả khoảng trống):

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

Đó là chuỗi fractal của chúng tôi! Bây giờ hãy lấy một phần tiền:

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

Nhưng nếu chúng ta lặp lại quá trình này thì sao? "Fractalise" chuỗi mới (nghĩa là tổng một phần thu được từ các bước trên):

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

Và lấy một phần tiền một lần nữa:

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

Rửa sạch, lặp lại. Nó chỉ ra rằng quá trình này hội tụ. Mỗi khi bạn lặp lại quá trình này, một tiền tố lớn hơn của chuỗi sẽ được cố định. Sau một số lần lặp vô hạn, bạn sẽ kết thúc với OEIS A085765 .

Sự thật thú vị: Quá trình này sẽ hội tụ vào cùng một chuỗi ngay cả khi chúng ta không bắt đầu từ các số tự nhiên miễn là chuỗi ban đầu bắt đầu 1. Nếu chuỗi ban đầu bắt đầu với bất kỳ thứ gì khác x, chúng tôi sẽ có được x*A085765thay vào đó.

Các thách thức

Cho một số nguyên dương N, xuất Nphần tử thứ của chuỗi hội tụ.

Bạn có thể viết chương trình hoặc hàm, lấy đầu vào qua STDIN (hoặc thay thế gần nhất), đối số dòng lệnh hoặc đối số hàm và xuất kết quả qua tham số STDOUT (hoặc thay thế gần nhất), tham số trả về hàm hoặc tham số hàm (out).

Bạn có thể chọn chỉ mục Nlà 0 hoặc 1 dựa trên.

Các trường hợp thử nghiệm

Trình tự bắt đầu bằng:

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

Vì vậy, đầu vào 5nên dẫn đến đầu ra 9.

Dưới đây là một triển khai tham chiếu CJam ngây thơ tạo ra các Nsố đầu tiên (được đưa ra Ntrên STDIN). Lưu ý rằng mã của bạn chỉ nên trả về Nphần tử thứ, không phải toàn bộ tiền tố.


Vì vậy, chỉ cần kiểm tra: chúng tôi đang xuất ra Nthuật ngữ thứ A085765 , đúng không?
GamrCorps 8/12/2015

@GamrCorps Có.
Martin Ender

Câu trả lời:


7

CJam ( 23 22 byte)

Các khoản tiền một phần được đưa ra tại các chỉ số chẵn của chuỗi fractal, đó là A086450 . Sự tái diễn được đưa ra theo định nghĩa của A086450 là cơ sở cho những triển khai này.

Sử dụng một "ngăn xếp" rõ ràng (trong trích dẫn sợ hãi vì đó không phải là LIFO):

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

Bản demo trực tuyến

Mổ xẻ

{         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)
}

Với 23 byte có một cách tiếp cận hiệu quả hơn nhiều, với sự phân biệt:

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

Bản demo trực tuyến


1
Tôi chắc chắn có một số ngôn ngữ trong đó sẽ ngắn hơn để thực hiện f(0) = 1; f(n) = f(n/2) + (n % 2 ? 0 : f(n-2)); return f(2*x), nhưng tôi không thể tìm ra cách tiết kiệm với cách tiếp cận đó trong CJam.
Peter Taylor

9

Con trăn 2, 55 49 42

Tôi không biết chuyện gì đang xảy ra, nhưng có vẻ khó đánh bại công thức Maple từ trang OEIS. Điều này sử dụng lập chỉ mục dựa trên 0.

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

Cảm ơn @PeterTaylor cho -6 byte.


Thật dễ dàng để tối ưu hóa bằng 6 ký tự nếu bạn không quan tâm đến hiệu suất. Các phần sau đầu tiên orcó hiệu quả g(n,1) = f(n/2,n%2); g(n,0) = f(n-1) + g(n,1); để bạn có thể rút ra cái chung g(n,1)để có đượcf=lambda n,t=0:n<1or f(n/2,n%2)+0**t*f(n-1)
Peter Taylor

3

Haskell, 65

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

2

Mẫu được coi là có hại , 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>>

Đây là một chức năng ẩn danh. Nó ít nhiều giống như Python của tôi trả lời công thức Maple trên trang OEIS, ngoại trừ việc tôi không thực hiện mô đun, vì vậy tôi phải sử dụng nn / 2 * 2 thay vì n% 2.

Mở rộng:

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

2

Toán học, 47 44 byte

If[#<1,1,#0[Floor@#/2]+(1-2#~Mod~1)#0[#-1]]&

0

Matlab 108 103

Tôi đang sử dụng thực tế là chuỗi mong muốn là tổng một phần của https://oeis.org/A086450

Nhưng sự phức tạp tính toán của việc thực hiện của tôi là không tối ưu, ngay cả đối với sự tái phát đơn giản này.

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)))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.