32
\$\begingroup\$

Let's use the four basic operations, addition +, multiplication *, subtraction - and division / (float, not integer).

Stewie's sequence is defined as follows:

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.

Challenge:

Take two non-negative integers (x(1), x(2)), and one positive integer N as input.

x(1) and x(2) will be the two first numbers of your sequence, and N will be the length of the sequence you must output. (You can choose to have the list 0-based, in which case N will be one less than the length).

  • You can not assume that x(2) >= x(1).
  • N will always be >2 if 1-based, (>1 if 0-based).
  • You do not have to handle division by zero errors.
    • Note the 2nd test case. You will not get 0, 1, and N=6 as input, since that will result in division by zero, but you must support 0, 1 and N=5.
  • Assume only valid input will be given.
  • The input and output can be on any convenient format, but you must support at least 3 digits after the decimal points if the output is non-integer.

Test cases:

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
\$\endgroup\$
7
  • \$\begingroup\$ Can a function take x(1) and x(2) as a list? Or seperate arguments? \$\endgroup\$
    – FlipTack
    Commented Nov 25, 2016 at 22:31
  • \$\begingroup\$ Whatever is convenient for you :) \$\endgroup\$ Commented Nov 25, 2016 at 22:32
  • \$\begingroup\$ Can N be 0-based? So take as inputs 1 less than the N shown in your examples. I guess taking N-2 is too much to ask for... :-P \$\endgroup\$
    – Luis Mendo
    Commented Nov 25, 2016 at 22:44
  • \$\begingroup\$ When you write output can be on any convenient format, does that include a list with the final element in the beginning and the start-elements at the end (a reversed list)? \$\endgroup\$
    – Emigna
    Commented Nov 25, 2016 at 22:50
  • 1
    \$\begingroup\$ @Emigna, no I think that's a bit of a stretch... The numbers should be in the correct order \$\endgroup\$ Commented Nov 25, 2016 at 22:58

24 Answers 24

9
\$\begingroup\$

Haskell, 69 68 64 bytes

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

x1 and x2 are taken as a list. Usage example: [1,3] # 8 -> [1.0,3.0,4.0,12.0,-8.0,-1.5,-9.5,14.25].

Laziness makes it possible to define an infinite recursive list where we take the first n elements.

Haskell, 66 bytes

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

Different approach, slightly longer. Argument order is N, x2, x1. Usage example: ( (.a).(.).take ) 8 3 1 -> [1.0,3.0,4.0,12.0,-8.0,-1.5,-9.5,14.25].

Defines 4 functions a, b, c and d which take two arguments y, x and make a list by putting x in front of a call to the next function with y as the second argument and x op y as the first. For example a is: a y x = x : (b (x+y) y), b does multiplication: b y x = x : (c (x*y) y), etc.

Edit: @Michael Klein saved a byte in the 1st variant (#). Luckily I also found one byte for the second variant, so both have the same length again.

Edit II: @Zgarb found 2 bytes in the second version to save, and I 4 in the first, so they are no longer of the same length.

\$\endgroup\$
5
  • \$\begingroup\$ Accept the arguments as a list (allowed) for a byte \$\endgroup\$ Commented Nov 26, 2016 at 2:40
  • \$\begingroup\$ I always get confused if (.) is composed with other functions :p \$\endgroup\$
    – tomsmeding
    Commented Nov 26, 2016 at 15:30
  • \$\begingroup\$ g x=(`take`f)where doesn't save a byte :-/ \$\endgroup\$
    – Bergi
    Commented Nov 26, 2016 at 16:27
  • \$\begingroup\$ Save 2 bytes in the alternative approach: (h%g)y x=x:g(h x y)y \$\endgroup\$
    – Zgarb
    Commented Nov 28, 2016 at 18:16
  • \$\begingroup\$ @Zgarb: oh, that's nice. Thanks! BTW, when editing in your suggestions I found 4 bytes to save along the way in the first version. \$\endgroup\$
    – nimi
    Commented Nov 28, 2016 at 18:47
6
\$\begingroup\$

ES6 (Javascript), 79, 67, 65 bytes

UPDATE

  • minus 2 bytes, by starting with i=2, as suggested by @ETHProductions
  • Saved 3 bytes, thanks to excellent advice from @Neil !

Golfed

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

Test

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, ...]
\$\endgroup\$
9
  • 1
    \$\begingroup\$ Can you not use ++i to avoid having to add 1 to i twice? \$\endgroup\$
    – Neil
    Commented Nov 26, 2016 at 0:03
  • 1
    \$\begingroup\$ Or, alternatively, writing ?S(n,a,i+1,a.push(...)):a might save you some bytes. \$\endgroup\$
    – Neil
    Commented Nov 26, 2016 at 0:05
  • 1
    \$\begingroup\$ Or maybe you could use the fact that a.push returns the new length, S=(n,a,i=2)=>i<n?S(n,a,a.push(...)):a \$\endgroup\$
    – Neil
    Commented Nov 26, 2016 at 0:06
  • 1
    \$\begingroup\$ I still think you can save more bytes by starting at i=2 though. \$\endgroup\$
    – Neil
    Commented Nov 26, 2016 at 0:48
  • 1
    \$\begingroup\$ With Neil's suggestion, I think you can do S=(n,a,i=2)=>i<n?S(n,a,a.push(eval(a[i-2]+"+*-/"[i%4]+a[i-1]))):a to save 2 bytes. \$\endgroup\$ Commented Nov 26, 2016 at 4:00
