Последовательность Стьюи: + * - / + * - /


29

Давайте используем четыре основные операции: сложение +, умножение *, вычитание -и деление /(число с плавающей точкой, а не целое число).

Последовательность Стьюи определяется следующим образом:

x = [x(1), x(2)]    // Two initial numbers (one indexed)
x(3) = x(1) + x(2)
x(4) = x(2) * x(3)
x(5) = x(3) - x(4)
x(6) = x(4) / x(5)
x(7) = x(5) + x(6)
... and so on.

Вызов:

Возьмите два неотрицательных целых числа ( x(1), x(2)) и одно положительное целое число в Nкачестве входных данных.

x(1)и x(2)будет двумя первыми числами вашей последовательности, и Nбудет длиной последовательности, которую вы должны вывести. (Вы можете выбрать список на основе 0, в этом случае Nдлина будет на единицу меньше длины).

  • Вы не можете предполагать это x(2) >= x(1).
  • Nвсегда будет, >2если 1 на основе, ( >1если 0 на основе).
  • Вам не нужно обрабатывать деление на ноль ошибок.
    • Обратите внимание на второй контрольный пример. Вы не получите 0, 1, и в N=6качестве ввода, так как это приведет к делению на ноль, но вы должны поддерживать 0, 1и N=5.
  • Предположим, будет дан только верный ввод.
  • Ввод и вывод могут быть в любом удобном формате, но вы должны поддерживать не менее 3 цифр после десятичной точки, если вывод не является целым числом.

Тестовые случаи:

1 3
8
1, 3, 4, 12, -8, -1.5, -9.5, 14.25

0 1
5
0, 1, 1, 1, 0     // N=6 would give division by zero error. You don't need to handle that case.

1 0
9
1, 0, 1, 0, 1, 0, 1, 0, 1

6 3
25
6, 3, 9, 27, -18, -1.5, -19.5, 29.25, -48.75, -0.6, -49.35, 29.61, -78.96, -0.375, -79.335, 29.7506, -109.086, -0.272727, -109.358, 29.825, -139.183, -0.214286, -139.398, 29.8709, -169.269

Может ли функция принимать x (1) и x (2) в виде списка? Или отдельные аргументы?
FlipTack

Все, что удобно для вас :)
Стьюи Гриффин

Может Nбыть 0 на основе? Поэтому возьмите в качестве входов 1 меньше, чем N, показанное в ваших примерах Я думаю, что брать N-2 - это слишком много, чтобы просить ... :-P
Луис Мендо

Когда вы пишете, вывод может быть в любом удобном формате , включает ли он список с последним элементом в начале и начальными элементами в конце (перевернутый список)?
Эминья

1
@ Emigna, нет, я думаю, что это немного натянуто ... Числа должны быть в правильном порядке
Стьюи Гриффин

Ответы:


3

MATL , 19 18 17 байт

q:"y'+*-/'@)hyhUV

Входные данные в формате: N( от 0), x(1), x(2)(как строки); все разделены переводом строки.

Попробуйте онлайн! Или проверьте все контрольные примеры (слегка измененный код; выходные последовательности разделены пустой строкой).

объяснение

У MATL нет правильной evalфункции, но U( str2num) может вычислять числовые выражения с помощью инфиксных операторов.

Каждый новый термин вычисляется и помещается в стек, сохраняя предыдущие термины. Весь стек печатается в конце.

q          % Implicitly input N (0-based). Subtract 1
:"         % Repeat that many times
  y        %   Duplicate x(n-1), where n is the number of already computed terms
           %   In the first iteration, which corresponds to n=2, this implicitly 
           %   inputs x(1) and x(2) as strings (and then duplicates x(1))
  '+*-/'   %   Push this string
  @)       %   Push iteration number and apply as modular index into the string. 
           %   So this gives '+' in the first iteration, '*' in the second etc
  h        %   Concatenate horizontally. This gives a string of the form
           %   '*x(n-1)+', where '+' is the appropriate operator 
  &y       %   Duplicate x(n)
  hh       %   Concatenate horizontally. This gives a string of the form
           %   'x(n-1)+x(n)'
  U        %   Convert to number. This evaluates the string
  V        %   Convert back to string. This is the new term, x(n+1)
           % Implicitly end loop and display stack

