สร้างลำดับตัวเลขรูปของ Hofstadter


16

ในGödel, Escher, Bach , Douglas Hofstadter แนะนำลำดับจำนวนเต็มซึ่งโดยทั่วไปจะเรียกว่าลำดับตัวเลขรูป:

2, 4, 5, 6, 8, 9, 10, 11, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, ...

คุณอาจจะสนุกกับการทำงานออกจากความหมายของลำดับตัวเองเป็นส่วนหนึ่งของความท้าทาย แต่ถ้าคุณไม่สามารถหรือไม่ต้องการที่จะคิดออกคุณสามารถค้นหาได้ใน OEIS เป็นลำดับA030124และคำนิยามที่ชัดเจนเล็กน้อยในวิกิพีเดีย

เขียนโปรแกรมหรือฟังก์ชั่นที่กำหนดnผ่าน STDIN, ARGV หรือฟังก์ชั่นอาร์กิวเมนต์พิมพ์รายการnหมายเลขแรกของลำดับไปยัง STDOUT ในรูปแบบรายการที่สมเหตุสมผล

นี่คือโค้ดกอล์ฟทางออกที่สั้นที่สุดในหน่วยไบต์ชนะ

คำตอบ:


6

CJam, 38 30 29 21 ไบต์

li_3*,2>\{(_pX+:X-}*;

ลองออนไลน์

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

li                     " Read an integer N from STDIN.              ";
  _3*,2>               " Push S := [ 2 3 ... (N * 3 - 1) ].         ";
        \{        }*   " Do the following N times:                  ";
          (            " Shift an integer I from S.                 ";
           _p          " Print a copy of I, followed by a linefeed. ";
             X+:X      " Execute X += I. (X is initialized to 1.)   ";
                 -     " Remove X from S.                           ";
                    ;  " Discard S from the stack.                  ";

ตัวอย่างการวิ่ง

$ cjam <(echo 'li_3*,2>\{(_pX+:X-}*;') <<< 20
2
4
5
6
8
9
10
11
13
14
15
16
17
19
20
21
22
23
24
25

คุณพลาด aditsu เมื่อพิมพ์ url สำหรับล่าม
Beta Decay

@BetaDecay แล้วทำไมไม่แก้ไขจะแก้ไขได้;)
มาร์ตินเอนเดอร์

@ มาร์ตินฉันไม่คิดว่าฉันมีตัวแทนมากพอ ...
Beta Decay

2
@BetaDecay คุณทำไม่ได้ แต่คุณยังสามารถแนะนำพวกเขาได้ (ซึ่งจะให้ 2 ตัวแทนถ้าพวกเขาได้รับการยอมรับ)
Martin Ender

ฉันรู้สึกชาญฉลาดมากในการเล่นกอล์ฟเพิ่มรหัสอีก 8 ไบต์ จากนั้นฉันก็รู้ว่าตอนนี้มันก็เหมือนกับคำตอบของนักประวัติศาสตร์, Matsjoyce และ Peter Taylor ...
Dennis

6

Haskell, 67 61 60 56 55 53 ตัวอักษร

g n=take n$2:4:h
a#(x:s)=[a..x-2]++x#s
h=5#scanl(+)8h

กลับไปที่อัลกอริทึมแรก

โซลูชันนี้คำนวณลำดับส่วนประกอบโดยการรวมองค์ประกอบเริ่มต้นของลำดับ จากนั้นจะคำนวณลำดับเป็นตัวเลขทั้งหมดระหว่างหมายเลขลำดับของส่วนประกอบ

(#)เป็นฟังก์ชันที่คำนวณตัวเลขระหว่างลำดับการเติมเต็ม
hเป็นลำดับตัวเอง
gเป็นฟังก์ชั่นที่ตอบคำถาม

ฟังก์ชั่น g ถูกกำหนดให้ใช้ปริมาณองค์ประกอบที่ต้องการจาก h

รายละเอียดปลีกย่อย:

hอันที่จริงแล้วลำดับตัวเลขรูปยกเว้นสำหรับ 2 องค์ประกอบแรก
ไม่ใช่การคำนวณลำดับประกอบ แต่เรียงลำดับส่วนประกอบที่มีการเพิ่ม 1 สำหรับแต่ละองค์ประกอบ
รายละเอียดปลีกย่อยทั้งสองนี้เป็นเหตุผลscanl(+)8h(ซึ่งเป็นรหัสสำหรับลำดับประกอบ (ยกเว้นองค์ประกอบ 2 ประการแรก) ที่มีการเพิ่ม 1) มี8อยู่ในนั้น มันเป็นองค์ประกอบที่สามของลำดับประกอบกับ 1 ที่เพิ่มเข้าไป
เหตุผลการคำนวณจะไม่ได้หายไปในองค์ประกอบที่สองคนแรกเป็นเพราะพวกเขามีการเพิ่มในในg2:4:h

ตัวอย่าง:

>g 50
[2,4,5,6,8,9,10,11,13,14,15,16,17,19,20,21,22,23,24,25,27,28,29,30,31,32,33,34,36,37,38,39,40,41,42,43,44,46,47,48,49,50,51,52,53,54,55,57,58,59]

5

ทับทิม, 54 48

f=->n{x=1
b=*2..n*n
n.times{b-=[x+=p(b.shift)]}}

การสาธิต

แก้ไข: ตีกอล์ฟนี้อีกเล็กน้อยเมื่อฉันรู้ว่าฉันไม่จำเป็นต้องจัดลำดับความสมบูรณ์แบบเต็มในหน่วยความจำ นี่คือวิธีการทำงานตอนนี้: เราใช้xเพื่อติดตามจำนวนที่คำนวณมากที่สุดในลำดับประกอบและbเป็นกลุ่มของผู้สมัครสำหรับลำดับ nครั้งที่เราส่งออกองค์ประกอบที่เล็กที่สุดที่เหลืออยู่ในbและเพิ่มเข้าไปxในการคำนวณจำนวนต่อไปในลำดับประกอบ จากนั้นเราลบตัวเลขทั้งสองออกจากกลุ่มผู้สมัครดังนั้นเราจึงแสดงจำนวนที่เล็กที่สุดที่ยังไม่ได้เพิ่มไปยังลำดับต่อไป

เทคนิคการเล่นกอล์ฟทับทิม: ไวยากรณ์แลมบ์ดาแล็บด้าสั้นกว่าคำจำกัดความวิธีการ ความต้องการที่เอาท์พุทให้กับ STDOUT แทนที่จะเป็นค่าตอบแทนเป็นแรงบันดาลใจให้ฉันใช้ความจริงที่ว่าค่าส่งคืนของp(x)คือxซึ่งปกติฉันจำไม่ได้เพราะไม่ใช่กรณีในรุ่น Ruby ที่ใช้ใน Anarchy Golf


1
มันทำงานยังไง?
ภูมิใจ haskeller

1
FWIW ที่คุณสามารถ2..2*nใช้ได้ ฉันต้องใช้n*nเพราะฉันทำอย่างมีประสิทธิภาพb = [x]^bดังนั้นฉันจึงต้องการองค์ประกอบที่ใหญ่ที่สุดbที่จะใหญ่กว่าค่าที่มากที่สุดxแต่สิ่งที่คุณb -= [x]ต้องการคือสิ่งที่bมีค่ามากที่สุดเท่าที่จะเป็นไปได้ของลำดับเอาต์พุต
Peter Taylor

4

GolfScript ( 24 21 ไบต์)

~.3*,1>\{(\(.p@+\|}*;

การสาธิตออนไลน์

สิ่งนี้เริ่มแตกต่างออกไปมาก แต่สุดท้ายก็มาบรรจบกันที่พอร์ตGolfScriptของสารละลายทับทิมของฮิสโทแคตก่อนที่เดนนิสจะให้คำแนะนำซึ่งนำไปสู่ทิศทางที่แตกต่างกันเล็กน้อย โดยเฉพาะอย่างยิ่งการพิมพ์ตัวเลขตามที่เราระบุไว้จะช่วยประหยัดการรวบรวมพวกเขาในอาร์เรย์สำหรับการพิมพ์ในตอนท้าย เหตุผลก็คือมันไม่ได้หมายความว่าเราไม่ต้องกังวลเกี่ยวกับสแต็คมากกว่า 3 รายการ

การผ่า

~.3*,           # Eval input n, dup, multiply by 3, make list [0 1 ... 3n-1]
1>              # Discard 0, which is part of neither sequence
\{              # Execute n times: stack contains pool of numbers not yet seen
                # in either sequence and the first element of it is the next element of the
                # complement sequence
  (\(           #   Pop two numbers from the start of the pool: stack is
                #     pool[0] pool[2..max] pool[1]
  .p            #   Print pool[1]
  @+            #   Rotate pool[0] to top and add to pool[1]
  \|            #   Place pool[0]+pool[1] at the start of the pool and
                #   (this is the clever bit) remove it from later in the pool
}*
;               # Discard the unused remainder of the pool

หากคุณแทนที่^ด้วย\-คุณสามารถแทนที่ด้วย).* 3*สิ่งนี้จะไม่บันทึกไบต์ใด ๆ แต่จะลดเวลาการใช้งานและการใช้หน่วยความจำลงอย่างมาก - คุณควรจะสามารถบันทึกหนึ่งไบต์โดยเก็บจำนวนเต็มไว้ด้านบนของอาร์เรย์ การวนซ้ำจะมีจำนวนไบต์เท่ากัน แต่การเริ่มต้นจะสั้นลงหนึ่งไบต์
Dennis

2
การรวมกลุ่มทำงานได้ดียิ่งกว่าความแตกต่าง:~.3*,1>\{(\(.p@+\|}*;
เดนนิส

3

J - 28 ตัวอักษร

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

($+/\(-.~2+i.)&:>:+/)^:_&2 4

เราเรียกใช้ฟังก์ชั่นที่มีnอาร์กิวเมนต์เป็นซ้ายเข้าสู่อาร์กิวเมนต์ที่ถูกต้องซ้ำ ๆ จนกระทั่งมันไม่มีการเปลี่ยนแปลง 2 4อาร์กิวเมนต์ที่จะเริ่มรายการ

ในการทำงานของตัวเองเราจะใช้ผลรวมบางส่วน+/\และเต็มทุนและจากนั้นพวกเขาทั้งสองเพิ่มขึ้นด้วย+/ &:>:จากนั้นเราจะสร้างจำนวนเต็มทุกจำนวนตั้งแต่ 2 ถึงหนึ่งมากกว่าผลรวมเต็ม ( 2+i.) และตั้งค่าการลบ ( -.) ผลรวมบางส่วนทำให้ลำดับตัวเลขรูปที่ยาวขึ้นตามคำจำกัดความ nสุดท้ายเราย่นหรือขยายวนรายการความยาว

ผลที่ตามมาคือการที่2 4จะกลายเป็น3 7และนี้ถูกลบออกจากออกจาก2..8 2 4 5 6 8หลังจากรอบอื่น2 4 5 6 8จะ3 7 12 18 26กลายเป็น

2 4 5 6 8 9 10 11 13 14 15 16 17 19 20 21 22 23 24 25 27

ด้วยวิธีนี้เราจะขยายลำดับภาพร่างซ้ำ ๆ $พฤติกรรมความยาวเป็นเพียงวิธีการประหยัดตัวละครที่ไม่น่ารำคาญของการรอคอยสำหรับลำดับที่จะเติบโตไปยาวnหรือสูงกว่าและเอาท์พุทnค่าเป็นอันดับแรกเมื่อพวกเขาหยุดการเปลี่ยนแปลง เราไม่ต้องรอนานเช่นกัน: เราสามารถรับได้มากถึง 46336 คำจากสี่แอปพลิเคชันของคำกริยาภายใน

ฟังก์ชั่นเดียวกันใน k:

  • k2, 37 ตัวอักษร: {{x#y@&~_lin[y:1+!1+/y;1+\y]}[x]/2 4}
  • k4, 36 ตัวอักษร: {{x#y@&~(y:2+!1+/y)in\:1+\y}[x]/2 4}

2

Java - 183 158

นี่คือสิ่งที่ฉันเคยเล่นกอล์ฟมากที่สุดและฉันภูมิใจในสิ่งนี้! (แม้ว่าจะไม่ได้อยู่ใกล้กับด้านบนของแผนภูมิ (เพราะเป็น Java))

ขอบคุณ Peter Taylor สำหรับคำแนะนำ

class f{public static void main(String[]a){int q=1,m=Byte.valueOf(a[0]),w=2,n[]=new int[m*m*2];for(n[q+=w]=1;m-->0;){System.out.println(w);for(;n[++w]>0;);}}}

ใหญ่กว่า -

public class f {
    public static void main(String[] a) {
        int q = 1, m = Byte.valueOf(a[0]), w = 2, n[] = new int[m * m * 2];
        for (n[q += w] = 1; m-- > 0;) {
            System.out.println(w);
            for (; n[++w] > 0;)
                ;
        }
    }
}

ด้านในของลูปนั้นค่อนข้างงงงวยอย่างน่าประทับใจ แต่ฉันคิดว่าคุณสามารถบันทึกได้สองสามไบต์ Byte.valueOfบันทึกสามและเนื่องจากคำถามไม่ได้ระบุช่วงของการป้อนข้อมูลฉันคิดว่ามันควรจะยอมรับได้ นอกลูปmใช้เพื่อกำหนดค่าเริ่มต้นnเท่านั้นดังนั้นk++<mสามารถm-->0กำจัดได้kทั้งหมด int[] nสามารถเริ่มต้นเป็นint n[]และผสานเข้ากับการเริ่มต้นก่อนหน้านี้ nไม่เคยถือค่าอื่น ๆ กว่า1ดังนั้นอาจจะn[...]!=0 n[...]>0ผู้เริ่มต้นสามารถกลายเป็นส่วนเริ่มต้นของการforวนซ้ำแรก
Peter Taylor

และถ้าคุณได้รับการกำจัดuและการใช้งานเพียงแค่++wต้องมีชุดไม่มีหรือn[q] n[w]มีข้อผิดพลาดหนึ่งข้อที่คุณหมดnเวลาm==2ซึ่งดูเหมือนว่าจะได้รับการแก้ไขที่ดีที่สุดเมื่อเริ่มต้นn=new int[2*m*m]แต่ฉันคิดว่ามันลดลงเหลือ 157 ไบต์
Peter Taylor

สิ่งที่ฉันหมายถึงเกี่ยวกับการเริ่มต้นกลายเป็นส่วนเริ่มต้นของการวนแรกคือfor(int q=1,w=2,m=...,n[]=...;m-->0;){...การบันทึกเครื่องหมายอัฒภาค
Peter Taylor

1

Python 2 - 77 ไบต์


รหัส:

n=input();x=1;b=range(2,n*n)
while n:v=b.pop(0);x+=v;print v;b.remove(x);n-=1

ทำงานเหมือนกับโซลูชันของ @ histocrat ยกเว้นอินพุตมาจาก stdin



0

เยลลี่ 15 ไบต์

SƤŻ‘µṀ‘Rḟ
2dz¡ḣ

ลองออนไลน์!

ข้อผิดพลาดของหน่วยความจำที่อินพุต 6

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

SƤŻ‘µṀ‘Rḟ  Aux. link (monad). Input: part of the desired sequence
SƤŻ‘       Sum of prefixes, then prepend a zero and increment
           This is a list of numbers to exclude from the next iteration
    µ      Re-focus on the above
     Ṁ‘Rḟ  Create range 1..Max + 1, then remove all elements of the above
           +1 is needed to progress from [2] to [2,4]

2dz¡ḣ  Main link (monad). Input: n, number of terms
2dz¡   Starting from 2, apply aux. link n times
    ḣ  Take n elements from the beginning

รุ่นที่มีประสิทธิภาพมากกว่า 16 ไบต์

SƤŻ‘µṀ‘Rḟḣ³
2ÇÐL

ลองออนไลน์!

ใช้แนวคิดจากคำตอบ Jนี้ ตัดให้ยาวตามที่ต้องการในแต่ละการวนซ้ำและรับฟิกซ์พ้อยท์ ฉันคิดว่าใช้S(ผลรวม) แทนṀ‘(สูงสุด + 1) แต่ฉันไม่สามารถรับประกันความถูกต้องได้


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