Số lượng tinh khiết


27

Hôm nay chúng ta sẽ xem xét một chuỗi a , liên quan đến chức năng Collatz f :

nhập mô tả hình ảnh ở đây

Chúng tôi gọi một chuỗi có dạng z, f (z), f (f (z)), một chuỗi Collatz .

Số đầu tiên trong chuỗi của chúng tôi , a (1) , là 0 . Theo ứng dụng lặp lại của f , nó rơi vào chu kỳ 0 → 0 →

Số nhỏ nhất chúng tôi chưa thấy là 1, tạo một (2) = 1 . Dưới ứng dụng lặp lại của f , nó rơi vào chu kỳ 1 → 4 → 2 → 1 → Cách

Bây giờ chúng ta đã thấy số 2 trong chu kỳ trên, vì vậy số nhỏ nhất tiếp theo là a (3) = 3 , rơi vào chu kỳ 3 → 10 → 5 → 16 → 8 → 4 → 2 → 1 → 4 → 2 → 1 →

Trong tất cả các chu kỳ trên, chúng ta đã thấy 45 rồi, nên số tiếp theo là a (4) = 6 .

Bây giờ bạn sẽ có được ý tưởng. a (n) là số nhỏ nhất không phải là một phần của bất kỳ chuỗi Collatz nào cho tất cả a (1), Vượt, a (n - 1) .

Viết chương trình hoặc hàm, cho số nguyên dương n , trả về a (n) . Mã ngắn nhất trong byte thắng.


Testcase:

1  -> 0
2  -> 1
3  -> 3
4  -> 6
5  -> 7
6  -> 9
7  -> 12
8  -> 15
9  -> 18
10 -> 19
50 -> 114

(Đây là trình tự OEIS A061641 .)



3
Đầu vào ncó thể dựa trên 0 không?
Luis Mendo

a(n+1) = a(n) odd: 3*a(n)+1, or a(n) even: a(n)/2
Karl Napf

@LuisMendo Xin lỗi, bằng cách nào đó tôi đã bỏ lỡ tin nhắn của bạn. Không, tái tạo chuỗi chính xác như trong thử thách.
orlp

Nếu akhông dựa trên 0, tôi không hiểu tại sao bạn dường như "nói 0 dựa trên" ở đây:a(n) is the smallest number that was not part of any Collatz sequences for all a(0), …, a(n − 1).
daniero

Câu trả lời:


5

Thạch , 20 19 byte

ḟ@JḢ×3‘$HḂ?ÐĿ;Ṛ
Ç¡Ṫ

Hãy thử trực tuyến! hoặc xác minh tất cả các trường hợp thử nghiệm .

Làm thế nào nó hoạt động

Ç¡Ṫ              Main link. No explicit arguments. Default argument: 0
 ¡               Read an integer n from STDIN and do the following n times.
Ç                  Call the helper link.
  Ṫ              Tail; extract the last element of the resulting array.


ḟ@JḢ×3‘$HḂ?ÐĿ;Ṛ  Helper link. Argument: A (array)

  J              Yield all 1-based indices of A, i.e., [1, ..., len(A)]. Since 0
                 belongs to A, there is at least one index that does belong to A.
ḟ@               Filter-false swapped; remove all indices that belong to A.
   Ḣ             Head; extract the first index (i) that hasn't been removed.
           ÐĿ    Call the quicklink to the left on i, then until the results are no
                 longer unique. Collect all unique results in an array.
         Ḃ?      If the last bit of the return value (r) is 1:
       $           Apply the monadic 3-link chain to the left to r.
    ×3‘              Yield 3r + 1.
        H        Else, halve r.
              Ṛ  Yield A, reversed.
             ;   Concatenate the results array with reversed A.

Sau n lần lặp, giá trị của a (n + 1) sẽ ở đầu mảng. Vì chúng ta ghép mảng mới với một bản sao đảo ngược của mảng cũ, điều này có nghĩa là một (n) sẽ ở cuối.


9

Haskell, 93 92 byte

c x|x<2=[[0,2]!!x]|odd x=x:c(3*x+1)|1<2=x:c(div x 2)
([y|y<-[-1..],all(/=y)$c=<<[0..y-1]]!!)

Ví dụ sử dụng: ([y|y<-[-1..],all(/=y)$c=<<[0..y-1]]!!) 10-> 19.

c xlà chu trình Collatz xvới một chút gian lận cho x == 1. Các chức năng chính vòng qua tất cả các số nguyên và giữ những người mà không phải là trong c xcho xtrong [0..y-1]. Khá nhiều thực hiện trực tiếp của định nghĩa. Vì toán tử chỉ mục Haskell !!dựa trên 0, tôi bắt đầu tại -1để thêm vào một số (nếu không vô dụng) để sửa chỉ mục.


4

MATL , 46 40 byte

