Recamán dizisini oluştur


20

Recamán'ın dizisi ( A005132 ) şu şekilde tanımlanan bir matematik dizisidir:

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

Yukarıdakilerin güzel bir LaTex sürümü (daha okunabilir olabilir):

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

İlk birkaç terim 0, 1, 3, 6, 2, 7, 13, 20, 12, 21, 11

Açıklığa kavuşturmak için, is newsayının zaten sırada olup olmadığı anlamına gelir.

nFonksiyon argümanı veya STDIN aracılığıyla bir tamsayı verildiğinde nRecamán dizisinin ilk terimlerini döndürün.


Bu bir kod golf mücadelesi, bu yüzden en kısa kod kazanır.


'Yeni' ne demek?
Beta Çürüğü

Bir sayı yeniyse, henüz dizide bulunmadığı anlamına gelir. Sadece diziyi yanlış yazdığımı fark ettim, düzeltmek için bana bir dakika ver.
James Williams

Sekans düzeltildi.
James Williams

1
Dizinin ilk değerlerini ekleyebilir misiniz?
gururlu haskeller

İlk birkaç sayı eklendi! (Ve OEIS sayfasına bir bağlantı)
James Williams

Yanıtlar:


9

CJam, 34 33 bayt

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

Çevrimiçi deneyin.

Örnek çalışma

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

Nasıl çalışır

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

Ne gibi bir değişiklik yaptın?
Soham Chowdhury

İlk yaklaşımım sıraya negatif sayılar ekledi, bu yüzden açıkça olup olmadığını kontrol etmek zorunda kalmadım A(i) - i > 0. Ancak, küçük değerleri için yeterli sayıları başaramadım n. Şimdi, tam olarak spesifikasyonun söylediklerini yapıyorum.
Dennis

33 vs. 45. Çok yakın ve şimdiye kadar. :)
Ingo Bürk

Vay be, e#Cjam olmadan yorum ... lezzetli kiraz.
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)

Örnek kullanım:

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

6

Yakut, 71 70 bayt

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

Tanımın çok "kelime-kelime" uygulaması.


5

Python 2, 78 75 73 69 Bayt

Xnor ve flornquake şeref
Şimdi ilk cevaptan yaklaşık 10 bayt daha kısa

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

Sen kısaltabilir [k,k+2*p][bool]için k+2*p*(bool).
xnor

@xnor Teşekkürler, 3 Bayt kaydedildi.
Markuz

Ayrıca, k in m or k<0o zaman k*(k>=0)in molabilir k<0, ürün 0, içinde olan m.
xnor

@xnor Brilliant! Tekrar teşekkürler
Markuz

Bunun -1yerine yazabilirsiniz p-1. Düzenleme: Ayrıca yapabilir mbir demet ve yazma m=0,ve m+=k+2*p*(k*(k>0)in m),.
flornquake

4

Golf Yazıları (41 45 )

Buradan çevrimiçi deneyin :

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

açıklama

Bu orijinal 45 baytlık çözüm içindir, ancak yine de hemen hemen aynıdır:

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

Düzenleme # 1: Dennis'e 4 bayt tıraş ettiği için teşekkürler.


4

dc , 46 bayt

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

Çevrimiçi deneyin!

Bu program başka türlü boş bir yığından girdi alır ve stdout'a (yeni satır sınırlandırılır) çıkar.

Bununla gerçekten gurur duyuyorum - özel bir golf dili olmayan her şeyi yeniyor ve en sevdiğim dc golf numaralarından üçünü sergiliyor:

  • Dizin değişkeni olarak kullanılan yığın boyutu
  • "A sonra B başka C" yi "koşulsuz C" ye yeniden düzenleme ve C ve D'nin B
  • benzersiz kısıtlamayı çözmek için az kullanılan rastgele erişim dizisi özelliği

açıklama

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

bu vahşi, dc bile var hiçbir fikrim yoktu
don parlak

3

JavaScript - 81 80 79 70

9 bayt kurtarmama yardım ettiği için edc65'e şeref

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

@ edc65 Grazie mille :)
William Barbosa

3

JavaScript, ES6, 74 69 karakter

En son Firefox'un Web Konsolunda aşağıdaki kodu çalıştırın.

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

Daha sonra golf oynamaya çalışacağız.

Örnek kullanım:

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

3

MATLAB, 83 78 Bayt

Aşağıdakileri kaydedin 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

Komut penceresinden çalıştır (5 bayt)

n=9;f

Yukarıdakiler yasal değilse, 90 bayt gerektirir.

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 karakter

golfed:

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

Örnek Çalışma:

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

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

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

Jo King sayesinde -5 bayt

Çevrimiçi deneyin!


bu inanılmaz ... kelimenin tam anlamıyla kedimin klavyemin üzerinden geçtiği anlaşılıyor.
Parlak don

3

05AB1E , 19 bayt

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

Çevrimiçi deneyin!

açıklama

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

Bu nasıl çalışıyor?
lirtosiast

@lirtosiast: Bu zorluğu yaptığımdan beri bir süredir, bu yüzden kısa sürede yapabileceğim en iyi açıklama bu. Umarım yeterlidir.
Emigna

