# Print the sequence

## 21, 21, 23, 20, 5, 25, 31, 24, ?

Inspired by this Puzzle, given an integer $$\n>0\$$ , print out the following sequence until you reach a non-Integer (spoilered, in case you want to solve the puzzle yourself first)

$$\a_0 = n\$$
$$\a_{4k+1} = a_{4k} \cdot(4k+1) \$$
$$\a_{4k+2} = a_{4k+1} + (4k+2)\$$
$$\a_{4k+3} = a_{4k+2} - (4k+3)\$$
$$\a_{4k+4} = a_{4k+3} / (4k+4)\$$
or more intuitively: *1, +2, -3, /4, *5, +6, -7, /8, ...

TestCases:

1: 1, 1, 3, 0, 0, 0, 6, -1
2: 2, 2, 4, 1
3: 3, 3, 5, 2
4: 4, 4, 6, 3
5: 5, 5, 7, 4, 1, 5, 11, 4
6: 6, 6, 8, 5
9: 9, 9, 11, 8, 2, 10, 16, 9
21: 21, 21, 23, 20, 5, 25, 31, 24, 3, 27, 37, 26

Input and Output may be taken in any reasonable format, standard loopholes are as forbidden as usual.

In the spirit of , the shortest answer in byte wins!

• May we instead return an infinite list of the sequence? Also, is the output for 1 correct? I had something different after the 6. – cole Oct 2 '19 at 6:11
• @cole Since the sequence ends I don't think you can output an infinite list. – Wheat Wizard Oct 2 '19 at 6:13
• May we output 1 indexed, i.e. skip the first element? – Jo King Oct 2 '19 at 6:19
• No, the entire sequence must be printed. – infinitezero Oct 2 '19 at 6:20
• Yes you may @KevinCruijssen – infinitezero Oct 2 '19 at 12:05

# 05AB1E (legacy), 18 17 bytes