Oiq:"tX>Q:yX-X<`t0)to?3*Q}2/]h5M1>]Pv]0)

Hãy thử trực tuyến!

Giải trình

Mã này có một forvòng lặp bên ngoài tạo ra ncác chuỗi Collatz, một chuỗi trong mỗi lần lặp. Mỗi chuỗi được tạo bởi một do...whilevòng lặp bên trong tính toán các giá trị mới và lưu trữ chúng trong một vectơ trình tự cho đến khi thu được một 1hoặc 0. Khi chúng ta thực hiện xong chuỗi, vectơ được đảo ngược và nối với một vectơ toàn cầu có chứa các giá trị từ tất cả các chuỗi trước đó. Vectơ này có thể chứa các giá trị lặp lại. Sự đảo ngược của vectơ chuỗi đảm bảo rằng ở cuối vòng ngoài, kết quả mong muốn (giá trị bắt đầu của chuỗi cuối cùng) sẽ ở cuối vectơ toàn cầu.

Mã giả :

1  Initiallization
2  Generate n sequences (for loop):
3    Compute initial value for the k-th sequence
4    Generate the k-th sequence (do...while loop)
5      Starting from latest value so far, apply the Collatz algorithm to get next value
6      Update sequence with new value 
7      Check if we are done. If so, exit loop. We have the k-th sequence
8    Update vector of seen values
9  We now have the n sequences. Get final result

Mã nhận xét :

