Hasilkan urutan Stöhr


12

Saya belajar Ruby dan menulis kode nontrivial pertama saya untuk mengatasi masalah ini.

Tantangannya adalah untuk menghasilkan elemen n pertama dari urutan Stöhr , S , yang didefinisikan sebagai berikut:

S [0] = 1

S [n] adalah angka terkecil yang tidak dapat dinyatakan sebagai jumlah dari dua elemen sebelumnya yang berbeda dalam urutan.

Jadi urutan dimulai dengan 1, 2, 4, 7, dan 10. Elemen berikutnya adalah 13, karena 11 (= 1 + 10) dan 12 (= 2 + 10) adalah jumlah dari elemen sebelumnya, tetapi 13 tidak.

Saya mencari kode terpendek. Saya sendiri, di Ruby, panjangnya 108 karakter, tapi mungkin saya akan menunggu untuk melihat apa yang orang lain buat sebelum mempostingnya?


Saya suka jawabannya sejauh ini. Sekarang, mungkin sudah terlambat untuk kembali dan mengubah persyaratan, tapi saya kira saya seharusnya menyebutkan bahwa saya sangat tertarik dengan solusi yang menggunakan definisi urutan itu sendiri (yaitu, kode tidak tahu sebelumnya bahwa pada akhirnya jumlahnya naik 3). Jadi: poin bonus moral jika Anda bisa melakukannya.
Théophile

Itulah masalah dengan urutan matematis. Jika Anda tahu polanya, biasanya akan lebih pendek.

Urutan ini adalah aritmatika tanpa menggunakan (?).
user75200

@ user75200 Urutannya bukan aritmatika, seperti yang Anda lihat dari perbedaan dalam tiga elemen pertama, tetapi selanjutnya mulai dari elemen ketiga memang aritmatika. Ini digunakan sehubungan dengan masalah Prangko.
Théophile

Jawaban:


13

APL, 7

Di APL Anda dapat memilih apakah Anda ingin bekerja dengan indeks 0 atau indeks 1. Anda melakukan ini dengan mengatur variabel global ⎕IO ← 0

Jika kita memilih untuk bekerja di indeks 0, kita memiliki:

+\3⌊1⌈⍳

Penjelasan:

⍳    creates a sequence 0...n   (0 1 2 3 4 5)
1⌈   takes whichever is bigger, number in sequence or 1 (1 1 2 3 4 5)
3⌊   takes whichever is lower, number in sequence or 3 (1 1 2 3 3 3)
+\   partial sums for the sequence (1 2 4 7 10 13)

Cobalah di tryapl.org


Tidak bisakah Anda bekerja dengan 1 indeks berbasis dan kemudian membuat array 1 ke n dan hanya menambahkannya dengan 1 lainnya? Jika itu bisa dilakukan, apakah lebih pendek?
Pengoptimal

Kode yang saya dapatkan lebih panjang. Ini adalah kode saya untuk indeks 1, 10 karakter: + \ 3⌊1, ⍳¯1 + Juga, versi indeks-0 berfungsi dengan argumen 0 juga, sedangkan yang ini tidak.
Moris Zucca

Ah. ya APL benar-benar bersinar melalui sini ..
Pengoptimal

9

Haskell - 11 21

Urutan tak terbatas malas

1:2:[4,7..]

Fungsi yang mengembalikan hanya jumlah anggota yang disediakan (desah)

flip take$1:2:[4,7..]

Anda harus mengambil input dan hanya mencetak nangka pertama .
Pengoptimal

4
@Optimizer Nah, secara teknis , Anda harus "menghasilkan elemen n pertama dari urutan Stöhr" —tidak mengatakan Anda tidak dapat menghasilkan sisanya juga! Itu tidak mengatakan bahwa Anda harus mengambil input juga. kode asli swish sebenarnya menghasilkan n istilah pertama , untuk n apa saja .
wchargin

1
@WChargin mencoba menjadi oversmart bukanlah hal baru. Mengambil kata-kata OP terlalu harfiah dan menghasilkan output ekstra dari yang dibutuhkan keduanya dianggap sebagai celah standar.
Pengoptimal