7

Haskell, 69 68 64 байта

x#n=take n$x++zipWith3 id(cycle[(+),(*),(-),(/)])(x#n)(tail$x#n)

x1и x2принимаются в виде списка. Пример использования: [1,3] # 8-> [1.0,3.0,4.0,12.0,-8.0,-1.5,-9.5,14.25].

Лень позволяет определить бесконечный рекурсивный список, в котором мы берем первые n элементов.

Haskell, 66 байт

(h%g)y x=x:g(h x y)y
a=(+)%b
b=(*)%c
c=(-)%d
d=(/)%a
(.a).(.).take 

Другой подход, чуть дольше. Порядок Аргумент N, x2, x1. Пример использования: ( (.a).(.).take ) 8 3 1-> [1.0,3.0,4.0,12.0,-8.0,-1.5,-9.5,14.25].

Определяет 4 функции a, b, cи dкоторые принимают два аргумента y, x и сделать список, поставив xперед вызовом следующей функции с в yкачестве второго аргумента , и x op yкак первый. Например aэто: a y x = x : (b (x+y) y), bделает умножение: b y x = x : (c (x*y) y)и т.д.

Редактировать: @ Майкл Кляйн сохранил байт в 1-м варианте ( #). К счастью, я также нашел один байт для второго варианта, поэтому оба снова имеют одинаковую длину.

Правка II: @Zgarb нашел 2 байта во второй версии для сохранения и I 4 в первой, так что они больше не имеют одинаковую длину.


Принять аргументы в виде списка (разрешено) для байта
Майкл Кляйн

Я всегда путаюсь, если (.)составлен с другими функциями: p
tomsmeding

g x=(`take`f)whereне сохраняет байт: - /
Берги

Сохраните 2 байта в альтернативном подходе:(h%g)y x=x:g(h x y)y
Zgarb

@ Zgarb: о, это мило. Благодарность! Кстати, при редактировании ваших предложений я нашел 4 байта для сохранения по пути в первой версии.
Ними

6

ES6 (Javascript), 79, 6765 байт

ОБНОВИТЬ

  • минус 2 байта, начиная с i = 2, как предложено @ETHProductions
  • Сохранено 3 байта, благодаря отличному совету @Neil!

Golfed

S=(n,a,i=2)=>i<n?S(n,a,a.push(eval(a[i-2]+"-/+*"[i%4]+a[i-1]))):a

Тест

S=(n,a,i=2)=>i<n?S(n,a,a.push(eval(a[i-2]+"-/+*"[i%4]+a[i-1]))):a

>S(8,[1,3])
Array [ 1, 3, 4, 12, -8, -1.5, -9.5, 14.25 ]

>S(5,[0,1])
Array [ 0, 1, 1, 1, 0 ]

>S(9,[1,0])
Array [ 1, 0, 1, 0, 1, 0, 1, 0, 1 ]

>S(25,[6,3])
Array [ 6, 3, 9, 27, -18, -1.5, -19.5, 29.25, -48.75, -0.6, ...]

1
Можете ли вы не использовать, ++iчтобы избежать необходимости добавлять 1 к iдважды?
Нил

1
Или, в качестве альтернативы, запись ?S(n,a,i+1,a.push(...)):aможет сэкономить вам несколько байтов.
Нил

1
Или, может быть, вы могли бы использовать тот факт, что a.pushвозвращает новую длину,S=(n,a,i=2)=>i<n?S(n,a,a.push(...)):a
Нейл

1
Я все еще думаю, что вы можете сохранить больше байтов, начав с i=2.
Нил

1
С предложением Нила, я думаю, вы можете S=(n,a,i=2)=>i<n?S(n,a,a.push(eval(a[i-2]+"+*-/"[i%4]+a[i-1]))):aсэкономить 2 байта.
ETHproductions

5

Python 3, 90 80 74 байта

xnor, вероятно, придет и уничтожит это решение ...

def F(s,n,i=2):
 while i<n:s+=eval('%s'*3%(s[-2],'-/+*'[i%4],s[-1])),;i+=1

Функция изменяет список, переданный ей. Используйте как это:

s = [1,3] 
F(s,8)

Попробуйте на repl.it!

-6 байт благодаря меди


Поскольку вы используете только Oодин раз, вы можете сохранить несколько байтов, сделав '-/+*'[i%4]и удалив объявление O. Кроме того, вы можете обойти повторные звонки str, сделав что-то вроде eval('%s'*3%(s[-2],'-/+*'[i%4],s[-1])).
Медь

Ах да, и s+=[...]может быть заменено на s+=...,(обратите внимание на запятую).
Медь

xnor не единственный, кто может разрушить ваше решение. Есть еще один человек: Деннис (мод).
Эрик Outgolfer

Вы гарантированно получите в iкачестве входных данных, поэтому вам не нужно значение по умолчанию для него ( i=2может быть просто i). Два байта прочь.
ArtOfCode

1
Если nвместо этого было разрешено возвращать этот элемент в последовательности, это на 1 байт короче с рекурсией:f=lambda x,n:n<2and x[n-1]or eval('%s'*3%(f(x,n-2),'*-/+'[n%4],f(x,n-1)))
mbomb007

5

Perl 6 ,  75 71  61 байт

->\a,\b,\c{$_=[|(&[+],&[*],&[-],&[/])xx*];(a,b,{.shift.($^a,$^b)}...*)[^c]}

Попробуй это

{$_=[|(&[+],&[*],&[-],&[/])xx*];($^a,$^b,{.shift.($^a,$^b)}...*)[^$^c]}

Попробуй это

{($^a,$^b,{(&[+],&[*],&[-],&[/])[$++%4]($^a,$^b)}...*)[^$^c]}

Попробуй это

Expanded:

{ # bare block lambda with placeholder parameters 「$a」 「$b」 「$c」

  # generate sequence
  (
    # initialize sequence
    $^a, # declare and use first argument
    $^b, # second argument

    {  # bare block lambda with two placeholder parameters 「$a」 「$b」

      (

        &[+], &[*], &[-], &[/] # the four operators

      )[             # index into the list of operators

         $++        # increment (++) an anonymous state variable ($)
         % 4        # modulo 4

      ]( $^a, $^b ) # and use it on the previous two values in sequence

    }

    ...  # repeat that until

    *    # indefinitely

  )[     # take only

    ^    # upto and excluding:     ( Range object )
    $^c  # third argument

  ]
}

4

Mathematica, 68 байт

(±1=#;±2=#2;±n_:=1##[#-#2,#/#2,+##][[n~Mod~4]]&[±(n-2),±(n-1)];±#3)&

Едва пробрался на 3 место! Безымянная функция трех аргументов, которая использует вспомогательный унарный оператор, ±такой, что ±nэто точно n-й элемент x (n) последовательности Стьюи. Первые два аргумента - это x (1) и x (2), а третий аргумент - это N, указывающий, какой x (N) мы выводим.

Прямая реализация с использованием вычисления mod-4, чтобы выбрать, какую двоичную функцию применять к двум предыдущим терминам. Выбор правильной бинарной функции, которая 1##[#-#2,#/#2,+##]помогает вам, использует некоторые из этих забавных трюков игры в гольф от Mathematica .


3

05AB1E , 21 19 18 байт

Ввод берется в порядке N (на основе 0), x (2) , x (1) .
Сохранено 1 байт благодаря carusocomputing .

GUDXsX"/+*-"Nè.V})

