Phỏng đoán Collatz đệ quy


21

Các Collatz phỏng đoán định đề rằng nếu bạn có bất kỳ số nguyên dương, sau đó lặp lại các thuật toán sau đây đủ thời gian:

if number is odd, then multiply by three and add one
if number is even, then divide by two

cuối cùng bạn sẽ kết thúc ở mức 1. Nó dường như luôn hoạt động, nhưng nó chưa bao giờ được chứng minh rằng nó luôn luôn như vậy.

Bạn đã chơi golf tính toán mất bao lâu để lên 1 , vì vậy tôi nghĩ tôi sẽ thay đổi mọi thứ một chút.

Bắt đầu với một số nguyên dương nhất định, tính toán mất bao lâu để đến 1 ("thời gian dừng" của nó). Sau đó tìm thời gian dừng của số.

Lặp lại cho đến khi bạn đạt được 1 hoặc cho đến khi bạn đạt đến giới hạn hoàn toàn tùy ý là 100 lần lặp. Trong trường hợp trước, in bao nhiêu lần lặp. Trong trường hợp sau, in "Fail" hoặc một số đầu ra nhất quán khác mà bạn chọn, miễn là nó không phải là số nguyên 1≤n≤100. Bạn không thể xuất một chuỗi trống cho tùy chọn này. Tuy nhiên, việc xuất ra một số nguyên nằm ngoài phạm vi [1, 100].

Ví dụ:

Input: 2
2->1
Output: 1

Input: 5
5->5->5->5->5->...
Output: Fail

Input: 10
10->6->8->3->7->16->4->2->1
Output: 8

Input: 100
100->25->23->15->17->12->9->19->20->7->16->4->2->1
Output: 13

Input: 10^100
10^100->684->126->108->113->12->9->19->20->7->16->4->2->1
Output: 13

Input: 12345678901234567890
12345678901234567890->286->104->12->9->19->20->7->16->4->2->1
Output: 11

Input: 1
--Depending on your code, one of two things may happen. Both are valid for the purposes of this question.
1
Output: 0
--Or:
1->3->7->16->4->2->1
Output: 6

Như tôi đã tính toán 10^10012345678901234567890sử dụng một ngôn ngữ chỉ hỗ trợ thực tế cho kích thước đó, nếu ngôn ngữ của bạn chính xác hơn, bạn có thể nhận được kết quả khác nhau cho những ngôn ngữ đó.

Chấm điểm

Vì đây là , câu trả lời có số byte ngắn nhất sẽ thắng.


Câu trả lời:




6

Tùy viên , 40 byte

`-&3@`#@PeriodicSteps[CollatzSize@Max&1]

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

Đây là một ngôn ngữ mới mà tôi đã thực hiện. Tôi muốn đi xung quanh để tạo ra một ngôn ngữ infix thích hợp, và đây là kết quả: một môn toán học bị loại. Hoan hô?

Giải trình