2
@ Opptizer Sebenarnya, menjadi malas berarti tidak ada output tambahan yang akan dihasilkan sampai Anda memintanya, dan Anda dapat meminta persyaratan apa pun yang Anda inginkan.
desir

1
@ harap saya tidak mengerti. Apa yang malas di sini?
Pengoptimal

7

Python 2, 37 35 byte

lambda n:[1,2][:n]+range(4,n*3-4,3)

Memanfaatkan pola ...


1
Anda dapat memasukkan 4dalam kisaran:lambda n:[1,2][:n]+range(4,n*3-4,3)
Jakube

Temuan yang bagus. Diedit ke 35 sekarang.
Logic Knight

6

CJam, 14 byte

1l~{_p_3e<+}*;

Uji di sini.

Mulai dari 1. Kemudian, S [n] = S [n-1] + min (S [n-1], 3) .

1l~{_p_3e<+}*;
1              "Push 1.";
 l~            "Read and evaluate input N.";
   {       }*  "Repeat this block N times.":
    _p         "Duplicate the last number and print it.";
      _3e<     "Duplicate it again, and take minimum with 3.";
          +    "Add to last number.";
             ; "Discard final number to prevent output.";

Ini secara umum mudah untuk h -Stöhr urutan jika kita mengganti 3 dengan 2 jam -1 .


6

Brainfuck, 13 karakter

+.+.++.[+++.]

Atau 30 karakter jika kita ingin membatasi ke n output:

,->+.<[->+.<[->++.<[->+++.<]]]

1
Saya pikir Anda perlu mencetak nelemen pertama , bukan aliran yang tak terbatas dari mereka ...
Sp3000

@ Sp3000 Apakah menggunakan kode karakter sebagai input dan output numerik diterima secara umum? Tidak dapat menemukan di meta. Dengan itu akan cukup mudah untuk memperbaiki kode BF.
randomra

Secara pribadi saya tidak yakin apa konsensus umum untuk ini, maaf. Saya punya sedikit masalah dengan ini juga.
Sp3000

untuk elemen n pertama, saya pikir saya bisa melakukan -> +. <[-> +. <[-> ++. <[-> +++. <]]] (29 karakter), tapi itu tidak elegan . Dan saya tidak berpikir bahasanya terbatas pada penggunaan kode ASCII untuk input dan output.
jgosar

1
Kode Anda harus menjawab pertanyaan bahkan jika itu tidak elegan. Saya akan menyarankan untuk mengedit posting dan memperbaiki jawabannya ,->+.<[->+.<[->++.<[->+++.<]]]. (Anda melewatkan koma pembacaan input di awal.)
randomra

4

Python, 136 byte

def f(n):
 if n<1:return[1]
 x=f(n-1);y=set(x)|{a+b for a in x for b in x if a!=b};return x+[min([a for a in range(1,max(y)+2)if{a}-y])]

Langsung dari definisi. Saya tidak yakin seberapa banyak saya bisa bermain golf ini - ini tentu jauh lebih lama dari yang saya harapkan.


3

J, 14 karakter

