การทำซ้ำ Collatz


21

การคาดคะเน Collatzตั้งสมมติฐานว่าหากคุณใช้จำนวนเต็มบวกใด ๆ ให้ทำซ้ำอัลกอริทึมต่อไปนี้ในเวลาที่เพียงพอ:

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

คุณจะได้อันดับที่ 1 ในที่สุดดูเหมือนว่าจะใช้ได้เสมอ แต่ก็ไม่เคยได้รับการพิสูจน์ว่าใช้งานได้

คุณตีกอล์ฟแล้วคำนวณว่าต้องใช้เวลานานเท่าไหร่จึงจะถึง 1ดังนั้นฉันคิดว่าฉันจะสลับบางอย่างได้

เริ่มต้นด้วยจำนวนเต็มบวกที่กำหนดคำนวณระยะเวลาที่จะได้รับ 1 ("เวลาหยุด") แล้วพบว่าเวลาหยุดจำนวนของ

ทำซ้ำจนกว่าจะถึง 1 หรือจนกว่าคุณจะถึงขีด จำกัด โดยสิ้นเชิง 100 การทำซ้ำ ในกรณีก่อนหน้าให้พิมพ์จำนวนการวนซ้ำ ในกรณีหลังพิมพ์ "ล้มเหลว" หรือบางส่วนเอาท์พุทที่สอดคล้องอื่น ๆ 1≤n≤100ของทางเลือกของคุณตราบใดที่มันไม่ได้เป็นจำนวนเต็ม คุณไม่สามารถส่งออกสตริงว่างเปล่าสำหรับตัวเลือกนี้ อย่างไรก็ตามอนุญาตให้แสดงจำนวนเต็มนอกช่วง [1, 100]

ตัวอย่าง:

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

เมื่อฉันคำนวณ10^100และ12345678901234567890ใช้ภาษาที่รองรับเฉพาะขนาดจริงเท่านั้นหากภาษาของคุณมีความแม่นยำมากขึ้นคุณอาจได้รับผลลัพธ์ที่แตกต่างกัน

เกณฑ์การให้คะแนน

เช่นนี้คือคำตอบที่มีจำนวนไบต์สั้นที่สุดจะชนะ


ขอให้เรายังคงอภิปรายนี้ในการแชท
โคล

คำตอบ:




6

ทูต 40 ไบต์

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

ลองออนไลน์!

นี่เป็นภาษาใหม่ที่ฉันทำ ฉันอยากที่จะสร้างภาษาที่เหมาะสมและนี่คือผลลัพธ์: การเคาะทางคณิตศาสตร์ ไชโย?

คำอธิบาย