Đây là một thành phần của một vài chức năng. Các chức năng này là:

  • PeriodicSteps[CollatzSize@Max&1]Điều này mang lại một hàm áp dụng đối số của nó cho đến khi kết quả chứa phần tử trùng lặp. Hàm này CollatzSize@Max&1, đang áp dụng CollatzSizecho đầu vào lớn hơn và 1, để tránh đầu vào không hợp lệ 0cho CollatSize.
  • `#là một toán tử trích dẫn; khi được áp dụng một cách đơn điệu theo nghĩa này, nó có được kích thước của đối số của nó
  • `-&3là một hàm ngoại quan, liên kết đối số 3với hàm `-, nó đọc là "trừ 3". Điều này là do ứng dụng periodicSteps mang lại 0s, cần phải được tính toán. (Nó cũng xử lý gọn gàng các số ngoài giới hạn như 5, ánh xạ tới -1.)

1
Là sử dụng ngôn ngữ của riêng bạn thực sự được phép? Bạn có thể tạo một langage cho mỗi codegolf chỉ với một số byte không?
Tweakimp

2
@Tweakimp Tất nhiên việc tạo (và sử dụng) ngôn ngữ của bạn được cho phép. Nhưng sửa đổi nó để một nhiệm vụ là một lệnh duy nhất (sau khi thử thách được đăng) là một lỗ hổng tiêu chuẩn.
caird coinheringaahing

2
@Tweakimp nếu nó làm bạn cảm thấy tốt hơn, tôi đã thiết kế chức năng này trước khi tôi thấy thử thách này. Tôi là một nhà thiết kế ngôn ngữ, vì vậy đó là những gì tôi làm.
Conor O'Brien

Đó là nhiều hơn một câu hỏi chung mà ngôn ngữ tự tạo được cho phép, không phải là một tuyên bố tiêu cực mà bạn sử dụng của riêng bạn.
Tweakimp

4

J , 49 45 byte

-4 byte nhờ mã Collatz Sequence ngắn hơn được lấy từ nhận xét của @ Randomra tại đây .

(2-~[:#(>&1*-:+2&|*+:+>:@-:)^:a:)^:(<101)i.1:

Đầu ra 101cho kết quả không hợp lệ.

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

Giải trình

Không có gì đáng ngạc nhiên, lời giải thích này đã nhanh chóng trở nên lỗi thời. Tôi sẽ để lại nó theo câu trả lời 49 byte cũ mà tôi có, mà tôi bao gồm bên dưới. Nếu bạn muốn cập nhật, chỉ cần cho tôi biết. Cách nó tìm thấy độ dài của chuỗi đệ quy vẫn giữ nguyên, tôi vừa sử dụng một phương pháp Collatz Sequence ngắn hơn.

(1-~[:#%&2`(1+3&*)@.(2&|)^:(1&<)^:a:)^:(<101)i.1:

Tìm độ dài của Chuỗi Collatz

Phần này của đoạn mã như sau

