Tạo chuỗi của Recamán


20

Trình tự của Recamán ( A005132 ) là một trình tự toán học, được định nghĩa như sau:

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

Một phiên bản LaTex đẹp ở trên (có thể dễ đọc hơn):

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

Một vài điều khoản đầu tiên là 0, 1, 3, 6, 2, 7, 13, 20, 12, 21, 11

Để làm rõ, is newcó nghĩa là số đã có trong chuỗi.

Cho một số nguyên n, thông qua đối số hàm hoặc STDIN, trả về các nđiều khoản đầu tiên của chuỗi Recamán.


Đây là một thử thách chơi gôn, vì vậy mã ngắn nhất sẽ thắng.


"Cái mới" nghĩa là gì?
Beta Decay

Nếu một số là mới, có nghĩa là nó chưa có trong chuỗi. Chỉ cần nhận ra tôi đã gõ sai trình tự, cho tôi một phút để sửa nó.
James Williams

Sửa lỗi trình tự.
James Williams

1
Bạn có thể thêm các giá trị đầu tiên của chuỗi?
tự hào

Đã thêm một vài số đầu tiên! (Và một liên kết đến trang OEIS của nó)
James Williams

Câu trả lời:


9

CJam, 34 33 byte

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

Hãy thử trực tuyến.

Chạy ví dụ

$ 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]

Làm thế nào nó hoạt động

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:]).                                     ";

Bạn đã thay đổi gì?
Soham Chowdhury

Cách tiếp cận đầu tiên của tôi đã chuẩn bị các số âm cho chuỗi, vì vậy tôi không phải kiểm tra rõ ràng nếu A(i) - i > 0. Tuy nhiên, tôi đã không trả trước đủ số cho các giá trị nhỏ n. Bây giờ, tôi chỉ làm chính xác những gì spec nói.
Dennis

33 so với 45. Rất gần và cho đến nay. :)
Ingo Bürk

Wow, bình luận mà không có e#trong Cjam ... anh đào ngon.
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)

Ví dụ sử dụng:

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

Việc thực hiện định nghĩa "từ ngữ cho từ".


5

Python 2, 78 75 73 69 byte

Kudos to xnor và flornquake
Bây giờ ngắn hơn gần 10 byte so với câu trả lời ban đầu

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

Bạn có thể rút ngắn [k,k+2*p][bool]để k+2*p*(bool).
xnor

@xnor Cảm ơn, đã lưu 3 Byte.
Markuz

Ngoài ra, k in m or k<0có thể k*(k>=0)in mkể từ khi k<0, sản phẩm là 0, đó là trong m.
xnor

@xnor Rực rỡ! Cảm ơn một lần nữa
Markuz

Bạn có thể viết -1thay vì p-1. Chỉnh sửa: Bạn cũng có thể tạo mmột tuple và viết m=0,m+=k+2*p*(k*(k>0)in m),.
flornquake

4

Golf (41 45 )

Dùng thử trực tuyến tại đây :

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

Giải trình

Đây là giải pháp 45 byte ban đầu, nhưng nó vẫn khá giống nhau:

(,              # 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

Chỉnh sửa # 1: Cảm ơn Dennis vì đã loại bỏ 4 byte.


4

dc , 46 byte

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

Hãy thử trực tuyến!

Chương trình này nhận đầu vào từ một ngăn xếp trống khác và đầu ra thành thiết bị xuất chuẩn (phân cách dòng mới).

Tôi thực sự tự hào về điều này - nó đánh bại mọi thứ không phải là ngôn ngữ chơi gôn chuyên dụng và thể hiện ba trong số các thủ thuật chơi golf yêu thích của tôi:

  • Kích thước ngăn xếp được sử dụng như một biến chỉ số
  • Tái cấu trúc "nếu A thì B khác C" thành "vô điều kiện C và nếu A thì D" trong đó C và D kết hợp để tạo B
  • tính năng mảng truy cập ngẫu nhiên ít được sử dụng để giải quyết một ràng buộc duy nhất

Giải trình

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

Điều đó thật hoang dã, tôi không có ý tưởng nào thậm chí còn tồn tại
đừng sáng

3

JavaScript - 81 80 79 70

Kudos đến edc65 đã giúp tôi tiết kiệm 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 ; trả lại a}
edc65