Попробуйте онлайн!

объяснение

 G                   # for N in [0 ... n-1] do:
  U                  # save top element of stack in X
   D                 # duplicate top of stack
    X                # push X
     s               # swap top 2 elements on stack
      X              # push X
       "/+*-"Nè      # index into the string with the current iteration number
               .V    # evaluate
                 }   # end loop
                  )  # wrap stack in list

Мы итеративно строим стек с последним элементом в последовательности сверху, сохраняя все предыдущие элементы в порядке.
Затем в конце мы оборачиваем стек в список, чтобы отобразить все значения сразу.


1
Я не мог понять это, но используя XYи UVможет сэкономить вам байты.
Волшебная Осьминога Урна

1
@carusocomputing: хороший улов! Сохраненный байт, который я потерял из реестра, не работает с неявным вводом, используя UX:)
Emigna

2

Common Lisp, 158

(lambda(x y n)(loop repeat n for a = x then b for b = y then r for o in '#1=(+ * - / . #1#)for r =(ignore-errors(funcall o a b))collect(coerce a'long-float)))

Не очень конкурентоспособный, но мне нравится, как это выражается вполне естественно:

(lambda (x y n)
  (loop 
    repeat n
    for a = x then b
    for b = y then r
    for o in '#1=(+ * - / . #1#)
    for r = (ignore-errors (funcall o a b))
    collect (coerce a 'long-float)))

Мы игнорируем ошибки при вычислении R, в результате чего R (а затем и B), возможно, принимает значение NIL. Это позволяет вывести текущий результат, даже если следующее значение не определено. Затем, в конце концов, цикл завершится ошибкой, но это в рамках правил.

тесты

Назовем функцию Fи убедимся, что ожидаемые значения примерно равны проверенному.

(loop
  for (args expected)
    in
  '(((1 3 8)
     (1 3 4 12 -8 -1.5 -9.5 14.25))

    ((0 1 5)
     (0 1 1 1 0))

    ((1 0 9)
     (1 0 1 0 1 0 1 0 1))

    ((6 3 25)
     (6 3 9 27 -18 -1.5 -19.5 29.25 -48.75 -0.6 -49.35 29.61 -78.96 -0.375 -79.335 29.7506 -109.086 -0.272727 -109.358 29.825 -139.183 -0.214286 -139.398 29.8709 -169.269)))

  for result = (apply #'f args)
  always (every (lambda (u v) (< (abs (- u v)) 0.001)) result expected))

=> T

Причина приблизительного теста состоит в том, что вычисленные значения немного более точны, чем требуется; здесь, для (f 6 3 25):

(6.0d0 3.0d0 9.0d0 27.0d0 -18.0d0 -1.5d0 -19.5d0 29.25d0 -48.75d0 -0.6d0
 -49.35d0 29.61d0 -78.96d0 -0.375d0 -79.335d0 29.750625d0 -109.085625d0
 -0.2727272727272727d0 -109.35835227272727d0 29.825005165289255d0
 -139.18335743801654d0 -0.21428571428571427d0 -139.39764315230224d0
 29.870923532636194d0 -169.26856668493843d0)

2

постоянный ток, 112 110 108 байт

5k?sarfsmsn[pSnla1-Sa]sh[lmlndSm]sv[lvx/lhx]sb[lvx+lhx]sc[lvx*lhx]sd[lvx-lhx]se[lcx2la>d2la>e2la>b2la>j]dsjx

Иногда dcответы могут быть очень длинными, а иногда они могут быть очень короткими. Все зависит только от поставленной задачи, как в случае со многими другими языками. В любом случае, при запросе в командной строке вводится разделенная пробелами одноиндексная входная строка из трех целых чисел, x(1), x(2), Nи каждый элемент последовательности выводится в отдельных строках с нецелыми выходными данными, содержащими 5 цифр после десятичной точки.

Например, ввод 6 3 25приводит к следующему выводу:

6
3
9
27
-18
-1.50000
-19.50000
29.25000
-48.75000
-.60000
-49.35000
29.61000
-78.96000
-.37500
-79.33500
29.75062
-109.08562
-.27272
-109.35834
29.82420
-139.18254
-.21428
-139.39682
29.86995
-169.26677

2

Perl, 62 + 3 ( -plaфлаг) = 65 байт

push@F,eval$F[-2].qw(* - / +)[$_%4].$F[-1]for 3..pop@F;$_="@F"

С помощью:

perl -plae 'push@F,eval$F[-2].qw(* - / +)[$_%4].$F[-1]for 3..pop@F;$_="@F"' <<< '1 3 8'

1

Рубин, 79 байтов

->(b,c,d){a=[b,c];(d-2).times{|i|a<<a[i].send(%i{+ * - /}[i%4],a[i+1]).to_f};a}

Я подозреваю, что это очень далеко от оптимального (и я еще не смотрел на другие ответы), но, тем не менее, это весело.

Я хотел повеселиться Enumerable#cycle, но, к сожалению, на 4 персонажа меньше, чем просто использовать %4.


1

C ++ 14, 118 байт

[](auto&v,int N){for(int i=0;++i<N-1;){auto p=v.rbegin(),q=p+1;v.push_back(i%4?i%4<2?*q+*p:i%4<3?*q**p:*q-*p:*q/ *p);}

Как безымянная лямбда изменяет свой ввод. Требуется vбыть vector<double>или vector<float>.

Ungolfed и использование:

#include<iostream>
#include<vector>

auto f=
[](auto&v,int N){
  for(int i=0; ++i<N-1;){
    auto p=v.rbegin(),q=p+1;
    v.push_back(
      i%4 ?
        i%4<2 ? *q+*p : 
          i%4<3 ? *q**p : *q-*p
      : *q/ *p
    );
  }
};

int main(){
  std::vector<double> v={1,3};
  f(v,8);
  for (auto x:v) std::cout << x << ", ";
  std::cout << "\n";
}

1

машинный код x86-64, 34 байта

Соглашение о вызове = x86-64 System V x32 ABI (зарегистрируйте аргументы с 32-разрядными указателями в длинном режиме).

Подпись функции есть void stewie_x87_1reg(float *seq_buf, unsigned Nterms);. Функция получает начальные значения x0 и x1 в первых двух элементах массива и расширяет последовательность, по крайней мере, еще на N элементов. Буфер должен быть дополнен до 2 + N-округлено до следующего-кратного-4. (т.е. 2 + ((N+3)&~3)или просто N + 5).

Требование заполненных буферов является нормальным в сборке для высокопроизводительных или SIMD-векторизованных функций, и этот развернутый цикл похож, поэтому я не думаю, что он слишком сильно нарушает правила. Вызывающий может легко (и должен) игнорировать все элементы заполнения.

Передача x0 и x1 как функции arg, которой еще нет в буфере, обойдется нам всего в 3 байта (для a movlps [rdi], xmm0или movups [rdi], xmm0), хотя это будет нестандартное соглашение о вызовах, поскольку System V передает struct{ float x,y; };в два отдельных регистра XMM.

Это objdump -drw -Mintelвывод с небольшим форматированием для добавления комментариев

0000000000000100 <stewie_x87_1reg>:
       ;; load inside the loop to match FSTP at the end of every iteration
       ;; x[i-1] is always in ST0
       ;; x[i-2] is re-loaded from memory
 100:   d9 47 04                fld    DWORD PTR [rdi+0x4]
 103:   d8 07                   fadd   DWORD PTR [rdi]
 105:   d9 57 08                fst    DWORD PTR [rdi+0x8]
 108:   83 c7 10                add    edi,0x10            ; 32-bit pointers save a REX prefix here

 10b:   d8 4f f4                fmul   DWORD PTR [rdi-0xc]
 10e:   d9 57 fc                fst    DWORD PTR [rdi-0x4]

 111:   d8 6f f8                fsubr  DWORD PTR [rdi-0x8]
 114:   d9 17                   fst    DWORD PTR [rdi]

 116:   d8 7f fc                fdivr  DWORD PTR [rdi-0x4]
 119:   d9 5f 04                fstp   DWORD PTR [rdi+0x4]

 11c:   83 ee 04                sub    esi,0x4
 11f:   7f df                   jg     100 <stewie_x87_1reg>
 121:   c3                      ret    

0000000000000122 <stewie_x87_1reg.end>:
## 0x22 = 34 bytes

Эта реализация ссылки C компилирует (с gcc -Os) в несколько похожий код. gcc выбирает ту же стратегию, что и я: хранить только одно предыдущее значение в регистре.

void stewie_ref(float *seq, unsigned Nterms)
{
    for(unsigned i = 2 ; i<Nterms ; ) {
        seq[i] = seq[i-2] + seq[i-1];       i++;
        seq[i] = seq[i-2] * seq[i-1];       i++;
        seq[i] = seq[i-2] - seq[i-1];       i++;
        seq[i] = seq[i-2] / seq[i-1];       i++;
    }
}

Я экспериментировал с другими способами, включая версию с двумя регистрами x87, которая имеет такой код:

; part of loop body from untested 2-register version.  faster but slightly larger :/
; x87 FPU register stack    ;       x1, x2   (1-based notation)
fadd    st0, st1            ; x87 = x3, x2
fst     dword [rdi+8 - 16]  ; x87 = x3, x2

fmul    st1, st0            ; x87 = x3, x4
fld     st1                 ; x87 = x4, x3, x4
fstp    dword [rdi+12 - 16] ; x87 = x3, x4
; and similar for the fsubr and fdivr, needing one fld st1

Вы бы сделали это таким образом, если бы вы шли на скорости (а SSE не было доступно)

Помогло бы размещение нагрузок из памяти внутри цикла вместо однократного ввода, поскольку мы могли бы просто хранить результаты sub и div не по порядку, но все же для настройки стека при входе необходимы две инструкции FLD.

Я также попытался использовать скалярную математику SSE / AVX (начиная со значений в xmm0 и xmm1), но больший размер инструкции является убийственным. Использование addps(так как это на 1B короче addss) помогает немного. Я использовал AVX VEX-префиксы для некоммутативных инструкций, поскольку VSUBSS всего на один байт длиннее SUBPS (и такой же длины, что и SUBSS).

; untested.  Bigger than x87 version, and can spuriously raise FP exceptions from garbage in high elements
addps   xmm0, xmm1      ; x3
movups  [rdi+8 - 16], xmm0
mulps   xmm1, xmm0      ; xmm1 = x4,  xmm0 = x3
movups  [rdi+12 - 16], xmm1
vsubss  xmm0, xmm1, xmm0      ; not commutative.  Could use a value from memory
movups  [rdi+16 - 16], xmm0
vdivss  xmm1, xmm0, xmm1      ; not commutative
movups  [rdi+20 - 16], xmm1

Протестировано с помощью этого теста:

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

int main(int argc, char**argv)
{
    unsigned seqlen = 100;
    if (argc>1)
        seqlen = atoi(argv[1]);
    float first = 1.0f, second = 2.1f;
    if (argc>2)
        first = atof(argv[2]);
    if (argc>3)
        second = atof(argv[3]);

    float *seqbuf = malloc(seqlen+8);  // not on the stack, needs to be in the low32
    seqbuf[0] = first;
    seqbuf[1] = second;

    for(unsigned i=seqlen ; i<seqlen+8; ++i)
        seqbuf[i] = NAN;

    stewie_x87_1reg(seqbuf, seqlen);
//  stewie_ref(seqbuf, seqlen);
    for (unsigned i=0 ; i< (2 + ((seqlen+3)&~3) + 4) ; i++) {
        printf("%4d: %g\n", i, seqbuf[i]);
    }

    return 0;
}

Компилировать с nasm -felfx32 -Worphan-labels -gdwarf2 golf-stewie-sequence.asm &&
gcc -mx32 -o stewie -Og -g golf-stewie-sequence.c golf-stewie-sequence.o

Запустите первый тест-кейс с ./stewie 8 1 3

Если у вас не установлены библиотеки x32, используйте nasm -felf64и оставьте gcc по умолчанию -m64. Я использовал mallocвместо float seqbuf[seqlen+8](в стеке) получение низкого адреса без фактической сборки как x32.


Интересный факт: в YASM есть ошибка: он использует rel32 jcc для ветвления цикла, когда цель ветвления имеет тот же адрес, что и глобальный символ.

global stewie_x87_1reg
stewie_x87_1reg:
   ;; ended up moving all prologue code into the loop, so there's nothing here
.loop:

...
sub    esi, 4
jg     .loop

собирает в ... 11f: 0f 8f db ff ff ff jg 100 <stewie_x87_1reg>




0

Bash, 224 байта (без конкурса)

Чрезвычайно большая реализация в BASH .

Принимает задачу буквально и делает все в одной непрерывной трубе, без каких-либо порочных структур управления или рекурсии.

вход

$ 1, $ 2 - начальные элементы

$ 3 - размер целевой последовательности

Golfed

{ echo "a[0]=$1;a[1]=$2;a[0];a[1]";paste <() <(seq 2 $[$3-1]) <(seq 0 $[$3-3]) <(printf '%.0s+*-/' `seq $[$3/4]`|fold -1|head -$[$3-2]) <(seq 1 $[$3-2]);}|sed -r '1 ! s/(.+)\s(.+)\s(.+)\s(.)/a[\1]=a[\2]\3a[\4];a[\1];/'|bc -l

Меньше гольфа

{ 
 echo "a[0]=$1;a[1]=$2;a[0];a[1]";
 paste <() <(seq 2 $[$3-1]) <(seq 0 $[$3-3]) <(printf '%.0s+*-/' `seq $[$3/4]`|fold -1|head -$[$3-2]) <(seq 1 $[$3-2]);
}\
|sed -r '1 ! s/(.+)\s(.+)\s(.+)\s(.)/a[\1]=a[\2]\3a[\4];a[\1];/' \
|bc -l

Тест

>./stewie.sh 1 3 8
1
3
4
12
-8
-1.50000000000000000000
-9.50000000000000000000
14.25000000000000000000

Этапы трубопровода

Создайте таблицу индексов элементов + op для каждого элемента выходной последовательности (по одному на строку):

...
2   0   +   1
3   1   *   2
4   2   -   3
5   3   /   4
6   4   +   5
7   5   *   6
...

Используйте sed, чтобы преобразовать это в линейную программу bc :

...
a[2]=a[0]+a[1];a[2];
a[3]=a[1]*a[2];a[3];
a[4]=a[2]-a[3];a[4];
a[5]=a[3]/a[4];a[5];
a[6]=a[4]+a[5];a[6];
a[7]=a[5]*a[6];a[7];
...

накормить это до н.э. и пусть он сделает всю работу


0

Pyth - 20 байт

Вывод всего nстоит мне.

u+Gvj@"+*-/"H>2GttEQ

Не работает онлайн потому что Eval.


0

Цейлон, 195 байт

Float[]s(Integer a,Integer b,Integer n)=>loop([a.float,b.float,[Float.divided,Float.plus,Float.times,Float.minus].cycled.rest])(([x,y,o])=>[y,(o.first else nothing)(x)(y),o.rest]).take(n)*.first;

Отформатировано и прокомментировано:

// Print the first n entries of the Stewies sequence with given starting entries.
//
// Question:  http://codegolf.stackexchange.com/q/101145/2338
// My answer: http://codegolf.stackexchange.com/a/101251/2338

// Declare a function `s` which takes three integers, and returns a tuple
// of floats. (The more common syntax for the return value is [Float*],
// but Float[] is shorter.)
Float[] s(Integer a, Integer b, Integer n)
       // it is implemented by evaluating the following expression for each call.
         =>
        // start a loop with ...
        loop([
              // ... float versions of the integers, and ...
              a.float, b.float,
              // ... an infinite sequence of the four operators, ever repeating.
              // I needed the `.rest` here so the whole thing gets a {...*} type
              // instead of {...+}, which doesn't fit to what o.rest returns.
              // Each operator has the type Float(Float)(Float), i.e. you apply
              // it twice to one float each to get a Float result.
              [Float.divided, Float.plus, Float.times, Float.minus].cycled.rest])
               // in each iteration of the loop, map the triple of two numbers
               // and a sequence of operators to a triple of ... 
            (([x, y, o]) => [
               // the second number, 
                y,
               //the result of the first operator with both numbers
               // (using this "else nothing" here to convince the
               //  compiler that o.first is not null),
                   (o.first else nothing)(x)(y),
               // and the sequence of operators without its first element.
               // (that one unfortunately has a {...*} type, i.e. a possibly
               //  empty sequence.)
                                                 o.rest])
            // now we got an infinite sequence of those triples.
            // We just want the first n of them ...
                .take(n)
            // and of each triple just the first element.
            // (The *. syntax produces a tuple, non-lazily.
            //  We could also have used .map((z) => z.first)
            //  or .map(Iterable.first) or .map((z) => z[0]), each of
            //  which would return a (lazy) sequence, but they all would be
            //  longer.)
                *.first;

Пример использования:

shared void run() {
    print(s(1, 3, 8));
    print(s(0,1,11));
    print(s(1,0,9));
    print(s(6, 3, 29));
}

Пример вывода:

[1.0, 3.0, 4.0, 12.0, -8.0, -1.5, -9.5, 14.25]
[0.0, 1.0, 1.0, 1.0, 0.0, Infinity, Infinity, Infinity, NaN, NaN, NaN]
[1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0]
[6.0, 3.0, 9.0, 27.0, -18.0, -1.5, -19.5, 29.25, -48.75, -0.6, -49.35, 29.61, -78.96000000000001, -0.37499999999999994, -79.33500000000001, 29.750625, -109.08562500000001, -0.2727272727272727, -109.35835227272727, 29.825005165289255, -139.18335743801651, -0.2142857142857143, -139.39764315230224, 29.870923532636194, -169.26856668493843, -0.17647058823529413, -169.44503727317374, 29.90206540114831, -199.34710267432206]

Второй пример показывает, как это будет обрабатывать деление на ноль. Последний пример показывает, что результаты немного отличаются в зависимости от того, какой тип арифметики (и округления) используется ... Я думаю, что 64-битная арифметика Цейлона немного ближе к тому, что должно быть, чем то, что было опубликовано в вопросе ,


0

Clojure, 99 байт

#(let[ops[+ * - /]](take %3(map first(iterate(fn[[a b i]][b((ops i)a b)(mod(inc i)4)])[%1 %2 0]))))

Эта версия лучше использовать на практике, но имеет 110 байтов:

(defn f[a b n](let[ops[+ * - /]](take n(map first(iterate(fn[[a b i]][b((ops i)a b)(mod(inc i)4)])[a b 0])))))

У меня были проблемы со слиянием итерированной функции и циклической последовательности операций, поэтому мне пришлось вместо этого использовать счетчик. Также пытался использовать таблицу переходов FSM, как, {+ * * - - / / +}но я не мог сжать ее для меньшего количества кода.

Может быть выражено как анонимная функция

Un-golfed:

(defn f [a b n]
  (let [ops [+ * - /]]
    (->> [a b 0]
         (iterate (fn [[a b i]]
                    [b
                     ((ops i) a b)
                     (mod (inc i) 4)]))
         (map first)
         (take n))))

Должен быть вызван с плавающей точкой, (f 6.0 3.0 25)как иначе вы получите рациональные числа. В качестве альтернативы может быть начата итерация, [a (float b) 0]которая приносит дополнительные символы.


0

Октава , 91 байт

@(x,n)eval 'for i=3:n,x(i)=eval([(n=@num2str)(x(i-2)),"*-/+"(mod(i,4)+1),n(x(i-1))]);end,x'

Попробуйте онлайн!

Некоторые гольфы:

  • Нет скобок для первого evalзвонка
  • Нет конкатенаций для первого evalзвонка
  • Встроенное назначение *-/+(не возможно в MATLAB)
  • В сочетании 'и "во избежание выхода из апострофов (невозможно в MATLAB)
  • Хранение, n=@num2strтак как он используется дважды (невозможно в MATLAB)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.