5
\$\begingroup\$

Python 3, 90 80 74 bytes

xnor's probably going to come and destroy this solution...

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

The function modifies the list passed to it. Use like this:

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

Try on repl.it!

-6 bytes thanks to Copper

\$\endgroup\$
7
  • \$\begingroup\$ Since you only use O once, you can save a few bytes by doing '-/+*'[i%4] and removing the declaration of O. Also, you might be able to get around the repeated calls to str by doing something like eval('%s'*3%(s[-2],'-/+*'[i%4],s[-1])). \$\endgroup\$
    – Copper
    Commented Nov 25, 2016 at 23:08
  • \$\begingroup\$ Oh yeah, and s+=[...] can be replaced by s+=..., (note the trailing comma). \$\endgroup\$
    – Copper
    Commented Nov 25, 2016 at 23:12
  • \$\begingroup\$ xnor is not the only one that can destroy your solution. There is another person too: Dennis (the mod). \$\endgroup\$ Commented Nov 26, 2016 at 9:04
  • \$\begingroup\$ You're guaranteed to get i as input, so you don't need the default value for it (i=2 can be just i). Two bytes off. \$\endgroup\$
    – ArtOfCode
    Commented Nov 26, 2016 at 14:24
  • 1
    \$\begingroup\$ If it was allowed to return the nth item in the sequence instead, this is 1 byte shorter with recursion: f=lambda x,n:n<2and x[n-1]or eval('%s'*3%(f(x,n-2),'*-/+'[n%4],f(x,n-1))) \$\endgroup\$
    – mbomb007
    Commented Dec 12, 2016 at 22:26
5
\$\begingroup\$

Perl 6,  75 71  61 bytes

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

Test it

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

Test it

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

Test it

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

  ]
}
\$\endgroup\$
4
\$\begingroup\$

Mathematica, 68 bytes

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

Barely snuck into 3rd place! Unnamed function of three arguments, which uses a helper unary operator ± such that ±n is exactly the nth element x(n) of the Stewie sequence. The first two arguments are x(1) and x(2), and the third argument is the N indicating which x(N) we output.

Direct implementation, using a mod-4 calculation to choose which binary function to apply to the previous two terms. Picking the correct binary function, which is what 1##[#-#2,#/#2,+##] helps with, uses a few of these fun Mathematica golfing tricks.

\$\endgroup\$
4
\$\begingroup\$

x86-64 machine code, 34 bytes

Calling convention = x86-64 System V x32 ABI (register args with 32-bit pointers in long mode).

The function signature is void stewie_x87_1reg(float *seq_buf, unsigned Nterms);. The function receives the x0 and x1 seed values in the first two elements of the array, and extends the sequence out to at least N more elements. The buffer must be padded out to 2 + N-rounded-up-to-next-multiple-of-4. (i.e. 2 + ((N+3)&~3), or just N+5).