O           % Push 0                                                          1
iq:         % Input n. Generate [1 2 ... n-1]                                 ·
"           % For loop: repeat n-1 times. Let k denote each iteration         2
  t         %   Duplicate vector of all seen values                           · 3
  X>Q       %   Take maximum, add 1                                           · ·
  :         %   Range from 1 to that: these are potential initial values      · ·
  y         %   Duplicate vector of all seen values                           · ·
  X-X<      %   Set difference, minimum: first value not seen                 · ·
  `         %   Do...while: this generates the k-th Collatz sequence          · 4
    t0)     %     Duplicate, push last value of the sequence so far           · · 5
    to      %     Duplicate, parity: 1 if odd, 0 if even                      · · ·
    ?       %     If odd                                                      · · ·
      3*Q   %       Times 3, plus 1                                           · · ·
    }       %     Else                                                        · · ·
      2/    %       Half                                                      · · ·
    ]       %     End if                                                      · · ·
    h       %     Concatenate new value of the sequence                       · · 6
    5M      %     Push the new value again                                    · · 7
    1>      %     Does it exceed 1? This is the loop condition                · · ·
  ]         %   End do...while. The loops ends when we have reached 0 or 1    · ·
  P         %   Reverse the k-th Collatz sequence                             · 8
  v         %   Concatenate with vector of previously seen values             · ·
]           % End for                                                         ·
0)          % Take last value. Implicitly display.                            9


3

Python 2, 97 96 byte

r,=s={-1}
exec'n=r=min({r+1,r+2,r+3}-s)\nwhile{n}-s:s|={n};n=(n/2,3*n+1)[n%2]\n'*input()
print r

Lợi dụng thực tế là tất cả bội số của 3 là thuần túy. Kiểm tra nó trên Ideone .

Làm thế nào nó hoạt động

Trên dòng đầu tiên, r,=s={-1}đặt s = {-1} (bộ) và r = -1 .

Tiếp theo chúng ta đọc một số nguyên từ STDIN, lặp lại một chuỗi nhất định nhiều lần, sau đó thực hiện nó. Điều này tương đương với mã Python sau đây.

for _ in range(input())
    n=r=min({r+1,r+2,r+3}-s)
    while{n}-s:
        s|={n}
        n=(n/2,3*n+1)[n%2]

Trong mỗi lần lặp, chúng tôi bắt đầu bằng cách tìm thành viên nhỏ nhất của {r + 1, r + 2, r + 3} không thuộc về s . Trong lần lặp đầu tiên, điều này khởi tạo r0 .

Trong tất cả các lần chạy tiếp theo, s có thể (và sẽ) chứa một số r + 1 , r + 2r + 3 , nhưng không bao giờ là tất cả chúng, vì tất cả các bội số của 3 là thuần túy. Để xác minh tuyên bố này, hãy lưu ý rằng không có nhiều m trong 3 có dạng 3k + 1 . Điều đó để lại 2m là hình ảnh trước duy nhất có thể, cũng là bội số của 3 . Do đó, m không thể xuất hiện trong chuỗi Collatz của bất kỳ số nào nhỏ hơn m và do đó là thuần túy.

Sau khi xác định r và khởi tạo n , chúng ta áp dụng hàm Collatz với n=(n/2,3*n+1)[n%2], thêm từng giá trị trung gian của n vào tập s với s|={n}. Khi chúng ta gặp một số n đã có trong s , {n}-ssẽ mang lại một tập hợp trống và việc lặp lại dừng lại.

Giá trị cuối cùng của r là phần tử mong muốn của chuỗi.


1
Để thêm vào điều này, một bằng chứng cho thấy tất cả bội số của 3 là thuần túy. Nhìn vào bất kỳ modulo trình tự Collatz 3. Sau bất kỳ ứng dụng nào của quy tắc 3x + 1, modulo là 1. Sau khi áp dụng quy tắc x / 2, mod 1 trở thành 2 và mod 2 trở thành 1. Cả hai quy tắc đều không thể tạo ra bội số bằng 3, trừ khi giá trị ban đầu đã là bội số lớn hơn của 3 đã giảm một nửa. Nhưng đó là những giá trị lớn hơn chưa được tạo, vì vậy n = 0 (mod 3) => n là thuần túy.
orlp


1

Java, 148 byte

int a(int n){if(n<2)return 0;int f=a(n-1),b,i,c;do{f++;for(b=1,i=1;i<n;i++)for(c=i==2?4:a(i);c>1;c=c%2>0?c*3+1:c/2)b=c==f?0:b;}while(b<1);return f;}

Nghĩa là nó! (Cảnh báo: độ phức tạp theo cấp số nhân do tối ưu hóa bằng không.)

Chuyển đổi nó từ một do...whilevòng lặp sang một forvòng lặp sẽ là golfer, nhưng tôi gặp khó khăn khi làm điều đó.

Tư vấn chơi golf được chào đón như bình thường.


Không nhiều, nhưng bạn có thể tắt 1 byte bằng cách đổi for(b=1,i=1;i<n;i++)thành for(b=1,i=0;++i<n;). Btw, tôi hiểu tại sao ideone của bạn thiếu trường hợp thử nghiệm cho 50, nhưng tại sao nó cũng bỏ lỡ 10? Nó có thể xử lý nó mà không có vấn đề.
Kevin Cruijssen

@KevinCruijssen Vì định dạng sẽ tệ.
Leaky Nun

Không phải là sự cải thiện tốt nhất nhưng tôi đã không mất quá nhiều thời gian ... (147 byte)int a(int n){if(n<2)return 0;int f=a(n-1),b=0,i,c;for(;b<1;){f++;for(b=1,i=1;i<n;i++)for(c=i==2?4:a(i);c>1;c=c%2>0?c*3+1:c/2)b=c==f?0:b;}return f;}
Chọc

1

Perl6, 96

my @s;my $a=0;map {while ($a=@s[$a]=$a%2??3*$a+1!!$a/2)>1 {};while @s[++$a] {}},2..slurp;$a.say;

Dựa trên câu trả lời Perl 5 . Lâu hơn một chút vì cú pháp Perl6 ít tha thứ hơn cú pháp Perl5, nhưng bây giờ tôi sẽ giải quyết vấn đề này.


0

PHP, 233 124 byte

<?$n=$argv[1];for($c=[];$n--;){for($v=0;in_array($v,$c);)$v++;for(;$n&&!in_array($v,$c);$v=$v&1?3*$v+1:$v/2)$c[]=$v;}echo$v;

+4 cho chức năng:

function a($n){for($c=[];$n--;){for($v=0;in_array($v,$c);)$v++;for(;$n&&!in_array($v,$c);$v=$v&1?3*$v+1:$v/2)$c[]=$v;}return$v;}

0

Perl 5 - 74 byte

map{0 while 1<($a=$c[$a]=$a%2?$a*3+1:$a/2);0 while$c[++$a]}2..<>;print$a+0

Đây là một giải pháp khá đơn giản. Nó liên tục áp dụng hàm Collatz cho biến $avà lưu trữ trong mảng @cmà giá trị đã được nhìn thấy, sau đó sau khi đạt 0 hoặc 1, nó tăng lên $acho đến khi nó là một số chưa được nhìn thấy. Điều này được lặp lại một số lần bằng với đầu vào trừ 2 và cuối cùng giá trị của $ađược xuất ra.


0

Toán học, 134 byte

f=If[EvenQ@#,#/2,3#+1]&;a@n_:=(b={i=c=0};While[i++<n-1,c=First[Range@Max[#+1]~Complement~#&@b];b=b~Union~NestWhileList[f,c,f@#>c&]];c)

Định dạng dễ đọc hơn:

f = If[EvenQ@#, #/2, 3#+1] &;                        Collatz function
a@n_ := (                                            defines a(n)
  b = {i = c = 0};                                   initializations
                                                       b is the growing sequence
                                                       of cycles already completed
  While[i++ < n - 1,                                 computes a(n) recursively
    c = First[Range@Max[# + 1]~Complement~# & @b];   smallest number not in b
    b = b~Union~NestWhileList[f, c, f@# > c &]       apply f to c repeatedly
                                                       until the answer is smaller
                                                       than c, then add this new
                                                       cycle to b
    ]
  ; c)                                                 output final value of c
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.