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
asked Nov 25, 2016 at 22:25
\$\endgroup\$
7
  • \$\begingroup\$ Can a function take x(1) and x(2) as a list? Or seperate arguments? \$\endgroup\$ 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\$ 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\$ 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.

answered Nov 25, 2016 at 23:30
\$\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\$ Commented Nov 26, 2016 at 15:30
  • \$\begingroup\$ g x=(`take`f)where doesn't save a byte :-/ \$\endgroup\$ 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\$ 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\$ 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, ...]
answered Nov 25, 2016 at 23:02
\$\endgroup\$
9
  • 1
    \$\begingroup\$ Can you not use ++i to avoid having to add 1 to i twice? \$\endgroup\$ 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\$ 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\$ Commented Nov 26, 2016 at 0:06
  • 1
    \$\begingroup\$ I still think you can save more bytes by starting at i=2 though. \$\endgroup\$ 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

answered Nov 25, 2016 at 22:39
\$\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\$ Commented Nov 25, 2016 at 23:08
  • \$\begingroup\$ Oh yeah, and s+=[...] can be replaced by s+=..., (note the trailing comma). \$\endgroup\$ 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\$ 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\$ 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
 ]
}
answered Nov 25, 2016 at 23:25
\$\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.

answered Nov 26, 2016 at 0:04
\$\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>

answered Dec 9, 2016 at 20:02
\$\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\$ 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\$ 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\$ 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
answered Nov 25, 2016 at 22:45
\$\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.

answered Nov 25, 2016 at 22:32
\$\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\$ 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.

answered Jan 5, 2020 at 7:10
\$\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\$ 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\$ 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)
answered Nov 26, 2016 at 9:29
\$\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
answered Nov 26, 2016 at 20:48
\$\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'
answered Nov 27, 2016 at 11:51
\$\endgroup\$
2
\$\begingroup\$

05AB1E, 12 bytes

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

Try it online!

answered Nov 22, 2019 at 16:13
\$\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円]3円a[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円]3円a[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

answered Nov 26, 2016 at 20:54
\$\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";
}
answered Nov 28, 2016 at 18:34
\$\endgroup\$
1
\$\begingroup\$

Japt, 20 bytes

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

Try it

answered Nov 22, 2019 at 16:47
\$\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.

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

J, (削除) 49 (削除ここまで) (削除) 33 (削除ここまで) 29 bytes

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

Try it online!

-4 bytes thanks to FrownFrog

answered Jan 5, 2020 at 0:52
\$\endgroup\$
2
  • \$\begingroup\$ [$_2&(],(-,%,+,*)/@{.{~4|#@]) \$\endgroup\$ Commented Jan 8, 2020 at 6:39
  • \$\begingroup\$ Tyvm! I always forget about that little trick with Bond. \$\endgroup\$ 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.

answered Nov 26, 2016 at 21:50
\$\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.

answered Nov 27, 2016 at 14:21
\$\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.

answered Dec 12, 2016 at 18:43
\$\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)
answered Nov 26, 2019 at 10:23
\$\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
answered Jan 7, 2020 at 16:22
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.