Requiring padded buffers is normal in assembly for high-performance or SIMD-vectorized functions, and this unrolled loop is similar, so I don't think it's bending the rules too far. The caller can easily (and should) ignore all the padding elements.

Passing x0 and x1 as a function arg not already in the buffer would cost us only 3 bytes (for a movlps [rdi], xmm0 or movups [rdi], xmm0), although this would be a non-standard calling convention since System V passes struct{ float x,y; }; in two separate XMM registers.

This is objdump -drw -Mintel output with a bit of formatting to add comments

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

This C reference implementation compiles (with gcc -Os) to somewhat similar code. gcc picks the same strategy I did, of keeping just one previous value in a register.

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

I did experiment with other ways, including a two-register x87 version that has code like:

; 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

You'd do it this way if you were going for speed (and SSE wasn't available)

Putting the loads from memory inside the loop instead of once on entry might have helped, since we could just store the sub and div results out of order, but still it needs two FLD instructions to set up the stack on entry.

I also tried using SSE/AVX scalar math (starting with values in xmm0 and xmm1), but the larger instruction size is killer. Using addps (since that's 1B shorter than addss) helps a tiny bit. I used AVX VEX-prefixes for non-commutative instructions, since VSUBSS is only one byte longer than SUBPS (and the same length as 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

Tested with this test-harness:

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

Compile with nasm -felfx32 -Worphan-labels -gdwarf2 golf-stewie-sequence.asm &&
gcc -mx32 -o stewie -Og -g golf-stewie-sequence.c golf-stewie-sequence.o

Run the first test-case with ./stewie 8 1 3

If you don't have x32 libraries installed, use nasm -felf64 and leave gcc using the default -m64. I used malloc instead of float seqbuf[seqlen+8] (on the stack) to get a low address without having to actually build as x32.


Fun fact: YASM has a bug: it uses a rel32 jcc for the loop branch, when the branch target has the same address as a global symbol.

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

assembles to ... 11f: 0f 8f db ff ff ff jg 100 <stewie_x87_1reg>

\$\endgroup\$
6
  • \$\begingroup\$ Very nice! You beat me to a similar approach by over three years! The problem seemed to lend itself nicely to x87 stack-based operations. \$\endgroup\$
    – 640KB
    Commented Jan 5, 2020 at 16:24
  • \$\begingroup\$ @640KB: yeah, the r forms of non-commutative operations make the stack nature of x87 bearable. IDK about "nicely"; making it small introduced a bunch of store/reloads instead of just reading both previous sequence values from registers like we can with the AVX version. \$\endgroup\$ Commented Jan 5, 2020 at 16:34
  • \$\begingroup\$ Fair enough, "nicely" is probably putting it nicely. I didn't get very far since I saw your answer before I even started. If I'm reading it right it looks like this will always run through the +,*,-,/ pattern before stopping. Will it handle the N=5 / division by 0 test case? \$\endgroup\$
    – 640KB
    Commented Jan 5, 2020 at 17:04
  • \$\begingroup\$ @640KB: fdiv doesn't trap on division by zero with the default FP environment, merely produce a NaN. It's been 3 years since I looked at this, but presumably that was fine. (By default after finit, FP exceptions are masked. Mainstream OSes / C implementations use that same x87 environment by default). \$\endgroup\$ Commented Jan 5, 2020 at 17:40
  • \$\begingroup\$ Of course! If an exception falls in the woods, does anyone hear it? :) \$\endgroup\$
    – 640KB
    Commented Jan 5, 2020 at 19:05
3
\$\begingroup\$

MATL, 19 18 17 bytes

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

Input is in the format: N (0-based), x(1), x(2) (as strings); all separated by newlines.

Try it online! Or verify all test cases (slightly modified code; output sequences separated by a blank line).

Explanation

MATL doesn't have a proper eval function, but U (str2num) can evaluate numeric expressions with infix operators.

Each new term is computed and pushed onto the stack, keeping the previous terms. The entire stack is printed at the end.

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
\$\endgroup\$
3
\$\begingroup\$

05AB1E, 21 19 18 bytes

Input is taken in the order N(0-based), x(2), x(1).
Saved 1 byte thanks to carusocomputing.

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

