生成雷卡曼的序列


20

Recamán的序列(A005132)是一个数学序列,定义如下:

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

上面漂亮的LaTex版本(可能更易读):

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

前几个词是 0, 1, 3, 6, 2, 7, 13, 20, 12, 21, 11

要澄清,is new是指该数字是否已在序列中。

给定一个整数n,通过函数参数或STDIN返回nRecamán序列的第一项。


这是一个代码挑战,所以最短的代码胜出。


“新”是什么意思?
Beta Decay

如果一个数字是新的,则表示它尚未在序列中。刚意识到我输入了错误的序列,请给我一点时间来纠正它。
James Williams

更正了顺序。
James Williams

1
您可以添加序列的第一个值吗?
骄傲的haskeller 2014年

添加了前几个数字!(及其OEIS页面的链接)
James Williams

Answers:


9

CJam,34 33字节

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

在线尝试。

运行示例

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

怎么运行的

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

您做了什么改变?
Soham Chowdhury 2014年

我的第一种方法是在序列前加上负数,因此不必显式检查是否为A(i) - i > 0。但是,我没有为的小数值添加足够的数字n。现在,我完全按照规格说明进行操作。
丹尼斯2014年

33比45。如此接近,但至今。:)
IngoBürk2014年

哇,没有e#Cjam的评论...好吃的樱桃。
Chromium

8

哈斯克尔,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)

用法示例:

λ> 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字节

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

该定义的“逐字逐句”实现。


5

Python 2,78 75 73 69字节

xnor和flornquake的荣誉
现在比初始答案短了近10个字节

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

您可以缩短[k,k+2*p][bool]k+2*p*(bool)
xnor 2014年

@xnor谢谢,保存了3个字节。
Markuz 2014年

另外,k in m or k<0可以是k*(k>=0)in m因为,如果k<0产品是0,则位于中m
xnor 2014年

@xnor很棒!再次感谢
Markuz 2014年

您可以写-1而不是p-1。编辑:您还可以制作m一个元组并编写m=0,m+=k+2*p*(k*(k>0)in m),
flornquake 2014年

4

Golfscript(41 45

在这里在线尝试:

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

说明

这是原始的45字节解决方案,但仍几乎相同:

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

编辑1:感谢Dennis削减了4个字节。


4

直流电,46字节

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

在线尝试!

该程序从原本为空的堆栈中获取输入,然后输出到stdout(以换行符分隔)。

我真的为此感到自豪-它击败了所有不是专门的高尔夫语言,并且展示了我最喜欢的三个DC高尔夫技巧:

  • 堆栈大小用作索引变量
  • 将“如果A则B,否则B,C”重构为“无条件C,如果A则D,”,其中C和D合并为B
  • 很少使用的随机访问数组功能来解决唯一性约束

说明

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

那太疯狂了,我什
唐·

3

JavaScript- 81 80 79 70

edc65的帮助我节省了9个字节

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 2014年

@ edc65 Grazie mille :)
William Barbosa

3

JavaScript中,ES6,74 69个字符

在最新的Firefox Web控制台中运行以下代码。

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

稍后将尝试打高尔夫球。

用法示例:

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

3

MATLAB 83 78字节

将以下内容另存为f.m(73字节)

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

从命令窗口运行(5个字节)

n=9;f

如果以上内容不合法,则需要90个字节。

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个字符

打高尔夫球:

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

取消高尔夫:

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

样品运行:

> 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 bytes

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

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

-5 bytes thanks to Jo King

Try it online!


that's amazing... that literally looks like my cat walked across my keyboard.
don bright

3

05AB1E, 19 bytes

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

Try it online!

Explanation

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

How does this work?
lirtosiast

@lirtosiast: Been a while since I did this challenge, so this is the best explanation I can do on short notice. Hope it's enough.
Emigna

3

K (oK), 53 bytes

Solution:

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

Try it online!

Explanation:

Recursive solution.

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

readable version:

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

I use 2 tables, the first one is called a and it is built so that a[i]=1 iff i has already appeared in the sequence, nil otherwise, while the second table actually holds the sequence


Your sequence should start with 0, though
William Barbosa

1
You're right, I didn't look at the question very carefully and assumed it had the same definition at mathworld (starting with 1), I think that won't cost any more character, I'll test and correct it later, I'm writing from my phone now!

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

Edit 1: Thanks to @xnor's tips on the other Python answer! (I just realised that both look very similar.)

Edit 2: Thanks again, @xnor.


This gives an infinite loop. You need some sort of control flow so that f(x) doesn't always immediately call f(x-1).
xnor

@xnor fixed the code.
Soham Chowdhury

1
This seems to return the nth term, not the first n terms.
Dennis

Some minor saves: t=0 can go as an optional parameter to f, and t=t+ can be t+=.
xnor

2

Groovy : 122 118 111 chars

Golfed:

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

Ungolfed:

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

Sample Run:

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

2

Clojure : 174 chars

Golfed:

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

Ungolfed:

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

Sample run:

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
I suggest you not to read from STDIN but instead just take an integer argument to the function :) Also you don't get any benefits from defining y on the let form, you can use the expression directly where the value is needed.
NikoNyrh

2

Mathcad, 54 "bytes"

enter image description here


From user perspective, Mathcad is effectively a 2D whiteboard, with expressions evaluated from left-to-right,top-to-bottom. Mathcad does not support a conventional "text" input, but instead makes use of a combination of text and special keys / toolbar / menu items to insert an expression, text, plot or component. For example, type ":" to enter the definition operator (shown on screen as ":=") or "ctl-shft-#" to enter the for loop operator (inclusive of placeholders for the iteration variable, iteration values and one body expression). What you see in the image above is exactly what appears on the user interface and as "typed" in.

For golfing purposes, the "byte" count is the equivalent number of keyboard operations required to enter an expression.


That's all well and good, but what are the actual keystrokes?
Jo King


2

Stax, 19 bytes

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

Run and debug it

Unpacked, ungolfed, and commented, it looks like this. It keeps the sequence so far on the stack, and remembers A(n - 1) in the X register. The iteration index is used for n. The first time through, it's 0, but in that iteration it generates the 0 without any special cases, so there's no need to adjust for the off-by-1 index.

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

Run and debug this one


interesting. how does this work?
don bright

1
@donbright: Added some annotations and explanation.
recursive


2

Pyth, 24 bytes

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

Try it 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

Another 'word-for-word' implementation down here as well. Surprisingly readable for PowerShell, too.

Sequence is stored in the array $a, and printed out one term per line.

For $n=20 if we run the statement $a-join"," we get

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

1

C#: 140 characters

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 characters (158 without cin and cout statements)

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;

Welcome to Programming Puzzles & Code Golf Stack Exchange! Please edit the character/byte count of your solution into your header, as shown in the other answers here. Also, please golf your code (ex. remove whitespace to reduce the character count) as much as possible. Thanks!
Doorknob

Sure thing, I'll do that.
Abhay Jain

1

Mathematica - 81 bytes

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

Usage

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 bytes

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

Try it online!

Ungolfed:

$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 for my result
  • $s for tracking seens
  • $p previous value
  • $m mext value

1

Common LISP (139 bytes)

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

Ungolfed:

(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)))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.