3

K (oK) , 53 bayt

Çözüm:

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

Çevrimiçi deneyin!

Açıklama:

Özyinelemeli çözüm.

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

okunabilir versiyon:

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

I2 tablolar kullanmak, ilk olarak adlandırılır bir ve böylece oluşmuş olduğu bir [I] = 1 IFF ı önceden dizisi ortaya çıkmıştır nil ikinci tablo aslında sekansına sahip ise, aksi halde


Sıralamanız 0 ile başlamalıdır
William Barbosa

1
Haklısın, soruya çok dikkatle bakmadım ve mathworld'de (1'den başlayarak) aynı tanıma sahip olduğunu varsaydım, bence bu artık daha fazla karaktere mal olmayacak, daha sonra test edeceğim ve düzeltecağım, Şimdi telefonumdan yazıyorum!

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

Düzenleme 1: Diğer Python cevabındaki @ xnor'ın ipuçları sayesinde! (Her ikisinin de çok benzer göründüğünü fark ettim.)

Edit 2: Tekrar teşekkürler, @xnor.


Bu sonsuz bir döngü verir. Her f(x)zaman hemen arama yapmamak için bir tür kontrol akışına ihtiyacınız vardır f(x-1).
xnor

@xnor kodu düzeltti.
Soham Chowdhury

1
Bu, n terimini döndürüyor gibi görünüyor, ilk n terimleri değil.
Dennis

Bazı küçük tasarruflar: t=0isteğe bağlı bir parametre olarak gidebilir fve t=t+olabilir t+=.
xnor

2

Groovy: 122 118 111 karakter

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

Örnek Çalışma:

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

2

Clojure: 174 karakter

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

Örnek çalışma:

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
STDIN okumamanızı öneririm, bunun yerine işleve bir tamsayı argümanı almanızı öneririm :) Ayrıca form yüzerinde tanımlamaktan herhangi bir fayda elde letedemezsiniz, ifadeyi doğrudan değerin gerektiği yerde kullanabilirsiniz.
NikoNyrh

2

Mathcad, 54 "bayt"

enter image description here


Kullanıcı açısından, Mathcad etkili bir şekilde 2D beyaz tahtadır ve ifadeler soldan sağa, yukarıdan aşağıya değerlendirilmiştir. Mathcad geleneksel bir "metin" girişini desteklemez, bunun yerine ifade, metin, çizim veya bileşen eklemek için metin ve özel tuşlar / araç çubuğu / menü öğelerinin birleşimini kullanır. Örneğin, tanım operatörünü girmek için ":" yazın (ekranda ": =" olarak gösterilir) veya "ctl-shft- #" için for döngüsü operatörünü (yineleme değişkeni, yineleme değerleri ve bir gövde için yer tutucular dahil) girin sentezleme). Yukarıdaki resimde gördüğünüz, tam olarak kullanıcı arayüzünde görünen ve "yazılan" olarak görünen şeydir.

Golf amacıyla, "bayt" sayısı bir ifade girmek için gereken klavye işlemlerinin sayısıdır.


Hepsi bu iyi ve güzel , ama ne olduğunu gerçek tuş vuruşlarını?
Jo King


2

Stax , 19 bayt

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

Çalıştır ve hata ayıkla

Ambalajından çıkarılmış, golf edilmemiş ve yorum yapılmış gibi görünüyor. Diziyi yığının üzerinde tutar ve A(n - 1)X kaydında hatırlar . Yineleme indeksi için kullanılır n. İlk kez 0'dır, ancak bu yinelemede özel durumlar olmadan 0'ı üretir, bu nedenle 1'e kadar indeks için ayarlamaya gerek yoktur.

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

Bunu çalıştırın ve hata ayıklayın


ilginç. bu nasıl çalışıyor?
Parlak don

1
@ donbright: Bazı ek açıklamalar ve açıklamalar eklendi.
özyinelemeli


2

Pyth , 24 bayt

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

Çevrimiçi deneyin!

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

Burada da başka bir 'kelime-kelime' uygulaması. PowerShell için de şaşırtıcı derecede okunabilir.

Dizi $ a dizisinde saklanır ve her satıra bir terim yazdırılır.

Biz deyimi çalıştırırsanız $ n = 20 $a-join","elde ederiz

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

1

C #: 140 karakter

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 karakter (158 cin ve cout deyimi olmadan)

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;

Programlama Bulmacalar ve Kod Golf Stack Exchange hoş geldiniz! Lütfen çözümünüzün karakter / bayt sayısını başlığınıza, diğer yanıtlarda gösterildiği gibi düzenleyin. Ayrıca, lütfen kodunuzu golf (karakter sayısını azaltmak için boşluk kaldırmak) mümkün olduğunca golf. Teşekkürler!
Kapı tokmağı

Elbette, ben yaparım.
Abhay Jain

1

Mathematica - 81 bayt

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

kullanım

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 bayt

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

Çevrimiçi deneyin!

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 sonucum için
  • $s görmek için
  • $p önceki değer
  • $m m dahili değer

1

Ortak LISP (139 bayt)

(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)))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.