Hasilkan Gambar-Gambar Urutan Gambar Hofstadter


16

Dalam Gödel, Escher, Bach , Douglas Hofstadter memperkenalkan urutan bilangan bulat yang biasanya disebut sebagai urutan gambar-angka:

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

Anda dapat menikmati mengerjakan sendiri definisi urutan sebagai bagian dari tantangan, tetapi jika Anda tidak dapat atau tidak ingin mengetahuinya, Anda dapat menemukannya di OEIS sebagai urutan A030124 dan definisi yang sedikit lebih jelas di Wikipedia .

Tulis program atau fungsi yang, diberikan nmelalui STDIN, ARGV atau argumen fungsi, mencetak daftar nangka pertama dari urutan ke STDOUT dalam format daftar yang masuk akal.

Ini adalah kode golf, solusi terpendek dalam byte yang menang.

Jawaban:


6

CJam, 38 30 29 21 byte

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

Cobalah online.

Bagaimana itu bekerja

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.                  ";

Contoh dijalankan

$ 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

Anda melewatkan kata aditsu ketika mengetikkan url untuk penerjemah
Beta Decay

@BetaDecay lalu mengapa tidak mengedit untuk memperbaikinya;)
Martin Ender

@ Martin Saya tidak berpikir saya punya cukup perwakilan ...
Beta Decay

2
@ BetaDecay Anda tidak, tetapi Anda masih bisa menyarankan mereka (yang bahkan memberi Anda 2 rep jika mereka diterima).
Martin Ender

Saya merasa sangat pintar untuk bermain golf dari 8 byte tambahan kode saya. Kemudian saya menyadari bahwa itu sekarang persis sama dengan jawaban dari histokrat, matsjoyce dan Peter Taylor ...
Dennis

6

Haskell, 67 61 60 56 55 53 karakter

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

kembali ke algoritma pertama.

solusi ini menghitung urutan komplemen dengan menjumlahkan elemen awal dari urutan. kemudian menghitung urutan karena semua angka antara nomor urutan pelengkap.

(#)adalah fungsi yang menghitung angka antara urutan komplemen.
hadalah urutan itu sendiri.
gadalah fungsi yang menjawab pertanyaan.

fungsi g didefinisikan hanya mengambil jumlah elemen yang dibutuhkan dari h.

kehalusan:

hsebenarnya adalah urutan gambar figur kecuali untuk 2 elemen pertama.
bukan urutan komplemen yang dihitung, tetapi urutan komplemen dengan menambahkan 1 untuk setiap elemen.
dua kehalusan ini adalah alasan scanl(+)8h(yang merupakan kode untuk urutan komplemen (kecuali untuk 2 elemen pertama) dengan 1 yang ditambahkan) ada 8di dalamnya. itu untuk elemen ketiga dari urutan komplemen dengan 1 ditambahkan padanya.
alasan perhitungan tidak hilang dua elemen pertama adalah karena mereka ditambahkan gdi 2:4:h.

contoh:

>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

Ruby, 54 48

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

Demo

Sunting: Memotong golf ini sedikit lebih banyak setelah saya menyadari saya tidak perlu memegang urutan pelengkap lengkap dalam memori. Begini cara kerjanya sekarang: Kami menggunakan xuntuk melacak nomor yang dihitung terbesar dalam urutan pelengkap, dan bmerupakan kumpulan kandidat untuk urutan. nkali, kami menampilkan elemen terkecil yang tersisa bdan menambahkannya ke xuntuk menghitung angka berikutnya dalam urutan komplemen. Lalu kami menghapus kedua angka dari kumpulan kandidat, jadi kami selalu mengeluarkan angka terkecil yang belum ditambahkan ke urutan mana pun.

Trik golf Ruby: Sintaks lambab Stabby lebih pendek dari definisi metode. Persyaratan bahwa output diberikan kepada STDOUT alih-alih sebagai nilai pengembalian mengilhami saya untuk menggunakan fakta bahwa nilai baliknya p(x)adalah x, yang biasanya tidak saya ingat karena itu bukan kasus dalam versi Ruby yang digunakan dalam Anarchy Golf.


1
Bagaimana cara kerjanya?
haskeller bangga

1
FWIW bisa Anda gunakan 2..2*n. Saya harus menggunakan n*nkarena saya melakukan secara efektif b = [x]^bsehingga saya membutuhkan elemen terbesar buntuk menjadi lebih besar dari nilai terbesar x, tetapi Anda b -= [x]hanya membutuhkan yang bberisi nilai kemungkinan terbesar dari urutan output.
Peter Taylor

4

GolfScript ( 24 21 byte)

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

Demo online

Ini dimulai sangat berbeda, tetapi akhirnya konvergen pada port GolfScript dari solusi Ruby histokrat sebelum Dennis membuat beberapa saran yang membawanya ke arah yang sedikit berbeda. Secara khusus, mencetak angka-angka ketika kami mengidentifikasinya menghemat sedikit lebih banyak daripada mengumpulkannya dalam sebuah array untuk dicetak pada akhirnya; alasannya adalah bahwa itu berarti bahwa kita tidak perlu khawatir tentang lebih dari 3 item di stack.

Pembedahan

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

Jika Anda mengganti ^dengan \-, Anda dapat mengganti ).*dengan 3*. Ini tidak akan menghemat byte, tetapi secara drastis mengurangi waktu berjalan dan penggunaan memori. - Anda harus dapat menyimpan satu byte dengan mempertahankan integer di atas array. Loop akan memiliki jumlah byte yang sama, tetapi inisialisasi akan menjadi satu byte lebih pendek.
Dennis