@ edc65 Grazie mille :)
William Barbosa

3

JavaScript, ES6, 74 69 ký tự

Chạy mã dưới đây trong Bảng điều khiển web mới nhất của Firefox.

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

Sẽ cố gắng để chơi golf sau này.

Ví dụ sử dụng:

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

3

MATLAB, 83 78 byte

Lưu dưới đây như f.m (73 byte)

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

Chạy từ cửa sổ lệnh (5 byte)

n=9;f

Nếu ở trên không hợp pháp, thì nó yêu cầu 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 ký tự

Chơi gôn

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

Ung dung:

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

Chạy mẫu:

> 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 * ($ !> @ || $ - @ ∈ @ ) được cung cấp @ [* -1]} ... *) [^ $ ]}

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

-5 byte nhờ Jo King

Hãy thử trực tuyến!


thật tuyệt vời ... điều đó trông giống như con mèo của tôi đi ngang qua bàn phím của tôi.
don sáng

3

05AB1E , 19 byte

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

Hãy thử trực tuyến!

Giải trình

¾ˆ                    # 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

Cái này hoạt động ra sao?
lirtosiast

@lirtosiast: Đã được một thời gian kể từ khi tôi thực hiện thử thách này, vì vậy đây là lời giải thích tốt nhất tôi có thể làm trong một thông báo ngắn. Hy vọng nó là đủ.
Emigna

3

K (oK) , 53 byte

Dung dịch:

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

Hãy thử trực tuyến!

Giải trình:

Giải pháp đệ quy.

{$[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

Java, 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

phiên bản có thể đọc được:

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

Tôi sử dụng 2 bảng, người đầu tiên được gọi là một và nó được xây dựng sao cho a [i] = 1 khi và chỉ khi tôi đã xuất hiện trong trình tự, con số không khác, trong khi bảng thứ hai thực sự nắm giữ chuỗi


Trình tự của bạn nên bắt đầu bằng 0, mặc dù vậy
William Barbosa

1
Bạn nói đúng, tôi đã không xem xét câu hỏi rất cẩn thận và cho rằng nó có cùng định nghĩa tại mathworld (bắt đầu từ 1), tôi nghĩ rằng sẽ không tốn thêm bất kỳ ký tự nào nữa, tôi sẽ kiểm tra và sửa nó sau, Tôi đang viết từ điện thoại của tôi bây giờ!

2

Con trăn, 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

Chỉnh sửa 1: Nhờ các mẹo của @ xnor về câu trả lời Python khác! (Tôi chỉ nhận ra rằng cả hai trông rất giống nhau.)

Chỉnh sửa 2: Cảm ơn một lần nữa, @xnor.


Điều này cho một vòng lặp vô hạn. Bạn cần một số luồng điều khiển để f(x)không phải lúc nào cũng gọi ngay f(x-1).
xnor

@xnor đã sửa mã.
Soham Chowdhury

1
Điều này dường như trả về thuật ngữ thứ n, không phải là điều khoản n đầu tiên.
Dennis

Một số lưu nhỏ: t=0có thể là một tham số tùy chọn ft=t+có thể t+=.
xnor

2

Groovy: 122 118 111 ký tự

Chơi gôn

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

Ung dung:

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

Chạy mẫu:

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

2

Clojure: 174 ký tự

Chơi gôn

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

Ung dung:

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

Chạy mẫu:

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
Tôi khuyên bạn không nên đọc từ STDIN mà thay vào đó chỉ cần lấy một đối số nguyên cho hàm :) Ngoài ra, bạn không nhận được bất kỳ lợi ích nào từ việc xác định ytrên letbiểu mẫu, bạn có thể sử dụng biểu thức trực tiếp khi cần giá trị.
NikoNyrh

2

Mathcad, 54 "byte"

nhập mô tả hình ảnh ở đây


Từ góc độ người dùng, Mathcad thực sự là một bảng trắng 2D, với các biểu thức được đánh giá từ trái sang phải, từ trên xuống dưới. Mathcad không hỗ trợ đầu vào "văn bản" thông thường, mà thay vào đó sử dụng kết hợp văn bản và các phím / thanh công cụ / menu đặc biệt để chèn một biểu thức, văn bản, cốt truyện hoặc thành phần. Ví dụ: nhập ":" để nhập toán tử định nghĩa (hiển thị trên màn hình là ": =") hoặc "ctl-shft- #" để nhập toán tử vòng lặp for (bao gồm các trình giữ chỗ cho biến lặp, giá trị lặp và một thân biểu hiện). Những gì bạn nhìn thấy trong hình trên chính xác là những gì xuất hiện trên giao diện người dùng và được "nhập" vào.

Đối với mục đích chơi gôn, số "byte" là số thao tác bàn phím tương đương cần có để nhập một biểu thức.


Đó là tất cả tốt và tốt , nhưng những gì các tổ hợp phím thực tế?
Jo King


2

Stax , 19 byte

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

Chạy và gỡ lỗi nó

Giải nén, không được chỉnh sửa, và nhận xét, nó trông như thế này. Nó giữ chuỗi cho đến nay trên ngăn xếp và ghi nhớ A(n - 1)trong thanh ghi X. Chỉ số lặp được sử dụng cho n. Lần đầu tiên, nó là 0, nhưng trong lần lặp đó, nó tạo ra 0 mà không có trường hợp đặc biệt nào, do đó không cần điều chỉnh cho chỉ số 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

Chạy và gỡ lỗi cái này


hấp dẫn. Cái này hoạt động ra sao?
don sáng

1
@donbright: Đã thêm một số chú thích và giải thích.
đệ quy

2

Bình thường, 31 byte

VQ=+Y?Y?|>NeYhxY-eYN+eYN-eYNZ)Y

