Đường dẫn Collatz: Chuyển tiếp và lùi dọc theo phỏng đoán Collatz


8

Phỏng đoán Collatz là một phỏng đoán rất nổi tiếng. Lấy một số nguyên dương; nếu nó chẵn, chia cho 2, khác, nhân 3 và thêm 1. Lặp lại cho đến khi bạn đạt được 1hoặc một cái gì đó khác xảy ra. Phỏng đoán là quá trình này luôn đạt được 1.

Bạn cũng có thể đảo ngược quá trình. Bắt đầu tại 1, nhân với 2 và để phân nhánh thành các multiply by 3 and add 1số, khi bạn đạt đến một số chẵn 1 (mod 3), trừ đi 1 và chia cho 3.

Một đường dẫn Collatz kết hợp cả hai, cố gắng chuyển từ số này sang số khác với bốn thao tác đó.

Ví dụ: để nhận được 20từ 1:

1     *2
2     *2
4     *2
8     *2
16    *2
5     (-1)/3
10    *2
20    *2

Bạn cũng có thể nhận được 3từ 10bằng cách trừ 1 và chia cho 3.

Với các công cụ này, bạn có thể đi qua một đường dẫn Collatz từ số này sang số khác. Ví dụ: đường dẫn từ 20đến 3là (chia cho 2), (trừ 1, chia cho 3).

Nói tóm lại, các hoạt động có sẵn là:

n * 2       always
n // 2      if n % 2 == 0
n * 3 + 1   if n % 2 == 1
(n-1) // 3  if n % 6 == 4

Lưu ý: không phải tất cả các đường dẫn Collatz đều ngắn. a(7,3)có thể chạy

7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1, 2, 4, 8, 16, 5, 10, 3

nhưng một con đường ngắn hơn là

7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 3

Các thách thức

Tìm độ dài của đường Collatz ngắn nhất giữa hai số nguyên dương bất kỳ pq.

  • Đầu vào là bất kỳ hai số nguyên dương nào nhỏ hơn 2^20để tránh tràn số nguyên. Phương thức nhập liệu được để lại cho người chơi golf tùy ý. Các số nguyên có thể giống nhau, trong trường hợp đó, độ dài của đường dẫn Collatz là 0.
  • Đầu ra phải là một số nguyên, biểu thị độ dài của đường dẫn Collatz ngắn nhất giữa pq.

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

a(2,1)
1

a(4,1)
1         # 4 -> 1

a(3,1)
6         # 3 -> 10 -> 5 -> 16 -> 8 -> 4 -> 1

a(11,12)
11        # 11 -> 34 -> 17 -> 52 -> 26 -> 13
          # -> 40 -> 20 -> 10 -> 3 -> 6 -> 12

a(15,9)
20        # 46 -> 23 -> 70 -> 35 -> 106 -> 53 -> 160 -> 80 -> 40 -> 13
          # -> 26 -> 52 -> 17 -> 34 -> 11 -> 22 ->  7 -> 14 -> 28 -> 9

Rất cám ơn orlp đã giúp đỡ họ trong việc làm rõ thách thức này.

Như mọi khi, nếu vấn đề không rõ ràng, xin vui lòng cho tôi biết. Chúc may mắn và chơi golf tốt!


1
Máy tính của chúng tôi sẽ không chịu đựng được ít nhất 2 ^ 31 phần tử.

@MatthewRoh Thử thách đã được chỉnh sửa.
Sherlock9

Đây là khá nhiều thách thức tìm đường lý thuyết đồ thị . Và tôi khá chắc chắn rằng chúng tôi đã có một cái gần như giống hệt nhau trước đây.
flawr


2
@flawr Tôi không đồng ý với bản sao. Đúng, cả hai thách thức đều muốn tìm một đường dẫn trong biểu đồ, nhưng các biểu đồ là khác nhau và mã hóa cấu trúc biểu đồ trong câu trả lời của bạn là phần duy nhất, IMO. Xem ví dụ câu trả lời của tôi và so sánh nó với câu trả lời trong câu hỏi 'trùng lặp' của bạn.
orlp

Câu trả lời:


3

Haskell, 170 158 157 146 143 137 135 112 109 108 106 100 99 byte

a!b=length$fst$break(elem b)$iterate(>>= \n->2*n:cycle[div n 2,n*3+1]!!n:[div(n-1)3|mod n 6==4])[a]

Tôi không ngờ rằng phiên bản gốc của tôi lại dễ chơi hơn nhiều, đây cũng là tác phẩm của @nimi @Lynn và @Laikoni!

Cảm ơn @Laikoni cho một byte, @Lynn cho 11 14 20 21 byte, @nimi cho 8 byte!

Điều này mở rộng cây số lượng truy cập (bắt đầu bằng a) từng bước và kiểm tra từng bước xem chúng ta có đến số đã cho hay không b.


Bạn đã bỏ lỡ một khoảng trống:iterate s [a] -> iterate s[a]
Laikoni

Sweet ~ Inlining stiết kiệm thêm ba byte! iterate(nub.concat.map f)[a]Ngoài ra, bạn có thực sự cần nub?
Lynn

Nói cho tôi khi bạn chơi golf xong: D Cảm ơn bạn rất nhiều. Thật không may, tôi vẫn gặp khó khăn trong việc hiểu các đơn nguyên.
flawr