Try it online!

Explanation

 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

We iteratively build the stack with the latest element in the sequence on top, while keeping all previous elements in order.
Then we wrap the stack in a list at the end to display all values at once.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I couldn't figure it out, but using XY and UV may save you bytes. \$\endgroup\$ Commented Nov 28, 2016 at 17:14
  • 1
    \$\begingroup\$ @carusocomputing: Nice catch! Saved the byte I lost from the register not working on implicit input using UX :) \$\endgroup\$
    – Emigna
    Commented Nov 28, 2016 at 18:11
3
\$\begingroup\$

Haskell, 60 bytes

g(o:z)a b=a:g z b(o a b)
p=(+):(*):(-):(/):p
(.g p).(.).take

Try it online!

Ungolfed:

ungolfed :: Int -> Double -> Double -> [Double]                                
ungolfed len x1 x2 = take len $ go (cycle [(+),(*),(-),(/)]) x1 x2
    where go (f:fs) x y = x : go fs y (f x y)

Knowing \x -> f x == f, \x -> f $ g x == f . g, and some other patterns, you can transform a normal (point-full) function into a point-free one:

f0 len x1 x2 = take len $ go p x1 x2
f1 len = \x1 x2 -> take len $ go p x1 x2
f2 len = \x1 -> take len . go p x1
f3 len = (take len .) . go p
f4 = \len -> (. go p) (take len .)
f5 = \len -> (. go p) ((.) (take len))
f6 = \len -> (. go p) . (.) $ take len
f7 = \len -> ((. go p) . (.) . take) len
f8 = (. go p) . (.) . take

\x y -> f $ g x y == (f.) . g is also a common pattern.

You could also read this backwards for adding back arguments to a point-free function.

\$\endgroup\$
2
  • \$\begingroup\$ Welcome to PPCG and nice first answer! I'd appreciate an explanation of the decomposition of (.g p).(.).take into take len $ go p x1 x2 \$\endgroup\$
    – user41805
    Commented Jan 7, 2020 at 17:20
  • \$\begingroup\$ @KritixiLithos To be honest, I used pointfree.io, but I've worked it out and added the transformation from point-full to point-free. Hopefully it's clear (and correct) enough. \$\endgroup\$
    – Trioct
    Commented Jan 8, 2020 at 1:08
2
\$\begingroup\$

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

Not really competitive, but I like how it is is expressed quite naturally:

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

We ignore errors when computing R, which makes R (and then B) possibly take the NIL value. That allows to output the current result even if the next value is undefined. Then, eventually the loop will fail, but that's within the rules.

Tests

We name the function F and verify that the expected values are approximately equal to the tested one.

(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

The reason for the approximate test is because the computed values are a little more precise than required; here, for (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)
\$\endgroup\$
2
\$\begingroup\$

dc, 112 110 108 bytes

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

Sometimes dc answers can be super long, and sometimes they can be super short. It all just depends on the challenge at hand as is the case with many other languages. Anyways, this prompts for a space-separated one-indexed command line input of 3 integers, x(1), x(2), N, upon invocation, and outputs each element of the sequence on separate lines with non-integer outputs containing 5 digits after the decimal point.

For example, the input 6 3 25 results in the following output:

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
\$\endgroup\$
2
\$\begingroup\$

Perl, 62 + 3 (-pla flag) = 65 bytes

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

Using:

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

05AB1E, 12 bytes

λ£"-/+*"Nè.V

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Bash, 224 bytes (NO CONTEST)

A tremendously large implementation in BASH.

Takes the task quite literally, and does everything in one continuous pipe, w/o any unholy control flow structures or recursion.

Input

$1,$2 - initial elements

$3 - target sequence size

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

Less 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

Test

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

Pipeline Stages

Generate a table of element indices + op, for an each output sequence element (one per line):

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

Use sed to convert this into a linear bc program:

...
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];
...

feed this to bc and let it do all the job

\$\endgroup\$
1
\$\begingroup\$

Ruby, 79 bytes

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

I suspect this is very far off from optimal (and I haven't looked at the other answers yet), but it's fun nonetheless.

I wanted to have some fun with Enumerable#cycle, but sadly, it's 4 fewer characters to just use %4.

\$\endgroup\$
1
\$\begingroup\$

C++14, 118 bytes

[](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);}

