Genera la secuencia de Recamán


20

La secuencia de Recamán ( A005132 ) es una secuencia matemática, definida como tal:

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

Una bonita versión LaTex de lo anterior (podría ser más legible):

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

Los primeros términos son 0, 1, 3, 6, 2, 7, 13, 20, 12, 21, 11

Para aclarar, is newsignifica si el número ya está en la secuencia.

Dado un número entero n, a través del argumento de función o STDIN, devuelve los primeros ntérminos de la secuencia Recamán.


Este es un desafío de código de golf, por lo que gana el código más corto.


¿Qué significa "es nuevo"?
Beta Decay

Si un número es nuevo, significa que aún no está en la secuencia. Me acabo de dar cuenta de que he escrito mal la secuencia, dame un minuto para corregirla.
James Williams

Corregido la secuencia.
James Williams

1
¿Puedes agregar los primeros valores de la secuencia?
orgulloso Haskeller

¡Se agregaron los primeros números! (Y un enlace a su página OEIS)
James Williams

Respuestas:


9

CJam, 34 33 bytes

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

Pruébalo en línea.

Ejecución de ejemplo

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

Cómo funciona

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

¿Qué cambio hiciste?
Soham Chowdhury

Mi primer enfoque antepuso números negativos a la secuencia, por lo que no tuve que verificar explícitamente si A(i) - i > 0. Sin embargo, no antepuse suficientes números para valores pequeños de n. Ahora, solo hago exactamente lo que dice la especificación.
Dennis

33 vs. 45. Tan cerca y tan lejos. :)
Ingo Bürk

Wow, comentar sin e#en Cjam ... sabrosa cereza.
Cromo

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)

Ejemplo de uso:

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

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

Una implementación muy "palabra por palabra" de la definición.


5

Python 2, 78 75 73 69 Bytes

Felicitaciones a xnor y flornquake
Ahora casi 10 bytes más cortos que la respuesta inicial

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

Puedes acortar [k,k+2*p][bool]a k+2*p*(bool).
xnor

@xnor Gracias, guardado 3 Bytes.
Markuz

Además, k in m or k<0puede ser k*(k>=0)in mporque si k<0, el producto es 0, que está en m.
xnor

@xnor brillante! Gracias de nuevo
Markuz

Puedes escribir en -1lugar de p-1. Editar: también puede hacer muna tupla y escribir m=0,y m+=k+2*p*(k*(k>0)in m),.
flornquake

4

Golfscript (41 45 )

Pruébelo en línea aquí :

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

Explicación

Esto es para la solución original de 45 bytes, pero sigue siendo más o menos lo mismo:

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

Edición n. ° 1: Gracias a Dennis por reducir 4 bytes.


4

cc , 46 bytes

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

Pruébalo en línea!

Este programa toma la entrada de una pila vacía y la envía a stdout (nueva línea delimitada).

Estoy realmente orgulloso de este: está superando todo lo que no es un lenguaje de golf dedicado, y muestra tres de mis trucos de golf de CC favoritos:

  • Tamaño de pila utilizado como variable de índice
  • Refactorizando "si A entonces B más C" en "incondicionalmente C, y si A entonces D" donde C y D se combinan para formar B
  • la característica de matriz de acceso aleatorio poco utilizada para resolver una restricción de unicidad

Explicación

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

eso es descabellado, no tenía idea de que dc existía
don bright

3

JavaScript - 81 80 79 70

Felicitaciones a edc65 por ayudarme a ahorrar 9 bytes

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 => {para (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 caracteres

Ejecute el siguiente código en la última consola web de Firefox.

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

Trataré de jugarlo más tarde.

Ejemplo de uso:

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

3

MATLAB, 83 78 Bytes

Guarde lo siguiente como 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

Ejecutar desde la ventana de comandos (5 bytes)

n=9;f

Si lo anterior no es legal, entonces requiere 90 bytes.

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 caracteres

Golfizado:

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

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

Ejecución de muestra:

> 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 * ($ !> @ || $ - @ ∈ @ ) dado @ [* -1]} ... *) [^ $ ]}

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

-5 bytes gracias a Jo King

Pruébalo en línea!


eso es increíble ... literalmente parece que mi gato cruzó mi teclado.
Don brillante

3

05AB1E , 19 bytes

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

Pruébalo en línea!

Explicación

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

¿Como funciona esto?
lirtosiast

@lirtosiast: Ha pasado un tiempo desde que hice este desafío, así que esta es la mejor explicación que puedo hacer a corto plazo. Espero que sea suficiente.
Emigna

