Створити послідовність Рекамана


20

Послідовність Ремамана ( 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, поверніть перші nумови послідовності Recamán.


Це проблема з кодовим гольфом, тому виграє найкоротший код.


Що означає "нове"?
Бета-розпад

Якщо число нове, це означає, що воно ще не в послідовності. Щойно зрозумів, що я неправильно набрав послідовність, дайте мені хвилину, щоб її виправити.
Джеймс Вільямс,

Виправлена ​​послідовність.
Джеймс Вільямс

1
Чи можете ви додати перші значення послідовності?
гордий haskeller

Додано перші кілька номерів! (І посилання на його сторінку OEIS)
Джеймс Вільямс,

Відповіді:


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

Мій перший підхід передбачав негативні числа до послідовності, тому мені не довелося чітко перевіряти, чи є A(i) - i > 0. Однак я не додав достатньої кількості для малих значень n. Тепер я просто роблю саме те, що говорить специфікація.
Денніс

33 проти 45. Так близько, але поки що далеко. :)
Ingo Bürk

Нічого, коментуйте без e#Cjam ... смачна вишня.
Хром

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

Пітон 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

@xnor Спасибі, збережено 3 байти.
Маркуз

Крім того, k in m or k<0може бути, k*(k>=0)in mякщо if k<0, продукт є 0, який знаходиться в m.
xnor

@xnor Блискуче! Ще раз спасибі
Markuz

Можна писати -1замість p-1. Редагувати: Ви також можете зробити mкортеж і написати m=0,і m+=k+2*p*(k*(k>0)in m),.
flornquake

4

Гольфскрипт (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. Дякуємо Деннісу за те, що він поголив 4 байти.


4

постійного струму , 46 байт

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

Спробуйте в Інтернеті!

Ця програма приймає введення з інакше порожнього стека та виводить у stdout (з новим рядком).

Я справді пишаюся цим - він перемагає все, що не є спеціальною мовою для гри в гольф, і демонструє три мої улюблені трюки з гольфу в DC:

  • Розмір стека, що використовується в якості змінної індексу
  • Рефакторинг "якщо A тоді B else 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

Kudos to 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

@ edc65 Grazie mille :)
Вільям Барбоса

3

JavaScript, ES6, 74 69 символів

Запустіть наведений нижче код на останній веб-консолі Firefox.

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

05AB1E , 19 байт

¾ˆG¯¤N-DŠD0›*å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

Як це працює?
lirtosiast

@lirtosiast: Колись я робив цей виклик, було дуже довго, тому це найкраще пояснення, яке я можу зробити за короткий час. Сподіваюся, цього достатньо.
Емінья

3

K (oK) , 53 байти

Рішення:

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

Спробуйте в Інтернеті!

Пояснення:

Рекурсивне рішення.

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

Ява, 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

Луа - 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

читана версія:

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

Я використовую 2 таблиці, перша називається a, і вона побудована таким чином, що a [i] = 1 iff i вже з'явився в послідовності, нуль інакше, тоді як друга таблиця фактично містить послідовність


Ваша послідовність повинна починатися з 0, проте
Вільям Барбоса

1
Ви маєте рацію, я не дуже уважно подивився на це питання і припустив, що воно має те саме визначення у mathworld (починаючи з 1), я думаю, що це більше не буде коштувати символів, я перевіряю і виправляю його пізніше, Я зараз пишу з телефону!

2

Пітона, 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

Редагувати 1: Завдяки підказкам @ xnor щодо іншої відповіді Python! (Я щойно зрозумів, що обидва дуже схожі.)

Редагувати 2: Ще раз дякую, @xnor.


Це дає нескінченну петлю. Вам потрібен певний потік управління, щоб f(x)не завжди одразу викликати f(x-1).
xnor

@xnor виправив код.
Soham Chowdhury

1
Це, здається, повертає n-й термін, а не перший російський термін.
Денніс

Деякі незначні збереження: t=0можуть переходити як необов'язковий параметр до fта t=t+можуть бути t+=.
xnor

2

Грувий: 122 118 111 символів

Гольф:

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

Безголівки:

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

Виконання зразка:

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

2

Clojure: 174 символів

Гольф:

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

Безголівки:

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

Проба зразка:

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 , але замість того, щоб просто взяти цілочисельний аргумент функції :) Крім того, ви не отримаєте ніякої вигоди від визначення yна letформі, ви можете використовувати вираз безпосередньо там , де потрібно значення.
NikoNyrh

2

Mathcad, 54 "байти"

введіть тут опис зображення


З точки зору користувача, Mathcad фактично є двовимірною дошкою, вирази оцінюються зліва направо, зверху вниз. Mathcad не підтримує звичайний текст "введення тексту", але замість цього використовується комбінація тексту та спеціальних клавіш / панелі інструментів / елементів меню, щоб вставити вираз, текст, графік або компонент. Наприклад, введіть ":" для введення оператора визначення (на екрані відображається як ": =") або "ctl-shft- #", щоб ввести оператор циклу (включаючи заповнювачі для змінної ітерації, значення ітерації та одне тіло вираз). Те, що ви бачите на зображенні вище, саме те, що відображається в інтерфейсі користувача та як "набрано".

Для цілей гольфу кількість байтів - це еквівалентна кількість операцій на клавіатурі, необхідних для введення виразу.


Це все добре , але то , що є реальні натискання клавіш?
Джо Кінг


2

Стакс , 19 байт

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

Запустіть і налагоджуйте його

Розпакований, неозорений та прокоментований, це виглядає приблизно так. Він зберігає послідовність поки що на стеку і запам'ятовує A(n - 1)в X-регістрі. Індекс ітерації використовується для n. Перший раз через 0 це 0, але в цій ітерації він генерує 0 без особливих випадків, тому не потрібно коригувати індекс 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

Запустити та налагодити цей


цікаво. як це працює?
нехай яскравий

1
@donbright: Додано деякі примітки та пояснення.
рекурсивна

2

Pyth, 31 байт

VQ=+Y?Y?|>NeYhxY-eYN+eYN-eYNZ)Y

Ласкаво просимо на сайт!
Пшеничний майстер

Ласкаво просимо. Відповіді, що стосуються лише коду, відмовляються, оскільки вони, як правило, автоматично позначаються як неякісні. Додайте пояснення та розгляньте можливість додавання посилання до онлайн-перекладача, наприклад: tio.run/##K6gsyfj/PyzQVjvSPtK@xs4vNTKjIlI3NdJPG4hBdJRm5P//hoYA
mbomb007

2

Pyth , 24 байти

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

Спробуйте в Інтернеті!

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

Ще одна реалізація «слово за словом» також тут. Дивно читати і для PowerShell.

Послідовність зберігається в масиві $ a і роздруковується один додаток на рядок.

За $ п = 20 , якщо ми виконаємо оператор $a-join","отримує

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

1

C #: 140 символів

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 символів (158 без заяв cin і 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;

Ласкаво просимо до головоломки програмування та обміну гольфу для коду! Будь ласка, відредагуйте кількість символів / байтів вашого рішення у своєму заголовку, як показано в інших відповідях тут. Крім того, будь ласка, гольф свій код (наприклад, видаліть пробіли, щоб зменшити кількість символів) якомога більше. Спасибі!
Дверна ручка

Звичайно, я це зроблю.
Abhay Jain

1

Mathematica - 81 байт

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

Використання

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 байт

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

Спробуйте в Інтернеті!

Безголівки:

$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 за мій результат
  • $s для відстеження зображень
  • $p попереднє значення
  • $m м екст значення

1

Загальний LISP (139 байт)

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

Безголівки:

(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)))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.