Ini hanya mengubah kode [1,2, 4+3*k (k=0..n-1) ]urutan dan mengambil yang pertama N.

   ({.1,2,4+3*i.) 10
1 2 4 7 10 13 16 19 22 25

.

J, 18 karakter

Yang ini menggunakan kombinasi linear [0,1,2,3...], [1,1,0,0...]dan [0,1,1,1...]. Seharusnya lebih pendek tapi sepertinya tidak bisa golf.

   ((3&*+<&2-2**)@i.) 10
1 2 4 7 10 13 16 19 22 25

3

Prelude , 32 20

Sunting: ... dengan dua kali suara sekarang!

?(1-)
4 +3
2  ^
1 !^

Ini mengasumsikan interpreter Python dengan NUMERIC_OUTPUT = True. Seperti pengajuan Brainfuck, jawaban ini mengasumsikan bahwa input diberikan dalam bentuk titik kode. Ini sebagian untuk mendapatkan lebih banyak perhatian untuk diskusi meta ini (dan sebagian lagi, karena saya suka Prelude). Jadi, jika Anda ingin mencetak 32 angka pertama, katakanlah, Anda perlu memberi ruang pada STDIN. Tentu saja, ini berarti ada batas atas untuk input yang valid, tetapi jawaban ini tidak menang, jadi saya pikir dalam batasan Prelude ini tidak apa-apa.

Penjelasan

Di Prelude, semua baris dieksekusi secara paralel, yang barisnya memiliki tumpukan sendiri, diinisialisasi ke jumlah nol yang tak terbatas. Hanya ada satu penunjuk instruksi (menunjuk pada kolom), jadi jika Anda memasukkan satu loop pada satu suara, semua suara lain akan berputar bersamanya.

Dalam berikut ini saya telah mengubah kode, sehingga saya dapat membuat anotasi baris, bukan kolom:

?421  Read a character into the first stack. Push 4, 2, 1 onto the other stacks, respectively.
      Generally, the fourth stack will hold the next number to be printed, the third stack the
      one after that, and the second stack the number two steps ahead.
(     Start a loop if the input wasn't 0.
1+ !  Push a 1 onto the first stack. Add the top elements in the second stack. On the first
      iteration this will be 0 and 4, so it does nothing. On all further iterations
      this will increment the last number by 3.
-3^^  Subtract one from the first stack. Push a 3 onto the second stack for the next iteration.
      Copy the last value from the second to the third, and the third to the fourth stack.
)     If the top of the first stack is not 0, jump back to the column after the (.

2

JavaScript (ES6) 92

Sebagai fungsi rekursif berdasarkan definisi masalah

S=(n,v=1,s=[],r=0)=>[for(a of s)for(b of s)r+=(a-b&&a+b==v)]|r||(s.push(v),--n)?S(n,v+1,s):s

Menggunakan pola 1,2, 1 + 3 * k: 58

S=(n)=>(i=>{for(t=1;n>r.push(t+=i);i+=(i<3));})(0,r=[])||r

Catatan: menemukan urutan h-Stöhr (memverifikasi jumlah hingga hangka, bukan hanya 2). The RFungsi mencoba semua jumlah possibile hingga sejumlah tertentu daftar elemen.

S=(n,h=2,s=[],v=1,R=(t,v,l,i=0,r=t,w)=>{
  for(;r&&l&&v[i];i++)
    w=[...v],r=!R(t-w.splice(i,1),w,l-1)
  return!r;
})=>R(v,s,h)||(s.push(v),--n)?S(n,h,s,v+1):s

Ungolfed kira-kira setara (dan kompatibel dengan ES5)

function S(n, v, s)
{
  var r=0,a,b
  v = v||1
  s = s||[]
  for(a of s)
    for(b of s)
    {
      if (a != b && a+b == v) 
        r++;
    }
  if (r == 0) 
  {
    s.push(v);
    --n;
  }
  if (n != 0)
     return S(n,v+1,s)
  else
     return s
}

Uji di konsol FireFox / FireBug. Fungsi sederhana:

S(20)

[1, 2, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, 49, 52, 55]

Fungsi lanjutan:

S(10,5)

[1, 2, 4, 8, 16, 32, 63, 94, 125, 156]


2

> <> (ikan) , 72 65 49 46 karakter

1n1-:?!;' 'o2n1-v
v1&no' ':<4&;!?:<
>-:?!;&3+^

Masukan diberikan kepada penerjemah:

>fish.py stohr.fish -v 10
1 2 4 7 10 13 16 19 22 25

Program pertama saya> <>, saran dihargai.


Oh bagus! Saya berharap seseorang akan menulis program> <>.
Théophile

2

> <>, 31 byte

4i1nao:?!;2nao1-:?!;$:nao3+$d0.

Membaca dalam satu karakter, menggunakan titik kode (mis. Spasi = 32) dan mencetak angka satu pada setiap baris.


2

Perl6 22/30

Saya akan melihat apakah Perl6 dapat menyimpulkan urutan untuk saya.

Untuk melakukan itu saya menggunakan REPL yang dibangun ke dalam Perl6

$ perl6
> 1,2,4,7...*
Unable to deduce arithmetic or geometric sequence from 2,4,7 (or did you really mean '..'?)
> 1,2,4,7,10...*
1 2 4 7 10 13 16 19 22 25 28 31 34 37 40 43 46 49 52 55 58 61 64 67 70 ...

Hmm, saya melihat pola yang disimpulkan Perl. Setelah 4 untuk mendapatkan nilai berikutnya Anda hanya menambahkan 3.

1,2,4,*+3...*

Yang menyimpan satu karakter membuat kode untuk mendapatkan daftar nomor tak terbatas dalam urutan 13 karakter Stöhr.

Kode ini hanya melakukan sesuatu yang berguna dalam REPL karena mencetak intisari hasilnya bagi kami. Untuk mencetaknya, Anda harus memberi tahu Perl untuk mencetak hasilnya.

$ perl6 -e 'say 1,2,4,*+3...*'

( * + 3hanyalah cara untuk mendapatkan referensi kode yang mengembalikan 3 ditambahkan ke argumen itu saja. Cara lain untuk menulisnya adalah { $_ + 3 }, atau -> $i { $i + 3 }, { $^i + 3 }atau sub ($i){ $i + 3 })


Cara terpendek untuk membuat sesuatu Callable untuk menghasilkan elemen n pertama adalah untuk mendapatkan sepotong elemen.

{(1,2,4,*+3...*)[^$_]} # 22

Dalam konteks kosong yang akan menghasilkan nilai pertama $_, lalu segera membuangnya.

Dalam apa pun selain konteks batal itu menciptakan blok kode anonim (subrutin dasar tanpa nama) yang mengambil satu argumen.

# store it in a scalar variable
my $sub = {(1,2,4,*+3...*)[^$_]};
say $sub.(5);
# 1 2 4 7 10

# use it immediately
say {(1,2,4,*+3...*)[^$_]}.(5);
# 1 2 4 7 10

# pretend it always had a name
my &Stöhr-first = {(1,2,4,*+3...*)[^$_]};
say Stöhr-first 5;

Jika Anda benar-benar berpikir itu harus memiliki nama untuk memenuhi syarat sebagai valid untuk tantangan ini, Anda mungkin akan melakukan ini:

sub s(\n){(1,2,4,*+3...*)[^n]} # 30

Meskipun karena sjuga digunakan untuk operator substitusi, untuk memanggil ini parens adalah non-opsional. (Anda bisa memberikannya nama yang berbeda saya kira)

say s(5);
# 1 2 4 7 10

Kecuali ditentukan lain dalam tantangan, pengiriman ke tantangan golf kode harus program atau fungsi lengkap , bukan hanya cuplikan.
Martin Ender

@ MartinBüttner bersikap adil 1,2,4,*+3...*sebenarnya menciptakan objek yang akan menghasilkan nilai yang dibutuhkan. Saya tidak berpikir bahwa banyak orang benar-benar akan membuat sesuatu Callable di sekitar sesuatu seperti itu di Perl6.
Brad Gilbert b2gills

2

Saya melihat sudah ada jawaban java yang JAUH lebih baik tetapi saya menghabiskan beberapa waktu untuk hal ini dan saya akan mempostingnya. bahkan jika itu menyebalkan.

Java 313 char (+4 agar pas di layar)

import java.util.*;public class S{public static void main(String[] a){
Set<Integer> S=new HashSet<Integer>();S.add(1);int i=1,k=0;
while(S.size()<=new Integer(a[0])){if(S.contains(i)){}else{k=0;for(int j:S){
for(int l:S){if(l!=j){if((j+l)==i)k=1;}}}if(k==0)S.add(i);}i++;}for(int x:S)
{System.out.println(x);}}}

selalu bersyukur mendapatkan tip atau petunjuk tentang cara meningkatkan


1

T-SQL 204

Mengasumsikan bahwa input dalam variabel yang disebut @N. Saya bisa membuat prosedur jika Anda mau, tetapi sebenarnya tidak ada cara yang baik untuk mendapatkan STD_IN di T-SQL.

Juga, Anda dapat bonus moral!

DECLARE @Q INT=0,@B INT=2
DECLARE @ TABLE(A INT)WHILE @N>0
BEGIN
SET @N-=1
WHILE @B>1
BEGIN
SET @Q+=1
SELECT @B=COUNT(*)FROM @ C,@ B WHERE C.A+B.A=@Q
END
INSERT INTO @ VALUES(@Q)SET @B=2
END
SELECT*FROM @

Bagus! Saya tidak tahu banyak tentang SQL — bagaimana @N digunakan di sini? Saya melihat bahwa itu diatur di dekat awal, tetapi kemudian tampaknya tidak direferensikan nanti.
Théophile

Sepertinya @Nadalah "i" dari "for loop".
Jacob

Yakub benar. @N adalah "i" dari for loop, yang merupakan loop sementara di SQL. Pada dasarnya itu lintas bergabung dengan tabel itu sendiri dan menemukan pasangan yang menambah @Q. Jika setidaknya ada dua pasangan (yaitu bukan hanya angka dengan dirinya sendiri), maka ia akan melewatkannya. Kalau tidak, itu menambahkannya ke tabel. @ adalah nama tabel.
tanda

1

Mathematica, 27 byte

Hmmm, masih tidak ada jawaban Mathematica? Inilah dua:

NestList[#+3~Min~#&,1,#-1]&
Array[i=1/2;i+=3~Min~i&,#]&

keduanya mendefinisikan fungsi murni tanpa nama yang menerima integer dan mengembalikan daftar integer. Ini didasarkan pada hubungan perulangan yang sama dengan pengajuan CJam saya. Perhatikan bahwa Arraykode berbasis mulai dari 1/2, karena relasi perulangan selalu diterapkan sebelum nilai dikembalikan.



1

Python - bahkan tidak menutup (139)

Bertindak berdasarkan asumsi bahwa ini tidak mudah dihitung seperti yang dilakukan orang lain, solusi terpendek yang saya temukan adalah di bawah:

from itertools import combinations as C
x,i,n=[],1,input()
while len(x)<=n:
 if i not in [sum(y) for y in C(x,2)]:x.append(i)
 i+=1
print n

1

Clojure - 130 118

(defn s[n](last(take n(iterate #(if(<(count %)3)(conj %(+ (apply + %)1))(conj %(+(last %)(second %)(first %))))[1]))))

Versi tidak golf:

(defn stohr [n]
  (last
    (take n
      (iterate #(if (< (count %) 3)
                   (conj % (+ (apply + %) 1))
                   (conj % (+ (last %) (second %) (first %)))) [1]))))

Bagikan dan nikmati.


1

Ruby - 108 88

q=->n{*k=1;(m=k[-1];k<<([*m+1..2*m]-k.combination(2).map{|i,j|i+j})[0])while k.size<n;k}

Ini menggunakan definisi urutan.

Versi yang lebih mudah dibaca:

q=->n{
    *k=1
    (
        m = k[-1]
        k << ([*m+1..2*m] - k.combination(2).map{|i,j|i+j})[0]
    ) while k.size < n
    k
}

cetak q [10]

[1, 2, 4, 7, 10, 13, 16, 19, 22, 25]


Kiat golf Ruby: *k=1alih-alih k=[1]. foo while barbukannya while bar;foo;end. [*s..e]bukannya (s..e).to_a. .mapbukannya to_a.map. {|a,b|a+b}bukannya {|i|i.inject(:+)}.
histokrat

@ histokrat Terima kasih, itu sangat membantu!
Théophile

0

STATA 51

di 1 2 _r(a) 
loc b=3*$a-2
forv x=4(3)`b'{
di `x'
}

0

TI-BASIC, 41 27 30 byte

Untuk kalkulator Anda

Input N:For(I,1,N:I:If I>2:(I-2)3+1:Disp Ans:End

0

GML , 67 byte

n=argument0;for(i=1;i<=n;i++){t=i;if i>2t=(i-2)*3+1show_message(t)}
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.