Chào mừng đến với trang web!
Phù thủy lúa mì

Chào mừng bạn Các câu trả lời chỉ có mã không được khuyến khích vì chúng có xu hướng tự động được gắn cờ là chất lượng thấp. Thêm một lời giải thích và xem xét thêm một liên kết đến một thông dịch viên trực tuyến, như thế này: tio.run/##K6gsyfj/PyzQVjvSPtK@xs4vNTKjIlI3NdJPG4hBdJRm5P//hoYA
mbomb007

2

Bình thường , 24 byte

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

Hãy thử trực tuyến!

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

Một cách thực hiện 'từ-từ' khác cũng ở đây. Đáng ngạc nhiên là có thể đọc được cho PowerShell.

Trình tự được lưu trữ trong mảng $ a và được in ra một thuật ngữ trên mỗi dòng.

Với $ n = 20 nếu chúng ta chạy câu lệnh $a-join","chúng ta nhận được

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

1

C #: 140 ký tự

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 ký tự (158 không có câu lệnh cin và 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;

Chào mừng bạn đến với Câu đố lập trình & trao đổi mã Golf! Vui lòng chỉnh sửa số ký tự / byte của giải pháp của bạn vào tiêu đề của bạn, như thể hiện trong các câu trả lời khác ở đây. Ngoài ra, vui lòng đánh golf mã của bạn (ví dụ: xóa khoảng trắng để giảm số lượng ký tự) càng nhiều càng tốt. Cảm ơn!
Doorknob

Chắc chắn, tôi sẽ làm điều đó.
Abhay Jain

1

Toán học - 81 byte

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

Sử dụng

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

Hãy thử trực tuyến!

Ung dung:

$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 cho kết quả của tôi
  • $s để theo dõi seens
  • $p giá trị trước đây
  • $m m giá trị mở rộng

1

LISP phổ biến (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)))

Ung dung:

(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)))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.