ตัวเลขของความบริสุทธิ์


27

วันนี้เราจะดูลำดับaที่เกี่ยวข้องกับฟังก์ชัน Collatz f :

ป้อนคำอธิบายรูปภาพที่นี่

เราเรียกลำดับของรูปแบบZ, f (z), f (f (z)) ...ลำดับ Collatz

จำนวนครั้งแรกในของเราลำดับ(ที่ 1)เป็น0 ภายใต้การใช้fซ้ำ ๆมันจะตกอยู่ในวัฏจักร0 → 0 → ...

จำนวนที่น้อยที่สุดที่เรายังไม่ได้เห็นคือ 1, การทำ(ที่ 2) = 1 ภายใต้การใช้fซ้ำ ๆมันจะตกอยู่ในวัฏจักร1 → 4 → 2 → 1 →…

ตอนนี้เราได้เห็นหมายเลข2ในวัฏจักรข้างต้นแล้วดังนั้นจำนวนที่น้อยที่สุดถัดไปคือ(3) = 3 , ตกลงไปในรอบ3 → 10 → 5 → 16 → 8 → 4 → 2 → 1 → 4 → 2 → 1 →…

ในรอบดังกล่าวข้างต้นทั้งหมดที่เราเคยเห็น4และ5แล้วดังนั้นจำนวนต่อไปคือA (4) = 6

โดยตอนนี้คุณควรจะได้รับความคิด A (n)เป็นจำนวนที่น้อยที่สุดที่ไม่ได้เป็นส่วนหนึ่งของลำดับ Collatz ใด ๆ สำหรับทุกA (1), ... , A (n - 1)

เขียนโปรแกรมหรือฟังก์ชั่นที่ได้รับการจำนวนเต็มบวกnกลับA (n) รหัสที่สั้นที่สุดในหน่วยไบต์ชนะ


Testcases:

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

(นี่คือลำดับ OEIS A061641 )


1
บังคับOEIS
FryAmTheEggman

3
อินพุตสามารถnเป็นแบบ 0 หรือไม่?
Luis Mendo

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

@LuisMendo ขออภัยฉันพลาดข้อความของคุณ ไม่สร้างลำดับที่แน่นอนเหมือนในสิ่งที่ท้าทาย
orlp

ถ้าaไม่ใช่พื้นฐาน 0 ฉันไม่เข้าใจว่าทำไมคุณดูเหมือนจะ "พูด 0 ตาม" ที่นี่:a(n) is the smallest number that was not part of any Collatz sequences for all a(0), …, a(n − 1).
daniero

คำตอบ:


5

เยลลี่ , 20 19 ไบต์

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

ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทุก

มันทำงานอย่างไร

Ç¡Ṫ              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.

หลังจากการวนซ้ำnค่าของ(n + 1)จะอยู่ที่จุดเริ่มต้นของอาร์เรย์ เนื่องจากเราต่ออาร์เรย์ใหม่เข้ากับสำเนาเก่าที่กลับรายการซึ่งหมายความว่า(n)จะสิ้นสุดแล้ว


9

Haskell, 93 92 ไบต์

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]]!!)

ตัวอย่างการใช้งาน: ->([y|y<-[-1..],all(/=y)$c=<<[0..y-1]]!!) 1019

c xเป็นวัฏจักรของโคลลาตซ์สำหรับxการโกงx == 1เล็กน้อย หน้าที่หลัก loops ผ่านจำนวนเต็มทั้งหมดและช่วยให้ผู้ที่ไม่ได้อยู่ในc xสำหรับในx [0..y-1]ค่อนข้างจะเป็นการกำหนดคำนิยามโดยตรง เนื่องจากโอเปอเรเตอร์ดัชนี Haskell !!เป็นแบบ 0 ฉันเริ่มต้นที่-1จะเติมตัวเลข (มิฉะนั้นไร้ประโยชน์) เพื่อให้ดัชนีคงที่


4

MATL , 46 40 ไบต์

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

ลองออนไลน์!

คำอธิบาย

รหัสมีการforวนรอบด้านนอกที่สร้างnลำดับ Collatz หนึ่งในแต่ละรอบซ้ำ ลำดับแต่ละครั้งจะถูกสร้างขึ้นโดยภายในdo...whileวงที่คำนวณค่าใหม่และเก็บไว้ในเวกเตอร์ลำดับจนกว่าจะมี1หรือ0จะได้รับ เมื่อเราดำเนินการตามลำดับเวกเตอร์จะถูกย้อนกลับและต่อกับเวกเตอร์ส่วนกลางที่มีค่าจากลำดับก่อนหน้าทั้งหมด เวกเตอร์นี้อาจมีค่าซ้ำ การย้อนกลับของเวกเตอร์ลำดับนั้นทำให้แน่ใจว่าในตอนท้ายของลูปด้านนอกผลลัพธ์ที่ต้องการ (ค่าเริ่มต้นของลำดับสุดท้าย) จะอยู่ที่ส่วนท้ายของเวกเตอร์ส่วนกลาง

รหัสหลอก :

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

รหัสความคิดเห็น :

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

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

ใช้ประโยชน์จากความจริงที่ว่าทวีคูณของ3ทั้งหมดนั้นบริสุทธิ์ ทดสอบบนIdeone