นี่คือองค์ประกอบของฟังก์ชั่นบางอย่าง ฟังก์ชั่นเหล่านี้คือ:

  • PeriodicSteps[CollatzSize@Max&1]ฟังก์ชันนี้ใช้ฟังก์ชันซึ่งใช้อาร์กิวเมนต์ของมันจนกว่าผลลัพธ์จะมีองค์ประกอบที่ซ้ำกัน ฟังก์ชันCollatzSize@Max&1นี้ใช้CollatzSizeกับอินพุตที่มากกว่าและ1เพื่อหลีกเลี่ยงอินพุตที่ไม่ถูกต้อง0กับ CollatSize
  • `#เป็นผู้ประกอบการที่ยกมา; เมื่อนำมาใช้แบบเดี่ยวในแง่นี้มันจะได้ขนาดของการโต้แย้ง
  • `-&3เป็นฟังก์ชันที่ถูกผูกมัดซึ่งเชื่อมโยงอาร์กิวเมนต์3กับฟังก์ชัน`-ซึ่งอ่านเป็น "ลบ 3" นี่เป็นเพราะแอปพลิเคชัน PeriodicSteps ให้ผลตอบแทน0s ซึ่งจำเป็นต้องพิจารณา (นอกจากนี้ยังจัดการกับหมายเลขที่ไม่อยู่ในขอบเขตอย่างที่ต้องการ5ซึ่งแมปไปยัง-1)

1
ใช้ภาษาของคุณเองได้ไหม คุณไม่เพียงแค่สร้าง langage สำหรับแต่ละ codegolf ด้วยการใช้เพียงบางไบต์?
Tweakimp

2
@Takakimp แน่นอนการสร้าง (และการใช้) ภาษาของคุณได้รับอนุญาต แต่การแก้ไขเพื่อให้งานเป็นคำสั่งเดียว (หลังจากการโพสต์ความท้าทาย) เป็นช่องโหว่มาตรฐาน
caird coinheringaahing

2
@Teakimp ถ้ามันทำให้คุณรู้สึกดีขึ้นฉันได้ออกแบบฟังก์ชั่นนี้ก่อนที่ฉันจะเห็นความท้าทายนี้ ฉันเป็นนักออกแบบภาษาดังนั้นฉันจึงทำเช่นนั้น
Conor O'Brien

มันเป็นคำถามทั่วไปมากกว่าที่จะอนุญาตให้ใช้ภาษาที่สร้างตัวเองได้ไม่ใช่ข้อความเชิงลบที่คุณใช้ของคุณเอง
Tweakimp

4

J , 49 45 ไบต์

-4 ไบต์ขอบคุณที่สั้นรหัส Collatz ลำดับที่นำมาจากความคิดเห็น @ randomra ของที่นี่

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

ผลลัพธ์101สำหรับผลลัพธ์ที่ไม่ถูกต้อง

ลองออนไลน์!

คำอธิบาย

คำอธิบายนี้ล้าสมัยไปแล้วอย่างแปลกใจ ฉันจะทิ้งไว้ในรูปแบบของคำตอบ 49 ไบต์เก่าที่ฉันมีซึ่งฉันรวมอยู่ด้านล่าง หากคุณต้องการอัปเดตเพียงแจ้งให้เราทราบ วิธีที่พบความยาวของลำดับการเรียกซ้ำยังคงเหมือนเดิมฉันเพิ่งใช้วิธี Collatz Sequence ที่สั้นกว่า

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

การค้นหาความยาวของลำดับ Collatz

รหัสในส่วนนี้มีดังต่อไปนี้

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

นี่คือคำอธิบาย:

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

น่าเสียดายที่กริยานำไปใช้ ( ^:) เมื่อได้รับคำสั่งให้เก็บผลลัพธ์จะเก็บค่าเริ่มต้นด้วยเช่นกันดังนั้นจึงหมายความว่าเราเป็นหนึ่งเดียว เหตุใดเราจึงลบ 1

การค้นหาความยาวของลำดับแบบเรียกซ้ำ

(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
ถ้าคุณไม่รังเกียจที่จะใช้หัวข้อหัวข้อนี่อาจจะแสดงคำตอบของคุณได้แม่นยำกว่าเดิม
Conor O'Brien

@ ConorO'Brien ฉันไม่ได้เลย - ฉันไม่รู้ว่าจะจัดรูปแบบอย่างไร (แต่ฉันจะขโมยของคุณต่อจากนี้) ขอบคุณ
โคลม

1
A N Y เสื้อ I m E!
Conor O'Brien

1
38 ไบต์ด้วย*i.~(<101)1&(#@}.a:2&(<*|{%~,*+1+])])]ควรเทียบเท่า
ไมล์


3

JavaScript (ES6), 57 ไบต์

ส่งคืนtrueเมื่อล้มเหลว ผลตอบแทนสำหรับ01

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

กรณีทดสอบ


ฉันสงสัยว่าโปรแกรมของคุณเกิดขึ้นในการคำนวณผลลัพธ์ที่ถูกต้องนอกเหนือจาก overflow / inaccuracy หรือถ้าค่อนข้าง OP ได้ผลลัพธ์ของพวกเขาโดยใช้ภาษาที่มีจำนวนที่คล้ายกัน (ฉันคิดว่าพวกเขาไม่ได้คำนวณกรณีทดสอบด้วยมือทั้งหมด)
Jonathan Frech

@ JonathanFrech แน่นอน ปรากฎว่าผลลัพธ์ทั้งคู่ไม่ถูกต้องเท่ากัน
Arnauld

3

APL (Dyalog Unicode) , 39 60 53 52 49 ไบต์

-3 ไบต์ขอบคุณ @ngn

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

ลองออนไลน์!

ใช้รหัส @ngn สำหรับ Collatz แต่ก่อนหน้านี้ใช้รหัสของ @ Uriel

นี่คือเวอร์ชั่นเก่าที่ไม่ตรงตามข้อกำหนด:

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

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


2

Husk , 21 ไบต์

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

ลองออนไลน์! ผลตอบแทน-1ในความล้มเหลวในการป้อนข้อมูล01

คำอธิบาย

←€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 ไบต์

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

ลองออนไลน์!

ส่งคืน101เมื่อจำนวนการวนซ้ำเกิน 100


1
ยินดีต้อนรับสู่ PPCG! คำตอบนี้ไม่ได้ค่อนข้างถูกต้องเพราะทุกฟังก์ชั่นการส่งจะต้องนำมาใช้ใหม่ ฉันคิดว่าคุณสามารถแก้ไขปัญหานี้ได้โดยการแทรกm=0ลงในf(อาจใช้ประโยชน์จากforIntiailiser ที่ว่างเปล่าในปัจจุบันเพื่อบันทึกหนึ่งก;)
Martin Ender

2

ทำความสะอาด , 146 ... 86 ไบต์

-11 ไบต์ขอบคุณØ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]

เป็นฟังก์ชั่นบางส่วนตามตัวอักษร

ลองออนไลน์!

ยกเลิกด้วยhd of []ถ้าจำนวนการวนซ้ำเกิน 100
ออกด้วยHeap Fullสำหรับอินพุตด้านบน ~ 2^23เว้นแต่คุณจะระบุขนาดฮีปที่ใหญ่กว่า


1
ฉันเริ่มที่จะเข้าใจไวยากรณ์สะอาดบางคน (ในขณะที่มันแตกต่างจาก Haskell) จากคำตอบของคุณ ... j f l n=hd[u\\1<-iterate f n&u<-l]คุณสามารถร่นที่มีฟังก์ชั่นผู้ช่วย
Ørjan Johansen

@ ØrjanJohansenขอบคุณ!
Janurous

คุณไม่ต้องการชิ้น\a=...aส่วนมันเป็นแกง (หรือกทพลด.)
Ørjan Johansen

@ ØrjanJohansenโอ้พลาดแล้วขอบคุณมาก!
Οurous

1

Python 2 , 99 98 97 ไบต์

  • ที่บันทึกไว้ไบต์โดยใช้แทนc and t or ft if c else f
  • บันทึกเป็นไบต์โดยเอาท์พุท-1แทนfหรือ'f'สำหรับอินพุตที่ไม่หยุด
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)")

ลองออนไลน์!


1

BiwaScheme , 151 ตัวอักษร

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

คุณสามารถทดลองใช้งานได้ที่นี่


1

R , 119 107 ไบต์

บางส่วนจะใช้รหัส Collatz Jarko Dubbeldam จากที่นี่ ส่งคืน0สำหรับ> 100 การวนซ้ำ (ความล้มเหลว)

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

ลองออนไลน์!


1

APL NARS 115 ไบต์ 63 ตัวอักษร

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

อาจใช้ลูปก็จะชัดเจนมากขึ้น ... มี 4 ฟังก์ชั่น, 2 ซ้อนและ ricorsive และเป็นครั้งแรกเท่านั้นสำหรับการกำหนดและเริ่มต้นถึง = 0 ตัวแปร d, เห็นได้จากฟังก์ชั่นที่ 2 เป็นตัวแปรเคาน์เตอร์ทั่วโลก

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

ฟังก์ชั่นที่ 3 นี้จะเป็นฟังก์ชั่นที่คืนค่าจำนวนการเรียกที่มีไว้สำหรับการแก้ไขการคาดคะเน Collatz สำหรับ arg

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

นี่คือฟังก์ชั่นที่ 2 หากมี arg = 1 ให้หยุดการเรียกซ้ำและส่งกลับจำนวนเวลาที่เรียกว่าตัวเอง -1 อื่นถ้าตัวเองถูกเรียกว่ามากกว่า 99 ครั้งหยุดการเรียกซ้ำและกลับ -1 (ล้มเหลว) อื่นคำนวณการคาดคะเน Collatz สำหรับหาเรื่องของมันและเรียกตัวเองสำหรับค่าความยาวตามลำดับ Collatz สำหรับฉันแม้ว่าทั้งหมดนี้ดูเหมือนว่าการทำงานอาจเป็นปัญหาใหญ่หากมีการกำหนดตัวแปรส่วนกลางและตัวแปรหนึ่งตัวในฟังก์ชั่นที่มีชื่อเดียวกันเมื่อโปรแกรมเมอร์เห็นว่ามันเป็นเพียงตัวแปรในตัวเครื่อง

  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, Common, ... ) Lisp, 105 ไบต์

ส่งคืน t สำหรับการวนซ้ำ> 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))))

ขยาย:

(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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.