Hasilkan urutan Recamán


20

Urutan Recamán ( A005132 ) adalah urutan matematika, didefinisikan sebagai:

A(0) = 0
A(n) = A(n-1) - n if A(n-1) - n > 0 and is new, else
A(n) = A(n-1) + n

Versi LaTex yang cantik di atas (mungkin lebih mudah dibaca):

A(n)={0if n=0A(n1)nif A(n1)n is positive and not already in the sequenceA(n1)+notherwise

Beberapa istilah pertama adalah 0, 1, 3, 6, 2, 7, 13, 20, 12, 21, 11

Untuk memperjelas, is newberarti apakah nomor tersebut sudah ada dalam urutan.

Diberikan bilangan bulat n, melalui argumen fungsi atau STDIN, kembalikan nistilah pertama dari urutan Recamán.


Ini adalah tantangan kode-golf, sehingga kode terpendek menang.


Apa yang dimaksud dengan 'baru'?
Beta Decay

Jika suatu angka baru, itu berarti ia belum berurutan. Baru sadar saya telah salah mengetik urutan, beri saya min untuk memperbaikinya.
James Williams

Mengoreksi urutannya.
James Williams

1
Bisakah Anda menambahkan nilai pertama dari urutan?
haskeller bangga

Menambahkan beberapa angka pertama! (Dan tautan ke halaman OEIS-nya)
James Williams

Jawaban:


9

CJam, 34 33 byte

0ali{_W=_I-__0<4$@#)|@I+@?+}fI1>`

Cobalah online.

Contoh dijalankan

$ cjam <(echo '0ali{_W=_I-__0<4$@#)|@I+@?+}fI1>`') <<< 33
[0 1 3 6 2 7 13 20 12 21 11 22 10 23 9 24 8 25 43 62 42 63 41 18 42 17 43 16 44 15 45 14 46]

Bagaimana itu bekerja

0ali                               " Push S := [ 0 ] and read an integer N from STDIN.    ";
    {                      }fI     " For each I in [ 0 ... (N - 1) ]:                     ";
     _W=                           "   X := S[-1].                                        ";
        _I-                        "   Y := X - I                                         ";
            _0<                    "   A := (Y < 0)                                       ";
           _   4$@#)               "   B := (Y ∊ S)                                       ";
                     @I+           "   Z := X + I                                         ";
                    |   @?         "   C := (A || B) ? Z : Y                              ";
                          +        "   S += [C]                                           ";
                              1>`  " Push str(S[1:]).                                     ";

Perubahan apa yang Anda lakukan?
Soham Chowdhury

Pendekatan pertama saya menambahkan angka negatif ke urutan, jadi saya tidak perlu secara eksplisit memeriksa apakah A(i) - i > 0. Namun, saya tidak menambahkan angka yang cukup untuk nilai kecil n. Sekarang, saya hanya melakukan persis apa yang dikatakan spec.
Dennis

33 vs 45. Begitu dekat dan sejauh ini. :)
Ingo Bürk

Wow, komentar tanpa e#di Cjam ... ceri yang enak.
Chromium

8

Haskell, 74

l=0:0#1
a§v|a<0||a`elem`r v=v|1<2=0-v
a#b=a+(a-bb:l!!b#(b+1)
r=(`take`l)

Contoh penggunaan:

λ> r 20
[0,1,3,6,2,7,13,20,12,21,11,22,10,23,9,24,8,25,43,62]

6

Ruby, 71 70 byte

f=->n{a=[0];(n-1).times{|i|a+=[[b=a[-1]-i-1]-a!=[]&&b>0?b:b+2*i+2]};a}

Implementasi definisi "kata demi kata" yang sangat.


5

Python 2, 78 75 73 69 Bytes

Kudos to xnor and flornquake
Now hampir 10 byte lebih pendek dari jawaban awal

m=p,=0,
exec"p+=1;k=m[-1]-p;m+=k+2*p*(k*(k>0)in m),;"*input()
print m

Anda dapat mempersingkat [k,k+2*p][bool]menjadi k+2*p*(bool).
xnor

@ xnatau Terima kasih, menyimpan 3 Bytes.
Markuz

Juga, k in m or k<0dapat k*(k>=0)in mkarena jika k<0, produk 0, yang ada di m.
xnor

@xnor Brilliant! Terima kasih lagi
Markuz

Anda bisa menulis -1alih-alih p-1. Sunting: Anda juga dapat membuat mtuple dan menulis m=0,dan m+=k+2*p*(k*(k>0)in m),.
flornquake

4

Golfscript (41 45 )

Cobalah online di sini :

(,1,\{:~1$=~)-:^1<\.^?)!!@|^\{~)2*+}*+}/

Penjelasan

Ini untuk solusi 45 byte asli, tetapi masih hampir sama:

(,              # push array [0 .. n-1]
[0]\            # push sequence elements as [0] and reverse stack
{               # foreach element in [0 .. n-1] do:
  :m;           # store current element in m and discard
  .m=           # get the previous sequence element
  m)-:^         # subtract the current index from it and store in ^
  0>            # is that number greater than 0?
  \.^?)!        # is that number new to our sequence?
  @&            # logically and both checks
  {^}           # if true, push ^
  {^m)2*+}      # otherwise, add the index twice and push
  if
  +             # add new element to our sequence
}/
`               # make output pretty

Sunting # 1: Terima kasih kepada Dennis untuk mencukur 4 byte.


4

dc , 46 byte

sn[z+z+d0r:a]sF0[pz-d1>Fd;a0<Fddd:azln!<M]dsMx

Cobalah online!

Program ini mengambil input dari tumpukan kosong dan output ke stdout (dibatasi baris baru).

Saya sangat bangga dengan yang satu ini - mengalahkan semua yang bukan bahasa golf khusus, dan menampilkan tiga trik golf dc favorit saya:

  • Ukuran tumpukan digunakan sebagai variabel indeks
  • Refactoring "jika A maka B lain C" menjadi "tanpa syarat C, dan jika A maka D" di mana C dan D bergabung untuk membuat B
  • fitur array akses acak yang jarang digunakan untuk memecahkan kendala keunikan

Penjelasan

sn             Stores the input in register n
[z+z+0r:a]sF   Defines the macro F, which: 
    z+z+         adds twice the stack size/index variable
    0r:a         resets the "uniqueness" flag to 0 in the array a
               In context, F is the "D" in my description above, 
               changing A(z-1)-z to A(z-1)+z
0              The main loop starts with the previous sequence member on top of 
               the stack and total stack depth equal to the next index. 
               Pushing a zero accomplishes both of these things.
[              Start of the main loop M
  p               Print the previous sequence member, with newline (no pop)
  z-             Calculate A(z-1)-z
  d1>F           If that's nonpositive, (F)ix it to be A(z-1)+z
  d;a            a is my array of flags to see if we've hit this value before
  0<F            If we have, (F)ix it! (nonzero = flag, since ;a is zero by
                 default, and also zero if we just (F)ixed and therefore 
                 don't care about uniqueness right now)
  ddd            Make one copy to keep and two to eat
  :a             Flag this entry as "used" in the uniqueness array a
  zln!<M         If our "index variable" is n or less, repeat!
]dsMx          End of main loop - store it and execute

itu liar, saya tidak tahu dc bahkan ada
don bright

3

JavaScript - 81 80 79 70

Kudos to edc65 untuk membantu saya menghemat 9 byte

f=n=>{for(a=[x=i=0];++i<n;)a[i]=x+=x>i&a.indexOf(x-i)<0?-i:i;return a}

-9: g = n => {for (a = [x = i = 0]; ++ i <n;) a [i] = x + = x> i & a.indexOf (xi) <0? -I: i ; return a}
edc65

@ edc65 Grazie mille :)
William Barbosa

3

JavaScript, ES6, 74 69 karakter

Jalankan kode di bawah ini di Konsol Web Firefox terbaru.

G=n=>(i=>{for(r=[t=0];++i<n;)r[i]=t+=i>t|~r.indexOf(t-i)?i:-i})(0)||r

Akan mencoba golf lebih banyak nanti.

Contoh penggunaan:

G(11) -> 0,1,3,6,2,7,13,20,12,21,11

3

MATLAB, 83 78 Bytes

Simpan di bawah ini sebagai f.m(73 Bytes)

A=0;for i=1:n-1 b=A(i)-i;A(i+1)=b+2*i;if b>0&&~any(A==b) A(i+1)=b;end;end

Jalankan dari jendela perintah (5 byte)

n=9;f

Jika hal di atas tidak sah, maka dibutuhkan 90 byte.

function A=f(n) 
A=0;for i=1:n-1 b=A(i)-i;A(i+1)=b+2*i;if b>0&&~any(A==b) A(i+1)=b;end;end

3

R: 96 karakter

Golf:

A=function(s,n,m,i){if(m==n){return(s)}else{t=i-m;if(t%in%s||t<0){t=i+m};s=c(s,t);A(s,n,m+1,t)}}

Tidak Terkumpul:

A = function(s,n,m,i) {
    if(m==n){return(s)}
    else{
        t=i-m
        if(t%in%s||t<0){t=i+m}
        s=c(s,t)
        A(s,n,m+1,t)
    }
}

Contoh Run:

> An(0,34,1)
[1]   0   1   3   6   2   7  13  20  12  21  11  22  10  23   9  24   8
[18]  25  43  62  42  63  41  18  42  17  43  16  44  15  45  14  46  79


3

Perl 6 , 62 57 byte

{(0, {$ - @ + @ * 2 * ($ !> @ || $ - @ ∈ @ ) diberikan @ [* -1]} ... *) [^ $ ]}

{(0,{($!=@_[*-1])+@_-@_*2*($!>@_&&$!-@_∉@_)}...*)[^$_]}

-5 byte terima kasih kepada Jo King

Cobalah online!


itu luar biasa ... yang terlihat seperti kucing saya berjalan di atas keyboard saya.
don cerah

3

05AB1E , 19 byte

¾ˆG¯¤N-DŠD0›*åN·*+ˆ

Cobalah online!

Penjelasan

¾ˆ                    # Initialize the global list with 0
  G                   # for N in [1, input-1] do:
   ¯                  # push the global list
    ¤N-               # subtract N from the last item in the list
       D              # duplicate
        Š             # move the copy down 2 spots on the stack
         D            # duplicate again
          0›          # check if it is positive
            *         # multiply, turning negative results to zero
             å        # is the result already present in the list?
              N·*     # multiply by N*2
                 +    # add to the result
                  ˆ   # add this to the list

Bagaimana cara kerjanya?
lirtosiast

@ lirtosiast: Sudah lama sejak saya melakukan tantangan ini, jadi ini adalah penjelasan terbaik yang bisa saya lakukan dalam waktu singkat. Semoga cukup.
Emigna

3

K (oK) , 53 byte

Larutan:

{$[y>c:#x;o[x,(r;*|x+c)(r in x)|0>r:*|x-c;y];x]}[,0;]

Cobalah online!

Penjelasan:

Solusi rekursif.

{$[y>c:#x;o[x,(r;*|x+c)(r in x)|0>r:*|x-c;y];x]}[,0;] / the solution
{                                              }[,0;] / lambda with first arg set as list containing 0
 $[      ;                                  ; ]       / if[condition;true;false]
       #x                                             / length of x
     c:                                               / save as c
   y>                                                 / y greater than? (ie have we produced enough results?)
                                             x        / return x if we are done
          o[                             ;y]          / recurse with new x and existing y
                                      x-c             / subtract c from x
                                    *|                / reverse first, aka last
                                  r:                  / save result as r
                                0>                    / 0 greater than?
                               |                      / or
                       (      )                       / do together
                        r in x                        / r in x?
              ( ;     )                               / use result to index into this 2-item list
                   x+c                                / add c to x
                 *|                                   / reverse first, aka last 
               r                                      / result
            x,                                        / append to x

2

Jawa, 144

int[]f(int n){int[]a=new int[n];a[0]=0;int i,j,k,m;for(i=0;i<n-1;){k=a[i++]-i;m=0;for(j=0;j<i;)if(k==a[j++])m=1;a[i]=m<1&k>0?k:k+2*i;}return a;}

2

Lua - 141 135 139 135

function s(n)a,b={1},{[0]=0}for i=1,n do k=b[i-1]-i c=k+i+i if(k>0)and(a[k]==nil)then b[i],a[k]=k,1 else b[i],a[c]=c,1 end end return b end

versi yang dapat dibaca:

function s(n)
a,b={1},{[0]=0}
for i=1,n do 
   k=b[i-1]-i 
   c=k+i+i
   if (k>0) and (a[k]==nil) then 
      b[i],a[k]=k,1 
   else 
      b[i],a[c]=c,1
   end 
end 
return b 
end

Saya menggunakan 2 tabel, yang pertama disebut a dan itu dibangun sehingga [i] = 1 iff saya sudah muncul dalam urutan, nil sebaliknya, sedangkan tabel kedua benar-benar memegang urutan


Namun, urutan Anda harus dimulai dengan 0
William Barbosa

1
Anda benar, saya tidak melihat pertanyaan dengan sangat hati-hati dan menganggap itu memiliki definisi yang sama di mathworld (dimulai dengan 1), saya pikir itu tidak akan memerlukan biaya karakter lagi, saya akan menguji dan memperbaikinya nanti, Saya menulis dari ponsel saya sekarang!

2

Python, 73

def f(x,t=0):
 if x:t=f(x-1);t+=2*x*(t*(t>0)in map(f,range(x)))
 return t

Sunting 1: Berkat tips @ xnor tentang jawaban Python lainnya! (Saya baru menyadari bahwa keduanya terlihat sangat mirip.)

Sunting 2: Sekali lagi terima kasih, @xnor.


Ini memberikan loop tak terbatas. Anda memerlukan semacam aliran kontrol agar f(x)tidak selalu langsung menelepon f(x-1).
xnor

@ xnatau memperbaiki kode.
Soham Chowdhury

1
Ini sepertinya mengembalikan suku ke-n, bukan suku ke-n pertama.
Dennis

Beberapa minor save: t=0bisa digunakan sebagai parameter opsional f, dan t=t+bisa juga t+=.
xnor

2

Groovy: 122 118 111 karakter

Golf:

m=args[0] as int
a=[0]
(1..m-1).each{n->b=a[n-1];x=b-n;(x>0&!(x in a))?a[n]=x:(a[n]=b+n)}
a.each{print "$it "}

Tidak Terkumpul:

m = args[0] as int
a = [0]
(1..m-1).each { n->
    b = a[n-1]
    x = b-n
    ( x>0 & !(x in a) ) ? a[n] = x : (a[n] = b+n) 
}
a.each{print "$it "}

Contoh Run:

bash$ groovy Rec.groovy 14
0 1 3 6 2 7 13 20 12 21 11 22 10 23

2

Clojure: 174 karakter

Golf:

(defn f[m a](let[n(count a)b(last a)x(- b n)y(if(and(> x 0)(not(.contains a x)))x(+ b n))](if(= m n)a(f m(conj a y)))))(println(f(read-string(first *command-line-args*))[0]))

Tidak Terkumpul:

(defn f[m a]
  (let [n (count a) 
        b (last a) 
        x (- b n) 
        y (if (and (> x 0) (not (.contains a x))) x (+ b n)) ]
    (if (= m n) a (f m (conj a y))) ) )

(println (f (read-string (first *command-line-args*)) [0]) )

Contoh dijalankan:

bash$ java -jar clojure-1.6.0.jar rec.clj 14 
[0 1 3 6 2 7 13 20 12 21 11 22 10 23]

1
Saya menyarankan Anda untuk tidak membaca dari STDIN tetapi hanya mengambil argumen integer ke fungsi :) Juga Anda tidak mendapatkan manfaat dari mendefinisikan ypada letformulir, Anda dapat menggunakan ekspresi secara langsung di mana nilai dibutuhkan.
NikoNyrh

2

Mathcad, 54 "byte"

masukkan deskripsi gambar di sini


Dari perspektif pengguna, Mathcad secara efektif merupakan papan tulis 2D, dengan ekspresi dievaluasi dari kiri ke kanan, atas-ke-bawah. Mathcad tidak mendukung input "teks" konvensional, tetapi malah memanfaatkan kombinasi teks dan item tombol / toolbar / menu khusus untuk menyisipkan ekspresi, teks, plot, atau komponen. Misalnya, ketik ":" untuk memasukkan operator definisi (ditampilkan di layar sebagai ": =") atau "ctl-shft- #" untuk memasukkan operator loop (termasuk placeholder untuk variabel iterasi, nilai iterasi, dan satu badan ekspresi). Apa yang Anda lihat pada gambar di atas adalah persis apa yang muncul pada antarmuka pengguna dan sebagai "mengetik" pada.

Untuk tujuan bermain golf, hitungan "byte" adalah jumlah yang setara dengan operasi keyboard yang diperlukan untuk memasukkan ekspresi.


Itu semua baik dan bagus , tapi apa yang penekanan tombol yang sebenarnya?
Jo King


2

Stax , 19 byte

É╖C8½ΔL▄░▬L+≡ΩSa⌂¼╧

Jalankan dan debug itu

Dibongkar, tidak diserang, dan dikomentari, sepertinya ini. Itu membuat urutan sejauh ini di stack, dan mengingat A(n - 1)di register X. Indeks iterasi digunakan untuk n. Pertama kali melalui, ini 0, tetapi dalam iterasi itu menghasilkan 0 tanpa kasus khusus, jadi tidak perlu menyesuaikan untuk indeks off-by-1.

0X      push 0 to main stack and store it in X register, which will store A(n - 1)
z       push an empty array that will be used to store the sequence
,D      pop input from input stack, execute the rest of the program that many times
  xi-Y  push (x-register - iteration-index) and store it in the Y register
        this is (A(n - 1) - n)
  0>    test if (A(n - 1) - n) is greater than 0 (a)
  ny#   count number of times (A(n - 1) - n) occurs in the sequence so far (b)
  >     test if (a) > (b)
    y   (A(n - 1) - n)
    xi+ A(n - 1) + n
  ?     if/else;  choose between the two values based on the condition
  X     store the result in the X register
  Q     print without popping
  +     append to sequence array

Jalankan dan debug yang ini


menarik. bagaimana cara kerjanya?
don cerah

1
@donbright: Menambahkan beberapa penjelasan dan penjelasan.
Rekursif


2

Pyth , 24 byte

tu+G-eG_W|g0J-eGH}JGHQ]0

Cobalah online!

tu+G-eG_W|g0J-eGH}JGHQ]0   Implicit: Q=eval(input())
 u                   Q     Reduce [0-Q)...
                      ]0   ... with initial value G=[0], next value as H:
              eG             Last value of G (sequence so far)
             -  H            Take H from the above
            J                Store in J
          g0J                0 >= J
                 }JG         Is J in G?
         |                   Logical OR of two previous results
       _W           H        If the above is true, negate H, otherwise leave as positive
    -eG                      Subtract the above from last value in G
  +G                         Append the above to G
                           The result of the reduction is the sequence with an extra leading 0
