Wygeneruj sekwencję Recamana


20

Sekwencja Recamana ( A005132 ) jest sekwencją matematyczną zdefiniowaną jako taka:

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

Ładna wersja LaTex powyższego (może być bardziej czytelna):

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

Pierwsze kilka warunków to 0, 1, 3, 6, 2, 7, 13, 20, 12, 21, 11

Wyjaśnienie is newoznacza, czy liczba jest już w sekwencji.

Podana liczba całkowita n, za pomocą argumentu funkcji lub STDIN, zwraca pierwsze nwarunki sekwencji Recamán.


To wyzwanie dla golfa, więc wygrywa najkrótszy kod.


Co znaczy „jest nowy”?
Beta Decay

Jeśli liczba jest nowa, oznacza to, że nie znajduje się jeszcze w sekwencji. Właśnie zdałem sobie sprawę, że źle wpisałem sekwencję, daj mi minutę, aby ją poprawić.
James Williams

Poprawiono sekwencję.
James Williams

1
Czy możesz dodać pierwsze wartości sekwencji?
dumny haskeller

Dodano kilka pierwszych liczb! (I link do strony OEIS)
James Williams

Odpowiedzi:


9

CJam, 34 33 bajty

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

Wypróbuj online.

Przykładowy przebieg

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

Jak to działa

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

Jakich zmian dokonałeś?
Soham Chowdhury,

Moje pierwsze podejście dodało liczby ujemne do sekwencji, więc nie musiałem jawnie sprawdzać, czy A(i) - i > 0. Jednak nie przygotowałem wystarczającej liczby dla małych wartości n. Teraz robię dokładnie to, co mówi specyfikacja.
Dennis

33 vs. 45. Tak blisko i jak dotąd. :)
Ingo Bürk

Wow, komentuj bez e#w Cjam ... smaczna wiśnia.
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)

Przykładowe użycie:

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

6

Rubin, 71 70 bajtów

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

Bardzo implementacja definicji „słowo w słowo”.


5

Python 2, 78 75 73 69 bajtów

Wyrazy uznania dla xnora i trzęsienia ziemi
Teraz prawie 10 bajtów krótszych niż początkowa odpowiedź

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

Możesz skrócić [k,k+2*p][bool]do k+2*p*(bool).
xnor

@xnor Dzięki, zapisano 3 bajty.
Markuz,

k in m or k<0Może być również, k*(k>=0)in mponieważ k<0produkt jest 0, który jest w m.
xnor

@xnor Brilliant!
Jeszcze

Możesz pisać -1zamiast p-1. Edycja: Możesz także zrobić mkrotkę i pisać m=0,oraz m+=k+2*p*(k*(k>0)in m),.
trzęsienie ziemi

4

Gra w golfa (41 45 )

Wypróbuj online tutaj :

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

Wyjaśnienie

Dotyczy to oryginalnego rozwiązania 45 bajtów, ale nadal jest prawie takie samo:

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

Edycja nr 1: Podziękowania dla Dennisa za usunięcie 4 bajtów.


4

dc , 46 bajtów

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

Wypróbuj online!

Ten program pobiera dane wejściowe z innego pustego stosu i wyświetla dane wyjściowe na standardowe wyjście (rozdzielane znakiem nowej linii).

Jestem z tego naprawdę dumny - pokonuje wszystko, co nie jest dedykowanym językiem golfa, i prezentuje trzy moje ulubione sztuczki golfowe DC:

  • Rozmiar stosu używany jako zmienna indeksu
  • Refaktoryzacja „jeśli A, a następnie B, inaczej C” na „bezwarunkowo C, a jeśli A, to D”, gdzie C i D łączą się, tworząc B
  • mało używana funkcja tablicy dostępu swobodnego do rozwiązania ograniczenia wyjątkowości

Wyjaśnienie

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

to dzikie, nie miałem pojęcia, że ​​dc nawet istnieje
don bright

3

JavaScript - 81 80 79 70