มันทำงานอย่างไร

ในบรรทัดแรก, r,=s={-1}ชุดs = {-1} (ชุด) และr = -1

ต่อไปเราจะอ่านค่าจำนวนเต็มจาก STDIN ทำซ้ำสตริงที่มีหลายครั้งแล้วรันมัน นี่เทียบเท่ากับรหัส Python ต่อไปนี้

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]

ในแต่ละซ้ำเราเริ่มต้นด้วยการหาสมาชิกที่เล็กที่สุดของ{r + 1, R + 2 R + 3}ที่ไม่ได้อยู่ในs ในการย้ำแรก initializes นี้rเป็น0

ในการวิ่งตามมาทั้งหมดsอาจ (และจะ) มีบางส่วนของr + 1 , r + 2และr + 3แต่ไม่เคยทั้งหมดเพราะหลาย ๆ3ล้วนบริสุทธิ์ เพื่อตรวจสอบคำสั่งนี้สังเกตว่าไม่มีหลายเมตรของ3จะอยู่ในรูป3k + 1 ที่ใบ2Mเป็นไปได้เฉพาะก่อนภาพซึ่งยังมีหลาย3 ดังนั้นmไม่สามารถปรากฏในลำดับ Collatz ของจำนวนใด ๆ ที่น้อยกว่าmและจึงบริสุทธิ์

หลังจากระบุRและเริ่มต้นnเราใช้ฟังก์ชั่น Collatz กับn=(n/2,3*n+1)[n%2]การเพิ่มแต่ละค่ากลางของnไปยังชุดss|={n}ด้วย เมื่อเราพบจำนวนnที่มีอยู่แล้วในs , {n}-sจะให้ผลผลิตชุดที่ว่างเปล่าและหยุดซ้ำ

ค่าสุดท้ายของrคือองค์ประกอบที่ต้องการของลำดับ


1
เพื่อเพิ่มสิ่งนี้พิสูจน์ว่าทวีคูณของ 3 ทั้งหมดนั้นบริสุทธิ์ ดูที่ Collatz sequence modulo 3. หลังจากการใช้กฎ 3x + 1, modulo คือ 1 หลังจากการใช้กฎ x / 2, mod 1 กลายเป็น 2 และ mod 2 กลายเป็น 1 กฎทั้งสองไม่สามารถสร้างหลายตัวได้ จาก 3 เว้นแต่ค่าเริ่มต้นจะเป็นตัวคูณที่ใหญ่กว่าของ 3 ที่ลดลงครึ่งหนึ่ง แต่สิ่งเหล่านี้เป็นค่าที่ใหญ่กว่าที่ยังไม่ได้สร้างดังนั้น n = 0 (mod 3) => n นั้นบริสุทธิ์
orlp


1

Java, 148 ไบต์

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

ไอเดียมัน! (คำเตือน: ความซับซ้อนแบบเลขชี้กำลังเนื่องจากการปรับให้เหมาะสมเป็นศูนย์)

การแปลงจากdo...whileลูปเป็นforลูปจะเป็นนักกอล์ฟ แต่ฉันมีปัญหาในการทำเช่นนั้น

ยินดีให้คำแนะนำการเล่นกอล์ฟตามปกติ


ไม่มาก แต่คุณสามารถกอล์ฟ 1 ไบต์ออกโดยการเปลี่ยนไปfor(b=1,i=1;i<n;i++) for(b=1,i=0;++i<n;)Btw ฉันเข้าใจว่าทำไม ideone ของคุณถึงขาดกรณีทดสอบ 50 แต่ทำไมมันถึงพลาด 10? มันสามารถจัดการกับมันได้โดยไม่มีปัญหา
Kevin Cruijssen

@KevinCruijssen เพราะการจัดรูปแบบจะไม่ดี
แม่ชีที่รั่วไหล

ไม่ใช่การปรับปรุงที่ดีที่สุด แต่ฉันไม่ได้ใช้เวลามากเกินไป ... (147 bytes)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;}
Poke

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;

บนพื้นฐานของPerl 5 คำตอบ อีกเล็กน้อยเนื่องจากไวยากรณ์ Perl6 นั้นมีการให้อภัยน้อยกว่าไวยากรณ์ Perl5 แต่ฉันจะจัดการกับสิ่งนี้ในตอนนี้


0

PHP, 233 124 ไบต์

<?$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 สำหรับฟังก์ชั่น:

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

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

นี่เป็นวิธีแก้ปัญหาที่ค่อนข้างตรงไปตรงมา มันใช้ฟังก์ชั่น Collatz ซ้ำ ๆ กับตัวแปร$aและเก็บในอาร์เรย์@cที่เห็นค่าแล้วหลังจากถึง 0 หรือ 1 จะเพิ่มขึ้นเรื่อย ๆ$aจนกระทั่งมันเป็นตัวเลขที่ยังไม่เคยเห็น นี่คือการทำซ้ำหลายครั้งเท่ากับอินพุตลบ 2 และในที่สุดก็มีค่าของ$aเอาท์พุท


0

Mathematica, 134 ไบต์

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)

รูปแบบที่ง่ายต่อการอ่าน:

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