t                          Remove a leading 0, implicit print

1

Powershell (103)

$n=Read-Host;$a=@(0);$n-=1;1..$n|%{$x=$a[-1]-$_;if($x-gt0-and!($a-like$x)){$a+=$x}else{$a+=$x+2*$_}};$a

Implementasi 'kata demi kata' lain di sini juga. Juga bisa dibaca untuk PowerShell.

Urutan disimpan dalam array $ a, dan dicetak satu istilah per baris.

Untuk $ n = 20 jika kita menjalankan pernyataan yang $a-join","kita dapatkan

0,1,3,6,2,7,13,20,12,21,11,22,10,23,9,24,8,25,43,62

1

C #: 140 karakter

int i,w,t,y;int[]F(int n){var r=new int[n--];for(;i<n;y=0){w=r[i++]-i;for(t=0;y<i&&t<1;)t=w==r[y++]?1:0;r[i]=w>0&&t<1?w:r[i-1]+i;}return r;}

1

C ++: 180 karakter (158 tanpa pernyataan cin dan cout)

int a[5000000][2]={0},i,k,l;a[0][0]=0;a[0][1]=1;cin>>k;for(i=1;i<=k;i++){l=a[i-1][0];if(l-i>0&&a[l-i][1]!=1){ a[i][0]=l-i;a[l-i][1]=1;}else{ a[i][0]=l+i;a[l+i][1]=1;}cout<<a[i][0]<<endl;

Selamat Datang di Programming Puzzles & Code Golf Stack Exchange! Harap edit jumlah karakter / byte solusi Anda ke dalam tajuk Anda, seperti yang ditunjukkan pada jawaban lain di sini. Selain itu, harap golf kode Anda (mis. Hapus spasi putih untuk mengurangi jumlah karakter) sebanyak mungkin. Terima kasih!
Gagang pintu

Tentu, saya akan melakukannya.
Abhay Jain

1

Mathematica - 81 byte

Fold[#~Append~(#[[-1]]+If[#[[-1]]>#2&&FreeQ[#,#[[-1]]-#2],-#2,#2])&,{0},Range@#]&

Pemakaian

Fold[#~Append~(#[[-1]]+If[#[[-1]]>#2&&FreeQ[#,#[[-1]]-#2],-#2,#2])&,{0},Range@#]&[30]
{0,1,3,6,2,7,13,20,12,21,11,22,10,23,9,24,8,25,43,62,42,63,41,18,42,17,43,16,44,15,45}

1

PHP , 89 byte

$f=function($n){for(;$i<$n;$s[$r[$i++]=$p=$m]=1)if($s[$m=$p-$i]|0>$m)$m=$p+$i;return$r;};

Cobalah online!

Tidak Terkumpul:

$f = function ($n) {
    for (; $i < $n; $s[$r[$i++] = $p = $m] = 1) {
        if ($s[$m = $p - $i] | 0 > $m) {
            $m = $p + $i;
        }
    }

    return $r;
};
  • $r untuk hasil saya
  • $s untuk melacak dilihat
  • $p nilai sebelumnya
  • $m nilai m ext

1

LISP umum (139 byte)

(defun r(n)(do*(s(i 0(1+ i))(a 0(car s))(b 0(- a i)))((> i n)(nreverse s))(push(cond((= 0 i)0)((and(> b 0)(not(find b s)))b)(t(+ a i)))s)))

Tidak Terkumpul:

(defun recaman (n)
  (do*
   (series               ; starts as empty list
    (i 0 (1+ i))         ; index variable
    (last 0 (car s))     ; last number in the series
    (low 0 (- last i)))

   ((> i n)              ; exit condition
    (nreverse series))   ; return value

    (push                ; loop body
     (cond
       ((= 0 i) 0)       ; first pass
       ((and
         (> low 0) (not (find low s)))
        low)
       (t (+ last i)))
     series)))
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.