Generiere Recamáns Sequenz


20

Recamáns Sequenz ( A005132 ) ist eine mathematische Sequenz, definiert als:

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

Eine hübsche LaTex-Version des oben genannten (möglicherweise besser lesbar):

EIN(n)={0ob n=0EIN(n-1)-nob EIN(n-1)-n is positive and not already in the sequenceA(n1)+notherwise

Die ersten Begriffe sind 0, 1, 3, 6, 2, 7, 13, 20, 12, 21, 11

Zur Verdeutlichung is newbedeutet, ob die Nummer bereits in der Reihenfolge ist.

Wenn Sie eine Ganzzahl nangeben, geben Sie über das Funktionsargument oder STDIN die ersten nTerme der Recamán-Sequenz zurück.


Dies ist eine Code-Golf-Herausforderung, also gewinnt der kürzeste Code.


Was bedeutet "ist neu"?
Beta Decay

Wenn eine Nummer neu ist, bedeutet dies, dass sie noch nicht in der Reihenfolge enthalten ist. Ich habe gerade festgestellt, dass ich die Sequenz falsch eingegeben habe. Geben Sie mir eine Minute, um sie zu korrigieren.
James Williams

Die Reihenfolge wurde korrigiert.
James Williams

1
Können Sie die ersten Werte der Sequenz hinzufügen?
stolzer Haskeller

Die ersten Zahlen hinzugefügt! (Und ein Link zu seiner OEIS-Seite)
James Williams

Antworten:


9

CJam, 34 33 Bytes

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

Probieren Sie es online aus.

Beispiellauf

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

Wie es funktioniert

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

Welche Änderung haben Sie vorgenommen?
Soham Chowdhury

Mein erster Ansatz ging der Sequenz negative Zahlen voran, sodass ich nicht explizit prüfen musste, ob A(i) - i > 0. Ich habe jedoch nicht genügend Zahlen für kleine Werte von vorangestellt n. Jetzt mache ich genau das, was die Spezifikation sagt.
Dennis

33 vs. 45. So nah und doch so fern. :)
Ingo Bürk

Wow, Kommentar ohne e#in Cjam ... leckere Kirsche.
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)

Anwendungsbeispiel:

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

Eine sehr wörtliche Umsetzung der Definition.


5

Python 2, 78 75 73 69 Bytes

Ein großes Lob an xnor und Flornquake
Jetzt fast 10 Bytes kürzer als die ursprüngliche Antwort

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

Sie können verkürzen [k,k+2*p][bool]zu k+2*p*(bool).
Xnor

@xnor Danke, 3 Bytes gespart.
Markuz

Auch k in m or k<0kann k*(k>=0)in mda sein, ob k<0das Produkt ist 0, was drin ist m.
Xnor

@xnor Genial!
Nochmals vielen

Sie können -1anstelle von schreiben p-1. Bearbeiten: Sie können auch mein Tupel erstellen und schreiben m=0,und m+=k+2*p*(k*(k>0)in m),.
Flornquake

4

Golfscript (41 45 )

Probieren Sie es hier online aus :

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

Erläuterung

Dies ist für die ursprüngliche 45-Byte-Lösung, aber es ist immer noch ziemlich dasselbe:

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

Edit # 1: Danke an Dennis für das Abschneiden von 4 Bytes.


4

Gleichstrom , 46 Bytes

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

Probieren Sie es online!

Dieses Programm nimmt Eingaben von einem ansonsten leeren Stapel entgegen und gibt sie an stdout aus (Zeilenumbruch getrennt).

Ich bin wirklich stolz auf diese - sie schlägt alles, was keine dedizierte Golfsprache ist, und zeigt drei meiner Lieblings-DC-Golftricks:

  • Stapelgröße wird als Indexvariable verwendet
  • Refactoring "wenn A, dann B, sonst C" in "bedingungslos C, und wenn A, dann D", wobei C und D zusammen B ergeben
  • Die wenig genutzte Funktion des Direktzugriffs-Arrays zur Lösung einer Eindeutigkeitsbeschränkung

Erläuterung

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

das ist wild, ich hatte keine ahnung, dass es dc überhaupt gibt
don bright

3

JavaScript - 81 80 79 70

Ein dickes Lob an edc65, die mir dabei geholfen haben, 9 Bytes zu sparen

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 => {für (a = [x = i = 0]; ++ i <n;) a [i] = x + = x> i & amp; a.indexOf (xi) <0? -I: i ; return a}
edc65

@ edc65 Grazie Mille :)
William Barbosa

3

JavaScript, ES6, 74 69 Zeichen

Führen Sie den folgenden Code in der neuesten Firefox-Webkonsole aus.

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

Ich werde später versuchen, mehr Golf zu spielen.

Anwendungsbeispiel:

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

3

MATLAB, 83 78 Bytes

Speichern Sie die unten als 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

Vom Befehlsfenster ausführen (5 Bytes)

n=9;f

Wenn das oben Genannte nicht zulässig ist, sind 90 Byte erforderlich.

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 Zeichen

Golf gespielt:

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

Ungolfed:

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

Probelauf:

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

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

-5 Bytes dank Jo King

Probieren Sie es online!


das ist erstaunlich ... das sieht buchstäblich so aus, als wäre meine Katze über meine Tastatur gelaufen.
Don Bright

3

05AB1E , 19 Bytes

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

Probieren Sie es online!

Erläuterung

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

Wie funktioniert das?
Lirtosiast