(1-~[:#%&2`(1+3&*)@.(2&|)^:(1&<)^:a:)

Đây là lời giải thích:

(1 -~ [: # %&2`(1+3&*)@.(2&|) ^: (1&<) ^: a:)  Given an input n
                                       ^: a:   Apply until convergence, collecting
                                                each result in an array.
                              ^: (1&<)         If n > 1 do the following, else
                                                return n.
                        (2&|)                  Take n mod 2.
           %&2                                 If n mod 2 == 0, divide by 2.
               (1+3&*)                         If n mod 2 == 1, multiply by 3 
                                                and add 1.
         #                                     Get the length of the resulting
                                                array.
 1 -~                                          Subtract 1.

Thật không may, động từ áp dụng ( ^:) khi được yêu cầu lưu trữ kết quả cũng lưu trữ giá trị ban đầu, vì vậy nó có nghĩa là chúng ta (giống như luôn luôn) bị tắt bởi một. Do đó, tại sao chúng tôi trừ 1.

Tìm độ dài của chuỗi đệ quy

(1-~[:#%&2`(1+3&*)@.(2&|)^:(1&<)^:a:) ^: (< 101) i. 1:  Given an input n.
                                      ^: (< 101)        Apply 100 times,
                                                         collecting results
                                                         in an array.
(1-~[:#%&2`(1+3&*)@.(2&|)^:(1&<)^:a:)                   Collatz sequence length.
                                                 i. 1:  Index of first 1 (returns
                                                         101, the length of the
                                                         array if 1 not found).

1
Nếu bạn không phiền khi sử dụng phần tiêu đề, điều này có lẽ sẽ thể hiện chính xác hơn câu trả lời của bạn
Conor O'Brien

@ ConorO'Brien Tôi hoàn toàn không biết - Tôi thực sự không biết làm thế nào để nó được định dạng như vậy (nhưng tôi sẽ ăn cắp của bạn từ bây giờ). Cảm ơn
cole

1
A n y t i m e!
Conor O'Brien

1
38 byte với *i.~(<101)1&(#@}.a:2&(<*|{%~,*+1+])])]nên tương đương
dặm


3

JavaScript (ES6), 57 byte

Trả về truekhi thất bại. Trả lại 0cho 1.

f=(n,k=i=0)=>n>1?f(n&1?n*3+1:n/2,k+1):k?i>99||f(k,!++i):i

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


Tôi nghi ngờ nếu chương trình của bạn xảy ra để tính toán kết quả chính xác ngoài tràn / không chính xác hoặc nếu OP lấy kết quả của họ bằng cách sử dụng ngôn ngữ có triển khai số tương tự (tôi cho rằng họ không tính toán tất cả các trường hợp kiểm tra bằng tay).
Jonathan Frech

@JonathanFrech Thật vậy. Hóa ra cả hai kết quả đều không hợp lệ.
Arnauld

3

APL (Dyalog Unicode) , 39 60 53 52 49 byte

-3 byte nhờ @ngn

0∘{99<⍺:⋄1=⍵:01+(⍺+1)∇{1=⍵:01+∇⊃⍵⌽0 1+.5 3×⍵}⍵}

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

Sử dụng mã @ngn cho Collatz, nhưng trước đây đã sử dụng mã của @ Uriel.

Đây là phiên bản cũ không đáp ứng các đặc điểm kỹ thuật:

{1=⍵:01+∇{1=⍵:02|⍵:1+∇1+3×⍵⋄1+∇⍵÷2}⍵}

2|⍵:1+∇1+3×⍵⋄1+∇⍵÷2->1+∇⊃⍵⌽0 1+.5 3×⍵
ngn


2

Husk , 21 byte

←€1↑101¡ȯ←€1¡?½o→*3¦2

Hãy thử trực tuyến! Trả -1về thất bại, 0về đầu vào 1.

Giải trình

←€1↑101¡ȯ←€1¡?½o→*3¦2  Implicit input (a number).
             ?½o→*3¦2  Collatz function:
             ?     ¦2   if divisible by 2,
              ½         then halve,
               o→*3     else multiply by 3 and increment.
        ȯ←€1¡?½o→*3¦2  Count Collatz steps:
            ¡           iterate Collatz function and collect results in infinite list,
          €1            get 1-based index of 1,
        ȯ←              decrement.
       ¡               Iterate this function on input,
   ↑101                take first 101 values (initial value and 100 iterations),
←€1                    get index of 1 and decrement.

2

C (gcc) , 70 73 byte

g(x){x=x-1?g(x%2?3*x+1:x/2)+1:0;}f(x,m){for(m=0;(x=g(x))&&100>m++;);x=m;}

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

Trả về 101khi số lần lặp vượt quá 100.


1
Chào mừng đến với PPCG! Câu trả lời này không hoàn toàn hợp lệ, bởi vì tất cả các đệ trình chức năng cần phải được sử dụng lại . Tôi nghĩ rằng bạn có thể khắc phục điều này bằng cách chèn m=0vào f(thậm chí có thể sử dụng bộ forlọc thông gió hiện đang trống để lưu một cái ;).
Martin Ender

2

Sạch , 146 ... 86 byte

-11 byte nhờ rjan Johansen

import StdEnv
?f l n=hd[u\\1<-iterate f n&u<-l]

?(?(\b|isOdd b=3*b+1=b/2)[0..])[0..99]

Là một phần chức năng theo nghĩa đen.

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

Hủy bỏ hd of []nếu số lần lặp vượt quá 100.
Thoát với Heap Fullcác đầu vào ở trên ~ 2^23trừ khi bạn chỉ định kích thước heap lớn hơn.


1
Tôi bắt đầu hiểu một số cú pháp Clean (vì nó khác với Haskell) từ các câu trả lời của bạn ... bạn có thể rút ngắn câu đó bằng hàm trợ giúp j f l n=hd[u\\1<-iterate f n&u<-l].
Ørjan Johansen

@ RjanJohansen Cảm ơn!
Οurous

Bạn không cần \a=...amột phần, nó cà ri. (Hoặc eta giảm.)
rjan Johansen

@ RjanJohansen oh, bỏ lỡ điều đó, cảm ơn!
Οurous

1

Python 2 , 99 98 97 byte

  • Đã lưu một byte bằng cách sử dụng c and t or fthay vì t if c else f.
  • Đã lưu một byte bằng cách xuất ra -1thay vì fhoặc 'f'cho các đầu vào không tạm dừng.
exec"f,F="+"lambda n,i=0:n<2and i or %s"*2%("f([n/2,3*n+1][n%2],-~i),","i>99and-1or F(f(n),-~i)")

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


1

BiwaScheme , 151 ký tự

(define(f n i s)(if(= s 0) 'F(if(= n 0)i(f(letrec((c(lambda(m k)(if(= m 1)k(c(if(=(mod m 2)0)(/ m 2)(+(* m 3)1))(+ k 1))))))(c n 0))(+ i 1)(- s 1)))))

Bạn có thể thử nó ở đây .


1

R , 119 107 byte

Một phần sử dụng mã collatz của Jarko Dubbeldam từ đây . Trả về 0> 100 lần lặp (thất bại).

pryr::f(x,{N=n=0
while(x-1){while(x-1){x=`if`(x%%2,3*x+1,x/2);n=n+1}
x=n
n=0
N=N+1
if(N==100)return(0)}
N})

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


1

APL NARS, 115 byte, 63 ký tự

{d←0⋄{⍵=1:d⋄99<d+←1:¯1⋄∇{c←0⋄{1=⍵:c⋄c+←1⋄2∣⍵:∇1+3×⍵⋄∇⍵÷2}⍵}⍵}⍵}

Có lẽ sử dụng các vòng lặp sẽ rõ ràng hơn ... Có 4 hàm, 2 hàm lồng nhau và ricorsive, và hàm đầu tiên chỉ định nghĩa và khởi tạo thành = 0, biến d, được xem từ hàm thứ 2 là bộ đếm biến toàn cục.

q←{c←0⋄{1=⍵:c⋄c+←1⋄2∣⍵:∇1+3×⍵⋄∇⍵÷2}⍵}

Hàm thứ 3 này, sẽ là hàm trả về số lượng cuộc gọi để giải quyết phỏng đoán Collatz cho đối số của nó

{⍵=1:d⋄99<d+←1:¯1⋄∇q⍵}

Đây là hàm thứ 2, nếu có arg = 1, dừng đệ quy của nó và trả về d số thời gian nó được gọi là chính nó-1; khác nếu bản thân nó được gọi nhiều hơn 99 lần dừng đệ quy và trả về -1 (không thành công), hãy tính toán phỏng đoán Collatz cho đối số của nó và gọi chính nó cho giá trị độ dài chuỗi Collatz. Đối với tôi ngay cả khi tất cả điều này dường như chạy có thể là một vấn đề lớn nếu được định nghĩa một biến toàn cục và một biến trong một hàm cùng tên, khi lập trình viên xem nó chỉ là một biến cục bộ.

  f←{d←0⋄{⍵=1:d⋄99<d+←1:¯1⋄∇{c←0⋄{1=⍵:c⋄c+←1⋄2∣⍵:∇1+3×⍵⋄∇⍵÷2}⍵}⍵}⍵}     
  f 2
1
  f 3
5
  f 5
¯1
  f 10
8
  f 100
13
  f 12313
7
  f 1
0

1

(Emacs, Chung, ...) Lisp, 105 byte

Trả về t cho số lần lặp> 100

(defun f(n k c)(or(> c 100)(if(= n 1)(if(= k 0)c(f k 0(1+ c)))(f(if(oddp
n)(+ n n n 1)(/ n 2))(1+ k)c))))

Mở rộng:

(defun f (n k c)
  (or (> c 100)
      (if (= n 1)
          (if (= k 0) c
            (f k 0 (1+ c)))
        (f (if (oddp n) (+ n n n 1) (/ n 2))
           (1+ k) c))))
(f (read) 0 0)
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.