Wyrazy uznania dla edc65 za pomoc w oszczędzaniu 9 bajtów

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 => {dla (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 znaków

Uruchom poniższy kod w najnowszej konsoli internetowej Firefox.

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

Spróbuję później zagrać w golfa.

Przykładowe użycie:

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

3

MATLAB, 83 78 bajtów

Zapisz poniżej jako f.m(73 bajty)

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

Uruchom z okna poleceń (5 bajtów)

n=9;f

Jeśli powyższe jest niezgodne z prawem, wymaga 90 bajtów.

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 znaków

Gra w golfa:

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

Nie golfowany:

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

Przykładowy przebieg:

> 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 bajtów

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

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

-5 bajtów dzięki Jo King

Wypróbuj online!


to niesamowite ... dosłownie wygląda, jakby mój kot przeszedł przez klawiaturę.
don bright

3

05AB1E , 19 bajtów

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

Wypróbuj online!

Wyjaśnienie

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

Jak to działa?
lirtosiast

@lirtosiast: Minęło trochę czasu, odkąd podjąłem to wyzwanie, więc jest to najlepsze wytłumaczenie, jakie mogę zrobić w krótkim czasie. Mam nadzieję, że to wystarczy.
Emigna

3

K (oK) , 53 bajty

Rozwiązanie:

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

Wypróbuj online!

Wyjaśnienie:

Rozwiązanie rekurencyjne.

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

czytelna wersja:

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

Używam 2 tabel, pierwsza nazywa się a i jest zbudowana tak, że [i] = 1 iff i już się pojawiło w sekwencji, w przeciwnym razie zero , podczas gdy druga tabela faktycznie zawiera sekwencję


Twoja sekwencja powinna zaczynać się od 0
William Barbosa,

1
Masz rację, nie przyjrzałem się temu pytaniu bardzo uważnie i założyłem, że ma ono taką samą definicję w świecie matematyki (zaczynając od 1), myślę, że to nie będzie kosztować więcej postaci, przetestuję ją i poprawię później, Piszę teraz z telefonu!

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

Edycja 1: Dzięki wskazówkom @ xnor na temat innej odpowiedzi w języku Python! (Właśnie zdałem sobie sprawę, że oba wyglądają bardzo podobnie.)

Edycja 2: Jeszcze raz dziękuję, @xnor.


Daje to nieskończoną pętlę. Potrzebujesz pewnego rodzaju kontroli, aby f(x)nie zawsze zadzwonił natychmiast f(x-1).
xnor

@xnor naprawił kod.
Soham Chowdhury,

1
To wydaje się zwracać n-ty termin, a nie pierwsze n-termin.
Dennis

Niektóre drobne zapisy: t=0mogą przejść jako parametr opcjonalny do fi t=t+mogą być t+=.
xnor

2

Porywające: 122 118 111 znaków

Gra w golfa:

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

Nie golfowany:

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

Przykładowy przebieg:

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

2

Clojure: 174 znaki

Gra w golfa:

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

Nie golfowany:

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

Przykładowy przebieg:

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
Sugeruję, abyś nie czytał ze STDIN, ale zamiast tego po prostu weź argument liczby całkowitej do funkcji :) Również nie dostaniesz żadnych korzyści z definicji yw letformularzu, możesz użyć wyrażenia bezpośrednio tam, gdzie jest potrzebna wartość.
NikoNyrh

2

Mathcad, 54 „bajtów”

wprowadź opis zdjęcia tutaj


Z perspektywy użytkownika Mathcad jest tablicą 2D, której wyrażenia są oceniane od lewej do prawej, od góry do dołu. Mathcad nie obsługuje konwencjonalnego wprowadzania „tekstu”, ale zamiast tego wykorzystuje kombinację tekstu i specjalnych klawiszy / paska narzędzi / elementów menu, aby wstawić wyrażenie, tekst, fabułę lub komponent. Na przykład wpisz „:”, aby wprowadzić operator definicji (pokazany na ekranie jako „: =”) lub „ctl-shft- #”, aby wprowadzić operator pętli for (w tym symbole zastępcze dla zmiennej iteracji, wartości iteracji i jedną treść wyrażenie). To, co widać na powyższym obrazku, jest dokładnie tym, co pojawia się w interfejsie użytkownika i jest „wpisane”.

Na potrzeby gry w golfa liczba „bajtów” jest równoważną liczbą operacji na klawiaturze wymaganych do wprowadzenia wyrażenia.


Wszystko dobrze i dobrze , ale jakie rzeczywiste naciśnięcia klawiszy?
Jo King


2

Stax , 19 bajtów

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

Uruchom i debuguj

Rozpakowane, niepolowane i skomentowane, wygląda to tak. Utrzymuje sekwencję do tej pory na stosie i zapamiętuje A(n - 1)w rejestrze X. Stosuje się indeks iteracji n. Za pierwszym razem jest to 0, ale w tej iteracji generuje 0 bez żadnych specjalnych przypadków, więc nie trzeba dostosowywać indeksu 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

Uruchom i debuguj ten


ciekawy. jak to działa?
don bright

1
@donbright: Dodano kilka adnotacji i wyjaśnień.
rekurencyjny


2

Pyth , 24 bajty

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

Wypróbuj 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

Tu też znajduje się kolejna implementacja „słowo w słowo”. Zaskakująco czytelny również dla PowerShell.

Sekwencja jest przechowywana w tablicy $ a i drukowana jeden termin na linię.

Dla $ n = 20, jeśli prowadzimy oświadczenie $a-join","otrzymujemy

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

1

C #: 140 znaków

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 znaków (158 bez instrukcji cin i 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;

Witamy w Programowaniu łamigłówek i wymianie stosów kodów golfowych! Edytuj liczbę znaków / bajtów swojego rozwiązania w nagłówku, jak pokazano w innych odpowiedziach tutaj. Prosimy również o poprawienie kodu (np. Usunięcie białych znaków, aby zmniejszyć liczbę znaków) w jak największym stopniu. Dzięki!
Klamka

Jasne, zrobię to.
Abhay Jain,

1

Mathematica - 81 bajtów

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

Stosowanie

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 bajtów

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

Wypróbuj online!

Nie golfowany:

$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 dla mojego wyniku
  • $s do śledzenia nasienia
  • $p poprzednia wartość
  • $m m ext wartość

1

Wspólny LISP (139 bajtów)

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

Nie golfowany:

(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)))
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.