[N"/*+-"Nè.VÐïÊ#=


Explanation:

[                # Start an infinite loop:
N               #  Push the 0-based loop-index
"/*+-"         #  Push string "/*+-"
Nè       #  Index into this string with the loop-index
.V     #  And use a 05AB1E-eval to calculate the next number
Ð               #  Triplicate this number
ï              #  Cast it to an integer
Ê             #  And if it's NOT equal to the number we triplicated:
#            #   Stop the infinite loop
=              #  Print the number without popping


I'm using the legacy version of 05AB1E here, and also first calculate the next number before printing it, because the loop is 0-based and it will do a /0 in the very first iteration. This saved a byte in comparison to the previous N> and "*+-/". This only works, because in the legacy version a number that's being divided by 0 remains the same; whereas in the new version it would become 0; and in actual math it would give a division by zero error.

# Scratch 3.0 39 blocks/323 bytes

Try it online scratch!

Alternatively, as SB syntax:

when gf clicked
delete[all v]of[o v
set[n v]to(1
repeat until<(n)contains[.
if<((n)mod(4))=(0
set[. v]to((. )*(n
else
if<((n)mod(4))=(1
change[. v]by(n
else
if<((n)mod(4))=(2
change[. v]by((0)-(n
else
set[. v]to((. )/(n
end
end
end
change[n v]by(1
end
delete(length of(o))of[o v


Look at you guys, having fun with your fancy eval statements! Well, not me! No... Scratch doesn't have evals, so I had to do things the hard way... if statements.

At least it isn't gotos...

• Look at you, having fun with if statements and float division! Well, not me! No... Whitespace doesn't have evals, if-statement, or float-division, so I had to do things the hard way... gotos and a subtraction loop to verify if we can divide, in a stack-based language. ;p (In all seriousness, nice answer, +1 from me! I just couldn't resist quoting you in my just finished Whitespace answer.) – Kevin Cruijssen Oct 2 '19 at 11:35

# Whitespace, 251227 202 bytes

[S S S N
_Push_0][S N
S _Duplicate_0][S N
S _Duplicate_0][T   N
T   T   _Read_STDIN_as_integer][T   T   T   _Retrieve_input][N
S S N
_Create_Label_LOOP][S N
S _Duplicate_top][T N
S T _Print_as_integer][S S S T  S T S N
_Push_10_newline][T N
S S _Print_as_character][S N
T   _Swap_top_two][S S S T  N
_Push_1][T  S S S _Add][S T S S T   N
_Copy_2nd_item][S T S S T   N
_Copy_2nd_item][S N
S _Duplicate_top][S S S T   S S N
_Push_4][T  S T T   _Modulo][S N
S _Duplicate_top][N
T   S S N
_If_0_Jump_to_Label_DIVIDE][S S S T N
_Push_1][T  S S T   _Subtract][S N
S _Duplicate_top][N
T   S T N
_If_0_Jump_to_Label_MULTIPLY][S S S T   N
_Push_1][T  S S T   _Subtract][N
T   S S S N
T   _Swap_top_two][S T  S S T   N
_Copy_2nd_item][T   S S T   _Subtract][N
S N
N
_Jump_to_LOOP][N
S S S N
_Create_Label_DIVIDE][S N
N
_Discard_top][T S T S _Divide][S T  S S T   S N
_Copy_3nd_item][S T S S T   S N
_Copy_3nd_item][T   S T T   _Modulo][N
T   S N
_If_0_Jump_to_Label_LOOP][N
N
N
_Exit_Program][N
S S T   N
_Create_Label_MULTIPLY][S N
N
_Multiply][N
S N
N
_Jump_to_Label_LOOP][N
S S S S N
S N
N
_Jump_to_Label_LOOP]


Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.

Try it online (with raw spaces, tabs and new-lines only).

-24 bytes after a comment of @JoKing suggesting n%i > 0. Although only if(x < 0) and if(x == 0) are available in Whitespace, simply checking if(x*-1 < 0) is basically the same as if(x > 0).
An additional -25 bytes thanks to @JoKing.

Explanation:

At least it isn't gotos...

Did someone say goto? Whitespace has nothing else than goto to create both loops and if-statements. xD In addition it's a stack-based language, so I have to swap/discard/copy pretty often. And to top things off: Whitespace doesn't even have floating points and only integer-division, so I've used n % i * -1 < 0 to exit the program if the integer cannot divide the current number.

Pseudo-code:

Integer n = STDIN as input
Integer i = 0
Label LOOP:
Print n as number
i = i + 1
Integer t = i % 4
If(t == 0):
t = t - 1
If(t == 0):
t = t - 1
If(t == 0):
n = n - i
Label DIVIDE:
n = n / i
Integer m = n % i
If(m == 0):
Exit program
Label MULTIPLY:
n = n * i
n = n + i

• You absolute genius. Have my upvote! – Lyxal Oct 2 '19 at 11:51
• @JoKing Whitespace only has if(n == 0) or if(n < 0) available. Unfortunately no if(n > 0) or if(n != 0). But I'm sure some aspects can be simplified. This current solution was a trial-and-error of debugging, but maybe I should just take a step back and rethink a shorter approach. When I have time again. And fixed the pseudo-code, you were indeed right I switched i/n at most places.. – Kevin Cruijssen Oct 2 '19 at 12:08
• @JoKing I'm an idiot.. >.> I could just add a * -1 and then use the x < 0 check. Thanks for -24 bytes. Pretty ironic I can think more straight late in the evening than when I am at work.. ;) – Kevin Cruijssen Oct 2 '19 at 20:40
• @JoKing Thanks, both those suggestions saved bytes. The first suggestion is -7, and the second -18. :) – Kevin Cruijssen Oct 3 '19 at 6:47

# Haskell, 75 74 73 bytes

-1 byte thanks to Will Ness -1 byte thanks to nimi

(#1)
n#i|imod4<1,nmodi>0=[n]|y<-i+1=n:(x!!i)n i#y
x=div:(*):(+):(-):x


Try it online!

Avoids the use of fractional ints to save on bytes

• – Will Ness Oct 5 '19 at 8:01
• 1 less – nimi Oct 11 '19 at 5:31

# JavaScript (V8), 52 bytes

Prints groups of 4 terms. Inspired by GB's Ruby answer.

n=>{for(k=0;n%1==0;n/=k+=3)print(n,n*=++k,n-~k,--n)}


Try it online!

# JavaScript (V8), 54 bytes

Prints the terms of the sequence.

n=>{for(k=0;n%1==0;n=eval(n+'*+-/'[k++&3]+k))print(n)}


Try it online!

# JavaScript (ES6),  59  58 bytes

Returns an array.

f=(n,k)=>k&&(n=eval(n+'/*+-'[k&3]+k))%1?[]:[n,...f(n,-~k)]


Try it online!

# Piet, 297190 144 codels (432 bytes)

Tried a new approach using a pointer command as switch(k mod 4) to unify the output code, resulting in a denser 10x19 code picture. Then I golfed that down by 1 row and 2 collumns to 8x18.

Here is a trace, to see how it works:

The first line pushes a 0 on the stack as starting index (since we can only push natural numbers, we push 2 ones and then substract), then reads the input as number.

The leftmost collumn has the shared code of duplicating the number and popping one into output, then moving the index on top of the stack, incrementing it and then duplicating it thrice. We then enter the pastel red r-shaped block through the dark cyan codel for a pointer command which gives us different paths for the remainder of our index mod 4.

Mod 1, we exit through the top to multiply. We first shuffle a copy of our index down for later, then perform the multiplication. After passing through the white for a noop, we enter the collumn above to fix the cc parity (it needs to be flipped an even number of times to keep the loop stable), followed by a pointer (1) from entering the magenta bar: It acts as a catch for our four paths and send us back into the loop.

Mod 2, we exit backwards to sum. The shape of the pastel code block means we exit a row above from where we entered, and we use the 3 we push onto the stack by exiting through the red codel to pointer (3) ourselves upwards. This collumns has the white space before the arithmetic and a slightly different order of pushing and switching cc, because otherwise we would have colour overlap with integer-valued codels in the neighbouring collumn.

Mod 3 send us downwards for subtraction. Same deal as multiplication, except we cross over the division path on the way up (As the cc has differing parity when entering the pastel green bar, the two executions exit that bar at different ends). While doing so, we pick up an unwanted duplicate command, so we pop it back off with the dark green codel before entering the cc correction and collection bar.

Mod 4, we go straight ahead to divide. Here, we first have to re-shuffle the stack more severely to get two pairs of n and a to perform operations on, because we need to test if it's integer. We do that my doing mod on the first pair, then not on the result, then use that for a pointer - if it's not divisible, we keep going straight, which sends us with two pointer commands into the opposite corner into the inescapable block and thus ends program. Otherwise, we turn right and get a divide command from entering the magenta bar.

### Old Version

Very straightforward code: Pushes a 1 and the input on the stack, then loops through the four operations by: Shuffling the index on top of the stack, incrementing it by 1, duplicating it, shuffling one copy back down, performing the arithmetic operation, duplicating the number and popping one into output.

For division, which is the only one where the sequence can end, it creates a more complicated stack to first check if n mod index == 0, otherwise it enters the inescapable codel and terminates. Otherwise, it uses its second copy of i and n to perform the division.

• Would it be possible to mush the second and third row together? I.e., pivot the pink cell at (0,1) -> (1,2), shift the 3 cells in the middle down, and shrink the right column to a 1x2? – Veskah Oct 7 '19 at 15:27
• Not easily. I need 2 cells to execute the right turn, either for a push (1) pointer or for a black cell on top of a coloured one. – AlienAtSystem Oct 7 '19 at 16:06

# Perl 6, 44 bytes

{$_,{($_,<* + - />[$++%4]~++$).EVAL}...^*%1}


Try it online!

Anonymous code block that takes a number and returns a sequence. If we could skip the first element (which is always the same as the second element anyway), we could save 3 bytes by removing the $_, # Python 3, 60 bytes f=lambda n,i=1:[]if n%1else[n]+f([n/i,n*i,n+i,n-i][i%4],i+1)  Try it online! # C# (Visual C# Interactive Compiler), 72, 70, 69 bytes n=>{for(int i=1;n%1==0;n=new[]{n/i,n*i,n+i,n-i}[i++%4])Write(n+" ");}  Try it online! • 59 bytes by porting Arnauld's first JavaScript function, which is a port of the Ruby answer. And yes, this output is allowed, just got confirmation from OP in the comments of the challenge. – Kevin Cruijssen Oct 2 '19 at 12:10 • @KevinCruijssen nice, I wouldn't have come up with that! – Innat3 Oct 2 '19 at 13:21 # Ruby, 56 54 52 bytes f=->n,z=1{n%1>0?[]:[n,n*=z,n-~z,n-=1]+f[n/=z+3,z+4]}  Try it online! After some (failed) attempt with eval, I found out that the happiest solution is building the array with 4 elements at once, at least in ruby. Thanks to Arnauld for -2 bytes. • 53 bytes by porting back my last answer, which was inspired by yours. – Arnauld Oct 2 '19 at 8:14 • 52 bytes by using an improvement suggested by Shaggy that turned out to be just as long in JS but saves a byte in Ruby. – Arnauld Oct 2 '19 at 9:22 # R, 90 bytes, 87 bytes 85 bytes 80 bytes 7473 bytes A plain implementation of the rules: a=scan();while(T<13)a=c(a,d<-a[T]*T,d+T+1,e<-d-1,e/((T<-T+4)-1));a[!a%%1]  Try it online! with the T<13 following from a deeper analysis of the puzzle. Indeed there are only three kinds of sequences: those of length 4, when a⁰ is not congruent to 1 modulo 8; those of length 12 when a⁰ is congruent to 21 modulo 32; and those of length 8 for the remaining cases. An alternative code avoiding loops ends up being longer with 87 bytes: ~=rep;b=(scan()-1)*c(32~4,8,40~3,1,9~3)/32+c(1,1,3,0~3,6,-c(8,1,9,-71,17)/8);b[!b%%1]  Try it online! • You can remove the {} for -2 bytes. – Robin Ryder Oct 9 '19 at 14:01 • 74 bytes by avoiding length. – Robin Ryder Oct 9 '19 at 14:04 # Haskell, 10486 85 bytes n#i=n:(cycle[(/),(*),(+),(-)]!!floor i)n i#(i+1) takeWhile((==).ceiling<*>floor).(#1)  Try it online! The h= can be omitted since it's only used for testing. Ah, code golf, where a quadratic increase in time complexity is worth it for the reduction of one character. # 104 bytes f=flip g x=scanl(f($))x.zipWith(f($))[1..].cycle$f<$>[(*),(+),(-),(/)] takeWhile((==).ceiling<*>floor).g  Try it online! I like this answer better, but alas it is longer. # Japt, 25 24 bytes Another adaptation of GB's Ruby solution. %1ª[UU*=°VU´ÒVU]cßU/=V±3  Try it The main trick here is in the overloading of the c method for arrays. Pass it another array as an argument and it concatenates it to the original array. Pass it a number as an argument, as happens on the last recursive call, and it flattens the original array by that many levels - 1 in this case, after rounding. But, as the array is only ever one level deep, flattening it has no effect. %1ª[UU*=°VU´ÒVU]cßU/=V±3 :Implicit input of integer U %1 :U modulo 1 ª :Logical OR with [ :Construct and array containing U : U U*= : U multiplied by °V : V (initially 0) prefix incremented U´ : The new value of U, postfix decremented ÒV : Subtract the bitwise negation of V U : The now-decrmented U ] :End array c :Concatenate, or flatten by ß : Recursive call to the programme with argument U/= : U divided by V±3 : V incremented by 3  # Java 8, 84 bytes n->{for(int i=1;n%1==0;n=new float[]{n/i,n*i,n+i,n-i}[i++%4])System.out.println(n);}  Try it online. Creating an array with all four values is inspired by @GB's Ruby answer, although I now notice that using a ternary if-statement is the same amount of bytes: n->{for(int i=0;n%1==0;n=++i%4<1?n/i:i%4<2?n*i:i%4<3?n+i:n-i)System.out.println(n);}  Try it online. # Perl 5, 53 bytes @a=qw(/ * + -);say,eval"\$_$a[++$i%4]=$i"while$_==int


Try it online!

# Red, 102 bytes

func[n][k: m: 0 until[foreach o[* + - /][print n t: n
n: do reduce[n o m: m + 1]]k: k + 1 t % m <> 0]]


Try it online!

{n=$1;for(k=1;n%1==0;n/=k++)print n,n*=k++,n+=k++,n-=k++}  Try it online! # Rutger, 310 bytes n=e=$Input;
a=0;
w=While[{m=Modulo[$e];Not[m[1]];}]; w=w[{f=For[4];f=f[@x];f=f[{Print[$e];q=Equal[$x];i=If[{q[1];}];i=i[{k=Times[$e];}];Do[$i];i=If[{q[2];}];i=i[{k=Add[$e];}];Do[$i];i=If[{q[3];}];i=i[{k=Subtract[$e];}];Do[$i];i=If[{q[4];}];i=i[{k=Divide[$e];}];Do[$i];e=k[a=Increment[$a]];}];Do[$f];}]; Do[$w];


Try it online!

It's about time I used Rutger again. Unfortunately, it may not be the best language for the task, as it has no form of eval, forcing me to use four if statements

## How it works

### How Rutger works

A brief foreword on how the language works: Everything is either an assignment or a function, and every function takes exactly one argument. For operations that require more than one argument (e.g. multiplication), the first call returns a partial function, that, when called again with the second argument, returns the expected result. For example:

left = Times[5];
Print[left[6]];


will print out 30: Try it online!. While usually this is longer than the usual alternative, it can at times save bytes, if a function is called repeatedly with one constant argument, and one changing argument, for instance when printing out times tables.

This one argument rule applies to everything that isn't a constant or a variable, including loops and conditionals. However, loops and conditionals (For, Each, While, DoWhile, If and IfElse) are doable, meaning that in order to actually run them, the Do function must be called (see the last line in the answer). Again, this can save bytes when repeatedly running the same loop, or allow you to run arbitrary code between the definition and running of loops.

Finally, there are three ways of referring to variables, all of which are used in this program. The first is direct referencing, where the variable name is prefixed with a $ symbol. This accesses the value of the variable directly and returns it. The second is functional referencing, which doesn't have a prefixing character. This allows the code to distinguish between (potentially partial) functions assigned to variables, and actual variables containing a specific value. Finally, indirect referencing, prefixed with an @ symbol, creates a variable (if it doesn't already exist) and returns the variable object within a given scope. This allows you to create a loop variable (e.g. i in for i in range(...)). ### How the actual solution works Here is the ungolfed code: n = elem =$Input;
var = 0;
while = While[{
mod = Modulo[$elem]; Not[mod[1]]; }]; while = while[{ for = For[4]; for = for[@index]; for = for[{ Print[$elem];
equal = Equal[$index]; if = If[{ equal[1]; }]; if = if[{ func = Times[$elem]; }];
Do[$if]; if = If[{ equal[2];}]; if = if[{ func = Add[$elem];}];
Do[$if]; if = If[{ equal[3];}]; if = if[{ func = Subtract[$elem];}];
Do[$if]; if=If[{ equal[4];}]; if=if[{ func = Divide[$elem];}];
Do[$if]; elem = func[var = Increment[$var]];
}];
Do[$for]; }]; Do[$while];


Try it online!

As you can see, it starts by assigning the three variables n, e and a, which represent the input, the changing element in the sequence, and the modification number for each new element respectively. We then create a while loop:

w=While[{m=Modulo[$e];Not[m[1]];}];  The braces ({ and }) define a block of code, where the final statement in the block is the condition for the while loop. In this case, we start by defining a partial modulo function, which will take in a second argument m, and return e % m. We then call this partial function with $$\1\$$ as its second argument, returning $$\0\$$ for integers and a non-zero integer for floats. We then calculate the logical not of this, mapping $$\0 \to 1\$$ and $$\n \to 0, n \ne 0\$$. Next we come to the absolute monstrosity consisting of the while loop's body: w=w[{f=For[4];f=f[@x];f=f[{Print[$e];q=Equal[$x];i=If[{q[1];}];i=i[{k=Times[$e];}];Do[$i];i=If[{q[2];}];i=i[{k=Add[$e];}];Do[$i];i=If[{q[3];}];i=i[{k=Subtract[$e];}];Do[$i];i=If[{q[4];}];i=i[{k=Divide[$e];}];Do[$i];e=k[a=Increment[$a]];}];Do[$f];}];  The primary part of this loop is a for loop, that iterates $$\4\$$ times each iteration of the while loop, has an iteration variable of x and consists of: Print[$e];
q=Equal[$x]; i=If[{q[1];}];i=i[{k=Times[$e]    ;}];Do[$i]; i=If[{q[2];}];i=i[{k=Add[$e]      ;}];Do[$i]; i=If[{q[3];}];i=i[{k=Subtract[$e] ;}];Do[$i]; i=If[{q[4];}];i=i[{k=Divide[$e]   ;}];Do[$i]; e=k[a=Increment[$a]];


The first statement prints out each iteration of the sequence before modifying it. We then create a partial function to check equality with the loop variable x, and encounter four if statements. Each statement checks if x is equal to 1, 2, 3 or 4 respectively, and then assigns k to each function in *, +, - and /, then makes it into a partial function with e as its argument. Finally, we assign e to k run with a as its second argument, and increment a.

# Ruby, 52 bytes

->n{i=0.0;n=[p(n)/i+=1,n*i,n+i,n-i][i%4]until 0<n%1}


Try it online!

• Save 2 bytes: i=0 and use a float as argument to the function. – G B Oct 3 '19 at 6:46
• @GB Nice, thank you. Are we allowed to require the input be a float? – Reinstate Monica -- notmaynard Oct 3 '19 at 16:44

# C (clang), 80 bytes

i;f(n){for(i=0;~i;n=++i%4?i%4-1?i%4-2?n-i:n+i:n*i:n%i?i=-1:n/i)printf("%d ",n);}


Try it online!

A golfed switch statement.


Thanks to many @ceilingcat improvements.

# dzaima/APL, 34 33 bytes

⌽1↓{⍵,⍨⊃⍵(⍎⊃'÷×+-'⌽⍨≢⍵)≢⍵}⍣{⍵≢⌊⍵}


Try it online!

-1 thanks to ngn

• hint – ngn Oct 4 '19 at 0:33

# TI83/84 BASIC, 69 Bytes

1→A
DelVar L1Prompt N
Repeat fPart(N
N→L1(A
NA-1→O
augment(L1,{NA,Ans+A+2,Ans→L1
O/(A+3→N
A+4→A
End
Disp L1


We set up a counter in A and clear L1 so we can use it to track the sequence. We then repeat until the division step causes a fraction. Inside the loop we first store N to the list. Storing to one element past the end of a list or an empty list creates that element, so this one store both adds the result of the division when it doesn't cause a fraction, and initializes the list during the first pass. We then use augment to append the next 3 terms of the sequence. The math works out a few bytes smaller by calculating term A4k+3 in variable O and then basing A4k+2 and A4k+4 off O. Then we do the division separately to reset N for the repeat check and add 4 to A.

I put a Disp L1 at the end but I'm not sure how ideal it is as there's no good way to fit all the terms on the screen. Realistically the user would execute L1 after the program runs manually to scroll through the results.

# Charcoal, 29 bytes

ＮθＷ¬﹪θ¹«Ｉθ⸿≔§⟦∕θⅉ×θⅉ⁺θⅉ⁻θⅉ⟧ⅉθ


Try it online! Link is to verbose version of code. Explanation:

Ｎθ


Input the initial value.

Ｗ¬﹪θ¹«


Repeat until the value is no longer an integer.

Ｉθ⸿


Print the value on its own line.

≔§⟦∕θⅉ×θⅉ⁺θⅉ⁻θⅉ⟧ⅉθ


Calculate the four available arithmetic operations and select the correct one depending on the current output line number.

# Python 3, 78 76 bytes

f=lambda n:n[-1]%1and n[:-1]or f(n+[eval(f"n[-1]{'/*+-'[len(n)%4]}len(n)")])


Try it online!

Takes input as a list of 1 item and recursively appends the next item of the sequence until it's a non-integer.

In the case that taking input as a list is not allowed, here is a very quickly patched version which takes input as an int.

# Input as an integer, 102 bytes

f=lambda n:type(n)==int and f([n])or n[-1]%1and n[:-1]or f(n+[eval(f"n[-1]{'/*+-'[len(n)%4]}len(n)")])


Try it online!

+2 bytes thanks to me forgetting to name the recursive function...
-4 bytes thanks to Jitse

• Nice approach! Since your function is recursive, it cannot remain anonymous. You should include f= in your main code. However, you can also save 4 bytes since n[-1] and len(n) need not be in braces. Try it online! – Jitse Oct 3 '19 at 6:54
• Not sure about taking a list rather than an integer (I'd recommend asking the OP), but n[:-(n[-1]%1>0)]or f... would save a byte – Jonathan Allan Oct 3 '19 at 17:15

# Twig, 164 bytes

Okay, this was actually horribly horrible to write.

Limitations:

• No returns! You either output or don't output
• No while loops. You must use recursion or nothing
• No easy way to output! You have to repeat the output everytime
• You can't give variables a value without using the set tag
• No easy way to get out of a loop. There's no break, continue, goto or similar. This makes a loop impossible to use.
• There is only 1 loop: for ... in ...., and it loops over all the elements in an array, with no way to stop.

All those made the code massive!
It's as long as @Arnauld's JavaScript answer! ... With all 3 alternatives combined.

Here's the code:

{%macro a(b,n=1)%}{{n<2?b}}{%set b=b*n%},{{b}}{%set b=b+n+1%},{{b}}{%set b=b-(n+2)%},{{b}}{%set b=b/(n+3)%}{%if(b//1)==b%},{{b~_self.a(b,n+4)}}{%endif%}{%endmacro%}


You can try it on https://twigfiddle.com/zw5zls

## How to use:

Simply import the file and call the first macro.

{% import 'file.twig' as a %}

{{ a.a(21) }} {# 21,21,23,20,5,25,31,24,3,27,37,26 #}


To have an usable array, you can do a.a(21)|split(',').

## Ungolfed:

{% macro calc(number, index = 1) %}
{% if index < 2 %}
{{ number }}
{% endif %}

{% set number = number * index %},{{ number }}
{% set number = number + index + 1 %},{{ number }}
{% set number = number - (index + 2) %},{{ number }}
{% set number = number / (index + 3) %}

{#
verifies if it is an integer.
this is done with an integer division with 1 and compare with itself
if both values are the same, the number is an integer
otherwise, it is a floating-point number
#}
{% if (number // 1) == number %}
,{{ number ~ _self.calc(number, index + 4) }}
{% endif %}
{% endmacro %}


This ungolfed answer will NOT give the correct output, as it will throw random whitespaces.
It exists merely to be humanly readable.

# Husk, 16 bytes

↑¦1GI⁰zI¢ë*+-/N


Try it online!

## Explanation

↑¦1GI⁰zI¢ë*+-/N   Input is a number n, accessible via ⁰.
ë*+-/    Four-element list containing the functions *, +, - and /.
¢         Cycle infinitely.
z       N   Zip with the list [1,2,3,4,5,..
I          using the identity function (which works as function application since e.g. I+2 == (I+)2 == +2).
G               Cumulative reduce from the left
I             using flipped identity function
⁰            with initial value n.
This results in [n, n*1, (n*1)+2, ((n*1)+2)-3, ..
↑                  Take the maximal prefix of elements
¦1                that are divisible by 1, or in other words are integers.
`