@lirtosiast: Es ist schon eine Weile her, seit ich diese Herausforderung gemeistert habe. Das ist die beste Erklärung, die ich kurzfristig machen kann. Hoffe es reicht.
Emigna

3

K (oK) , 53 Bytes

Lösung:

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

Probieren Sie es online!

Erläuterung:

Rekursive Lösung.

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

lesbare 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

Ich benutze 2 Tabellen wird die erste genannt ein und es gebaut wird , so dass ein [i] = 1 genau dann , wenn i hat in der Folge bereits erschienen Null sonst, während die zweite Tabelle , die die Sequenz tatsächlich hält


Ihre Sequenz sollte jedoch mit 0 beginnen
William Barbosa

1
Sie haben Recht, ich habe die Frage nicht sehr sorgfältig geprüft und angenommen, dass sie in mathworld dieselbe Definition hat (beginnend mit 1). Ich denke, das kostet kein Zeichen mehr. Ich werde sie später testen und korrigieren. Ich schreibe jetzt von meinem Handy aus!

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: Danke an @ xnors Tipps zur anderen Python-Antwort! (Mir ist gerade aufgefallen, dass beide sehr ähnlich aussehen.)

Edit 2: Nochmals vielen Dank, @xnor.


Dies ergibt eine Endlosschleife. Sie benötigen eine Art Kontrollfluss, f(x)der nicht immer sofort aufruft f(x-1).
Xnor

@xnor hat den Code korrigiert.
Soham Chowdhury

1
Dies scheint den n-ten Ausdruck zurückzugeben, nicht die ersten n Ausdrücke.
Dennis

Einige kleinere Speicherungen: t=0können als optionaler Parameter an fund t=t+sein t+=.
11.

2

Groovy: 122 118 111 Zeichen

Golf gespielt:

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

Probelauf:

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

2

Clojure: 174 Zeichen

Golf gespielt:

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

Probelauf:

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
Ich schlage vor, nicht aus STDIN zu lesen, sondern nur ein ganzzahliges Argument für die Funktion zu verwenden :) Auch wenn Sie keine Vorteile durch die Definition yim letFormular erzielen , können Sie den Ausdruck direkt dort verwenden, wo der Wert benötigt wird.
NikoNyrh

2

Mathcad, 54 "Bytes"

Bildbeschreibung hier eingeben


Aus Benutzersicht ist Mathcad praktisch ein 2D-Whiteboard, dessen Ausdrücke von links nach rechts und von oben nach unten ausgewertet werden. Mathcad unterstützt keine herkömmliche Texteingabe, sondern verwendet stattdessen eine Kombination aus Text und Sondertasten / Symbolleisten / Menüelementen, um einen Ausdruck, einen Text, einen Plot oder eine Komponente einzufügen. Geben Sie beispielsweise ":" ein, um den Definitionsoperator (auf dem Bildschirm als ": =" angezeigt) oder "ctl-shft- #", um den for-Schleifenoperator (einschließlich Platzhalter für die Iterationsvariable, Iterationswerte und einen Hauptteil) einzugeben Ausdruck). Was Sie im obigen Bild sehen, ist genau das, was auf der Benutzeroberfläche angezeigt und als "eingegeben" wird.

Für Golfzwecke ist die "Byte" -Zahl die äquivalente Anzahl von Tastaturoperationen, die zur Eingabe eines Ausdrucks erforderlich sind.


Das ist alles schön und gut , aber was sind die tatsächlichen Tastenanschläge?
Jo King


2

Stax , 19 Bytes

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

Führen Sie es aus und debuggen Sie es

Ausgepackt, ungolfed und kommentiert sieht es so aus. Es behält die bisherige Sequenz auf dem Stapel und speichert sie A(n - 1)im X-Register. Der Iterationsindex wird für verwendet n. Beim ersten Durchlauf ist es 0, aber bei dieser Iteration wird die 0 ohne Sonderfälle generiert, sodass keine Anpassung für den Off-by-1-Index erforderlich ist.

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

Führen Sie diesen aus und debuggen Sie ihn


interessant. wie funktioniert das?
Don Bright

1
@donbright: Einige Anmerkungen und Erklärungen hinzugefügt.
rekursiver


2

Pyth , 24 Bytes

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

Probieren Sie es 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

Eine weitere wörtliche Implementierung hier unten. Überraschenderweise auch für PowerShell lesbar.

Die Sequenz wird im Array $ a gespeichert und ein Term pro Zeile ausgedruckt.

Für n $ = 20 , wenn wir die Anweisung ausführen $a-join","erhalten wir

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

1

C #: 140 Zeichen

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 Zeichen (158 ohne cin- und cout-Anweisungen)

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;

Willkommen beim Programmieren von Puzzles & Code Golf Stack Exchange! Bitte bearbeiten Sie die Zeichen- / Bytezahl Ihrer Lösung in Ihrer Kopfzeile, wie in den anderen Antworten hier gezeigt. Spielen Sie auch Ihren Code so gut wie möglich ab (z. B. entfernen Sie Leerzeichen, um die Anzahl der Zeichen zu verringern). Vielen Dank!
Türklinke

Klar, das mache ich.
Abhay Jain

1

Mathematica - 81 Bytes

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

Verwendung

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

Probieren Sie es 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 für mein Ergebnis
  • $s zur Verfolgung von Sehern
  • $p vorheriger Wert
  • $m m ext Wert

1

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

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)))
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.