2
Mengatur penyatuan bekerja lebih baik daripada perbedaan:~.3*,1>\{(\(.p@+\|}*;
Dennis

3

J - 28 char

Pengambilan fungsi n sebagai argumen.

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

Kami menjalankan fungsi, dengan n argumen kiri, ke argumen kanannya berulang kali hingga tidak menghasilkan perubahan. Argumen untuk memulai adalah daftar 2 4.

Dalam fungsi itu sendiri, kita mengambil jumlah parsial +/\dan jumlah penuh +/, dan kemudian menambah keduanya &:>:. Kami kemudian menghasilkan setiap bilangan bulat dari 2 menjadi satu lebih dari jumlah penuh (2+i. ), dan mengatur pengurangan ( -.) jumlah parsial, meninggalkan urutan figur-figur yang lebih panjang dengan definisi. Akhirnya, kami memperpendek atau memperpanjang daftar secara siklis n.

Hasilnya adalah itu 2 4menjadi 3 7, dan ini dihapus dari 2..8meninggalkan 2 4 5 6 8. Setelah satu putaran, 2 4 5 6 8menjadi 3 7 12 18 26menjadi

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

Dengan cara ini, kami berulang kali memperpanjang urutan gambar-gambar. Itu$ perilaku panjang adalah cara menghemat karakter non-sepele menunggu urutan tumbuh dengan panjang natau lebih besar, dan keluaran nnilai pertama ketika mereka berhenti berubah. Kita juga tidak harus menunggu lama: kita bisa mendapatkan sebanyak 46336 istilah dari empat aplikasi kata kerja dalam.

Fungsi yang sama di k:

  • k2, 37 karakter: {{x#y@&~_lin[y:1+!1+/y;1+\y]}[x]/2 4}
  • k4, 36 karakter: {{x#y@&~(y:2+!1+/y)in\:1+\y}[x]/2 4}

2

Jawa - 183 158

Ini adalah yang paling saya main golf, dan saya bangga karenanya! (Meskipun tidak ada di dekat bagian atas tangga lagu (karena itu Java))

Terima kasih kepada Peter Taylor untuk saran

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

lebih besar -

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

Batin untuk loop sangat mengesankan dikaburkan, tapi saya pikir Anda dapat menyimpan beberapa byte. Byte.valueOfmenghemat tiga, dan karena pertanyaan tidak menentukan kisaran input, saya pikir itu harus diterima. Di luar loop, mhanya digunakan untuk menginisialisasi n, sehingga k++<mbisa jadi m-->0, menghilangkan kseluruhnya. int[] ndapat diinisialisasi sebagai int n[]dan digabungkan ke dalam initialiser sebelumnya. ntidak pernah memegang nilai selain 1, jadi n[...]!=0bisa jadi n[...]>0. Penginisialisasi kemudian dapat menjadi bagian penginisialisasi dari forloop pertama .
Peter Taylor

Dan jika Anda menyingkirkan udan hanya menggunakan ++w, tidak perlu diatur n[q]atau n[w]. Ada satu bug, di mana Anda menjalankan akhir nkapan m==2, yang tampaknya paling baik diperbaiki dengan menginisialisasi n=new int[2*m*m], tapi saya pikir itu turun ke 157 byte.
Peter Taylor

Apa yang saya maksudkan tentang penginisialisasi menjadi bagian penginisialisasi pertama untuk loop adalah for(int q=1,w=2,m=...,n[]=...;m-->0;){...menyimpan tanda titik koma.
Peter Taylor

1

Python 2 - 77 byte


Kode:

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

Bekerja sama dengan solusi @ histocrat, kecuali input berasal dari stdin.


1

Python 2 - 68

R=[1]
s=0
n=input()
while n:s+=1+(s+1in R);R+=[R[-1]+s];print s;n-=1

0

Jelly , 15 byte

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

Cobalah online!

Kesalahan memori pada input 6.

Bagaimana itu bekerja

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

Versi yang lebih efisien, 16 byte

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

Cobalah online!

Gunakan ide dari jawaban J. ini . Potong ke panjang yang diinginkan setiap iterasi, dan ambil fixpoint. Saya pikir menggunakan S(jumlah) alih-alih Ṁ‘(maks + 1), tapi saya tidak bisa menjamin kebenarannya.


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.