3

K (oK) , 53 bytes

Solución:

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

Pruébalo en línea!

Explicación:

Solución recursiva.

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

versión legible:

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

Yo uso las tablas 2, la primera se llama una y está construido de manera que a [i] = 1 si y sólo si i ya ha aparecido en la secuencia, nil de lo contrario, mientras que la segunda tabla en realidad tiene la secuencia


Sin embargo, su secuencia debería comenzar con 0
William Barbosa

1
Tienes razón, no miré la pregunta con mucho cuidado y asumí que tenía la misma definición en mathworld (comenzando con 1), creo que eso no costará más caracteres, lo probaré y corregiré más tarde, Estoy escribiendo desde mi teléfono ahora!

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

Edición 1: ¡Gracias a los consejos de @ xnor sobre la otra respuesta de Python! (Me acabo de dar cuenta de que ambos se ven muy similares).

Edición 2: Gracias de nuevo, @xnor.


Esto da un bucle infinito. Necesita algún tipo de flujo de control para que f(x)no siempre llame de inmediato f(x-1).
xnor

@xnor arregló el código.
Soham Chowdhury

1
Esto parece devolver el enésimo término, no los primeros n términos.
Dennis

Algunos guardados menores: t=0pueden ir como un parámetro opcional para f, y t=t+pueden ser t+=.
xnor

2

Groovy: 122 118 111 caracteres

Golfizado:

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

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

Ejecución de muestra:

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

2

Clojure: 174 caracteres

Golfizado:

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

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

Ejecución de muestra:

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
Le sugiero que no lea desde STDIN, sino que simplemente tome un argumento entero para la función :) Además, no obtiene ningún beneficio al definir yen el letformulario, puede usar la expresión directamente donde se necesita el valor.
NikoNyrh

2

Mathcad, 54 "bytes"

ingrese la descripción de la imagen aquí


Desde la perspectiva del usuario, Mathcad es efectivamente una pizarra en 2D, con expresiones evaluadas de izquierda a derecha, de arriba a abajo. Mathcad no admite una entrada de "texto" convencional, sino que utiliza una combinación de texto y teclas especiales / barra de herramientas / elementos de menú para insertar una expresión, texto, diagrama o componente. Por ejemplo, escriba ":" para ingresar el operador de definición (que se muestra en la pantalla como ": =") o "ctl-shft- #" para ingresar el operador de bucle for (incluidos los marcadores de posición para la variable de iteración, los valores de iteración y un cuerpo expresión). Lo que ves en la imagen de arriba es exactamente lo que aparece en la interfaz de usuario y "tipeado".

Para fines de golf, el conteo de "bytes" es el número equivalente de operaciones de teclado requeridas para ingresar una expresión.


Eso está muy bien , pero ¿cuáles son las pulsaciones de teclas reales?
Jo King


2

Stax , 19 bytes

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

Ejecutar y depurarlo

Desempaquetado, sin golf y comentado, se ve así. Mantiene la secuencia hasta el momento en la pila, y recuerda A(n - 1)en el registro X. El índice de iteración se utiliza para n. La primera vez, es 0, pero en esa iteración genera el 0 sin ningún caso especial, por lo que no es necesario ajustar el índice 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

Ejecute y depure este


interesante. ¿como funciona esto?
Don brillante

1
@donbright: se agregaron algunas anotaciones y explicaciones.
recursivo el


2

Pyth , 24 bytes

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

Pruébalo en línea!

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

Otra implementación 'palabra por palabra' aquí también. Sorprendentemente legible para PowerShell, también.

La secuencia se almacena en la matriz $ a, y se imprime un término por línea.

Por $ n = 20 si ejecutamos la declaración $a-join","obtenemos

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

1

C #: 140 caracteres

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 caracteres (158 sin declaraciones cin y 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;

¡Bienvenido a Programming Puzzles & Code Golf Stack Exchange! Edite el recuento de caracteres / bytes de su solución en su encabezado, como se muestra en las otras respuestas aquí. Además, haga golf en su código (por ejemplo, elimine espacios en blanco para reducir el recuento de caracteres) tanto como sea posible. ¡Gracias!
Pomo de la puerta

Claro que lo haré.
Abhay Jain

1

Mathematica - 81 bytes

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

Uso

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

Pruébalo en línea!

Sin golf:

$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 por mi resultado
  • $s para rastrear senos
  • $p valor anterior
  • $m m ext valor

1

LISP común (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)))

Sin golf:

(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)))
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.