@nimi Một lần nữa, cảm ơn bạn rất nhiều, tôi không bao giờ ngờ rằng nó lại dễ chơi hơn thế! Tôi không biết về breakspan, thực sự hữu ích!
flawr

1
Thay thế [div n 2,n*3+1]!!mod n 2bằng cycle[div n 2,n*3+1]!!ntiết kiệm thêm một byte :)
Lynn

2

Python 2, 110 byte

a=lambda p,q,s={0}:1+a(p,q,s.union(*({p,n*2,[n/2,n*3+1][n%2]}|set([~-n/3]*(n%6==4))for n in s)))if{q}-s else-1

1

Bình thường, 30 byte

|q*FQ2ls-M.pm.u&n2N?%N2h*3N/N2

Dùng thử trực tuyến

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

Lấy độ dài của sự khác biệt đối xứng của hai chuỗi Collatz chuyển tiếp bắt đầu từ hai số đầu vào và kết thúc ở mức 2. Ngoại lệ duy nhất là nếu đầu vào là [1, 2]hoặc [2, 1], trong trường hợp đặc biệt.

  *FQ                        product of the input
|q   2                       if that equals 2, return 1 (True), else:
            m                  map for d in input:
             .u                  cumulative fixed-point: starting at N=d, iterate N ↦
               &n2N?%N2h*3N/N2     N != 2 and (N*3 + 1 if N % 2 else N/2)
                                 until a duplicate is found, and return the sequence
          .p                   permutations
        -M                     map difference
       s                       concatenate
      l                        length

1

Python 2, 156 179 191 209 181 172 177 171 byte

Từ một con đường Collatz có thể được hình dung như a(1,p)a(1,q)dính liền ở số điện thoại đầu tiên mà là chung cho cả chuỗi và a(1,n)là Collatz phỏng đoán ban đầu, chức năng này sẽ tính toán chuỗi Collatz của pq, và tính toán chiều dài từ đó. Đây không phải là một sân golf đẹp, vì vậy đề xuất chơi golf rất được hoan nghênh. Ngoại lệ duy nhất là khi p or q == 1. Sau đó, vì chúng ta có thể bỏ qua trực tiếp từ 4đến 1như trái ngược với một chuỗi Collatz thường xuyên, chúng ta cần phải trừ đi một bước từ kết quả.

Chỉnh sửa: Rất nhiều sửa lỗi.

Chỉnh sửa: Rất nhiều và rất nhiều sửa lỗi

f=lambda p:[p]if p<3else f([p//2,p*3+1][p%2])+[p]
def a(p,q):
 i=1;c=f(p);d=f(q)
 if sorted((p,q))==(1,2):return 1
 while c[:i]==d[:i]!=d[:i-1]:i+=1
 return len(c+d)-2*i+2

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


Cách tiếp cận của bạn không hoạt động, ví dụ a(3,1)trả về 7 trong khi nó sẽ trả về 6, vì đường dẫn ngắn nhất là3 -> 10 -> 5 -> 16 -> 8 -> 4 -> 1
flawr

@flawr Đã chỉnh sửa. Hy vọng nó hoạt động ngay bây giờ
Sherlock9

Tại sao bạn cho rằng thuật toán bạn mô tả hoạt động? Không thể một con đường ngắn nhất bao gồm nhiều lần đi "qua lại"?
flawr

2
Hãy fbiểu thị một bước tiến, bmột bước lùi trong chuỗi collatz. Các mô hình b->fkhông thể ở trong một con đường ngắn nhất, vì nó là bản sắc ( fđược hoàn tác btrong mọi trường hợp.) Vì vậy, con đường ngắn nhất chỉ có thể bao gồm các mẫu f->f, f->bb->b. Điều đó có nghĩa một lần nữa rằng con đường ngắn nhất luôn có dạng f->f->...->fhoặc b->b->...->bhoặcf->...->f->b->...->b
flawr

3
PS: Tôi có ấn tượng rằng số byte của bạn đang đi sai hướng. : D
flawr

0

JavaScript (ES6), 135 byte

f=(x,y,a=[(s=[],s[0]=s[x]=1,x)],z=a.shift())=>z-y?[z*2,z/2,z%2?z*3+1:~-z/3].map(e=>e%1||s[e]?0:s[a.push(e),e]=-~s[z])&&f(x,y,a):~-s[y]

Thực hiện tìm kiếm đầu tiên. xlà số bắt đầu, yđích đến, amột mảng các giá trị dùng thử, smột mảng gồm số bước bao gồm trên chuỗi từ x, zgiá trị hiện tại. Nếu zykhông bằng nhau, tính toán z*2, z/2và một trong hai z*3+1hoặc (z-1)/3, tùy thuộc vào việc zlà số lẻ hoặc thậm chí, sau đó lọc ra các phần phân đoạn và các giá trị nhìn thấy trước đây và thêm chúng vào danh sách tìm kiếm.


0

Python 2, 80 byte

p=lambda n:n-2and{n}|p([n/2,n*3+1][n%2])or{n}
lambda m,n:m*n==2or len(p(m)^p(n))

Lấy độ dài chênh lệch đối xứng của hai chuỗi Collatz chuyển tiếp bắt đầu từ hai số đầu vào và kết thúc ở mức 2. Ngoại lệ duy nhất là nếu đầu vào là 1, 2 hoặc 2, 1, trong trường hợp đặc biệt.

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.