As unnamed lambda modifying its input. Requires v to be a vector<double> or vector<float>.

Ungolfed and usage:

#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";
}
\$\endgroup\$
1
\$\begingroup\$

Japt, 20 bytes

@OxVs2n)q"-/+*"gY}hV

Try it

\$\endgroup\$
1
\$\begingroup\$

PowerShell, 66 60 58 bytes

-8 bytes thanks to mazzy

param($a,$b)3..$a|%{$b+=$b[-2,-1]-join"*-/+"[$_%4]|iex}
$b

Try it online!

Builds x(n) in place by making a string out of x(n-2) and x(n-1), joined by the operator we need (determined by modulo math using the index we get for free from iterating up), and feeds it into invokeExpression. We then spit out the final array.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ nice! $b is array, so you don't need brackets ,(...). Try it online! \$\endgroup\$
    – mazzy
    Commented Jan 7, 2020 at 18:49
  • \$\begingroup\$ @mazzy Ah, cheers. Smart move on the join as well. \$\endgroup\$
    – Veskah
    Commented Jan 7, 2020 at 18:54
  • 1
    \$\begingroup\$ also we can remove ++ Try it online! \$\endgroup\$
    – mazzy
    Commented Jan 7, 2020 at 19:04
  • 1
    \$\begingroup\$ @mazzy Oh yeah, guess we do already have something counting up. Nice \$\endgroup\$
    – Veskah
    Commented Jan 7, 2020 at 19:12
1
\$\begingroup\$

J, 49 33 29 bytes

[$_2&(],(-,%,+,*)/@{.{~4|#@])

Try it online!

-4 bytes thanks to FrownFrog

\$\endgroup\$
2
  • \$\begingroup\$ [$_2&(],(-,%,+,*)/@{.{~4|#@]) \$\endgroup\$
    – FrownyFrog
    Commented Jan 8, 2020 at 6:39
  • \$\begingroup\$ Tyvm! I always forget about that little trick with Bond. \$\endgroup\$
    – Jonah
    Commented Jan 8, 2020 at 19:02
0
\$\begingroup\$

Pyth - 20 bytes

Outputting all n costs me.

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

Doesn't work online cuz of eval.

\$\endgroup\$
0
\$\begingroup\$

Ceylon, 195 bytes

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;

Formatted and commented:

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

Example usage:

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

Example output:

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

The second example shows how this would handle division by zero. The last example shows that the results deviate a bit depending on which kind of arithmetic (and rounding) one is using ... I think Ceylon's 64 bit floating point arithmetic is a bit nearer to what it should be than what was posted in the question.

\$\endgroup\$
0
\$\begingroup\$

Clojure, 99 bytes

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

This version is nicer to use in practice but has 110 bytes:

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

I had trouble fuzing iterated function and a cyclical sequence of operations so I had to use a counter instead. Also tried using a FSM transition table like {+ * * - - / / +} but I couldn't squeeze it to less code.

Could be expressed as an anonymous function

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

Must be called with floats like (f 6.0 3.0 25) as otherwise you get rational numbers out. Alternatively the iteration could be started from [a (float b) 0] which brings some extra characters.

\$\endgroup\$
0
\$\begingroup\$

Octave, 91 bytes

@(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'

Try it online!

Some golfs:

  • No parentheses for the first eval call
  • No concatenations for the first eval call
  • Inline assignment of *-/+ (not possible in MATLAB)
  • Combined ' and " to avoid escaping the apostrophes (not possible in MATLAB)
  • Storing n=@num2str since it's used twice (not possible in MATLAB)
\$\endgroup\$
0
\$\begingroup\$

cQuents, 19 bytes

=A,B&Y+Z,YZ,Y-Z,Y/Z

Try it online!

Explanation

Receives three inputs, A B n

=A,B                   first two terms in sequence are A and B
    &                  output first n terms of sequence
     Y+Z,YZ,Y-Z,Y/Z    next terms are Y+Z, then Y*Z, ..., cycling back to beginning after 4th
                       Y and Z are the previous two terms in the sequence
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.