# "-rot" transform

## Background

-rot transform (read as "minus-rot transform") is a sequence transformation I just invented. This transform is done by viewing the sequence as a stack in Forth or Factor (first term on the top) and repeatedly applying -rot +. -rot is a command that moves the top of the stack to two places down, and + adds two numbers on the top of the stack.

For example, applying -rot transform to the sequence [1, 2, 3, 4, 5, 6, 7, 8, 9] looks like this (the right side is the top of the stack in this example, to match Forth/Factor conventions):

initial: 9 8 7 6 5 4 3 2 1 <--
-rot   : 9 8 7 6 5 4 1 3 2
+      : 9 8 7 6 5 4 1 5 <--
-rot   : 9 8 7 6 5 5 4 1
+      : 9 8 7 6 5 5 5 <--
-rot   : 9 8 7 6 5 5 5
+      : 9 8 7 6 5 10 <--
-rot   : 9 8 7 10 6 5
+      : 9 8 7 10 11 <--
-rot   : 9 8 11 7 10
+      : 9 8 11 17 <--
-rot   : 9 17 8 11
+      : 9 17 19 <--
-rot   : 19 9 17
+      : 19 26 <--


-rot does not work when there are only two items on the stack, so the operation stops there. Then the top of the stack at the initial state and after each + command are collected to form the resulting sequence of [1, 5, 5, 10, 11, 17, 19, 26]. Note that it is one term shorter than the input sequence.

Given a finite sequence of integers (of length ≥ 3), compute its -rot transform.

Standard rules apply. The shortest code in bytes wins.

## Test cases

[1, 2, 3] -> [1, 5]
[1, -1, 1, -1, 1, -1, 1, -1] -> [1, 0, 0, 1, -1, 2, -2]
[1, 2, 3, 4, 5, 6, 7, 8, 9] -> [1, 5, 5, 10, 11, 17, 19, 26]
[1, 2, 4, 8, 16, 32, 64, 128] -> [1, 6, 9, 22, 41, 86, 169]
[1, 0, -1, 0, 1, 0, -1, 0, 1] -> [1, -1, 1, 0, 1, -1, 1, 0]

• What does "first term on top" mean? It seems the first term is on the bottom in all the examples used. Aug 24 at 8:45
• @WheatWizard The example starts by reversing the array because (I think) it is a common convention to write the top of the stack on the right side. Should I include a vertical diagram? (Also there is only one example, I don't get what you mean by "examples") Aug 24 at 8:50
• Ah alright, that was very confusing for me since I am very accustomed to the top of the stack being on the left. I didn't realize "right side is the top of the stack" was describing the example exclusively. Aug 24 at 8:58
• The worked example uses reverse format from the test cases?! Grrr. Aug 27 at 0:55
• I was trying to brainfuck it until i realise i can't take reversed input :P
– okie
Sep 1 at 12:05

# Jelly, 8 bytes

Ä2œPF_@\


Try it online!

Based on the older approach below. Ä generates cumulative sums, and 2œPF (ew) throws away the second one. Then \ scanning by _@ flipped subtraction gives:

    [a,
a+b+c-(a),
a+b+c+d-(a+b+c-(a)),
a+b+c+d+e-(a+b+c+d-(a+b+c-(a))),
...]
= [a, b+c, a+d, b+c+e, ...]


I feel like there has to be something shorter than 2œPF to remove the 2nd element of a list.

# Jelly, 9 8 bytes

Jḟ2b1^\ḋ


Try it online!

Based on rak1507's observation that when the input is $$\[a,b,c,d,e,f...]\$$, the answer is $$[a, ~~b + c, ~~a + d, ~~b + c + e, ~~a + d + f, \dots].$$

That is: cumulative sums of even and odd elements, but with the first two elements swapped.

That means we can calculate (ḋ is dot product, padding the shorter argument with 0s at the end):

ḋ(input, ) = a
ḋ(input, [0, 1, 1]) = b + c
ḋ(input, [1, 0, 0, 1]) = a + d
ḋ(input, [0, 1, 1, 0, 1]) = b + c + e
ḋ(input, [1, 0, 0, 1, 0, 1]) = a + d + f
ḋ(input, [0, 1, 1, 0, 1, 0, 1]) = b + c + e + g
...


In this program, Jḟ2b1^\ computes the triangle [, [0,1,1], [1,0,0,1]…] and ḋ takes dot products with the input.

Jḟ2 is [1,3,4,5,…,n]. b1 generates lists of 1s of those lengths, and ^\ is a XOR scan.

# Python 3, 53 47 bytes

f=lambda a,b,*r:(a,)+(r and f(b+r,a,*r[1:]))


A variadic function that takes the integers as separate arguments and returns a tuple. Try it online!

### Explanation

f=lambda a,b,*r:(a,)+(r and f(b+r,a,*r[1:]))
f=                                              # Define f to be
lambda a,b,*r:                                # a function of at least two arguments
# where a,b are the first two args
# and any args beyond those are
# put in a tuple and assigned to r
(a,)                            # Tuple containing a
+                           # Add (concat) this tuple:
(r and                   ) # If r is falsey (empty), then r
f(               )  # Else, recursive call with:
b+r,           # The second arg plus the third
a,         # followed by the first arg
*r[1:]   # followed by all the rest

• @Shaggy I don't think so; have you misunderstood the meaning of "reverse"? Aug 24 at 9:53
• [9,8,7,6,5,4,3,2,1] should output [1,5,5,10,11,17,19,26] but yours outputs [9,15,15,20,19,23,21,24]. Aug 24 at 10:05
• Wait, no, I was going off the worked example in the spec and that's in the wrong order. I'll let Bubbler know. Aug 24 at 10:10

# Jelly, 11 10 bytes

-œ?UŒœÄZFḊ


Thank you very much to caird/Dude/ChartZ for helping golf this in TNB.

-1 thanks to Lynn!

Explanation:

I tried to look for a pattern that could be used to solve this more easily, so a quick sage script did the trick.

From that, we get the pattern

[a, b + c]
[a, b + c, a + d]
[a, b + c, a + d, b + c + e]
[a, b + c, a + d, b + c + e, a + d + f]
[a, b + c, a + d, b + c + e, a + d + f, b + c + e + g]
[a, b + c, a + d, b + c + e, a + d + f, b + c + e + g, a + d + f + h]


From this, we can see it is an interleaved cumulative sum of [a, d, f, h...] and [b, c, e, g...]. Flipping a and b makes this nicer, [b, d, f, h...] and [a, c, e, g...].

-œ?UŒœÄZFḊ
-           -1
œ?         -1th ordered permutation, i.e. second-from-last. This will always be the array reversed with the last 2 elements swapped
U        un-reverse
Œœ      uninterleave
Ä     cumulative sum
Z    zip
F   flatten
Ḋ  tail


Try it online!

• Nice! Thank you Aug 24 at 1:19

# convey, 55 bytes

 3!<
v<#/:<
?:"  \&
v?~"#:}
>#>>,^^
?v v^-1
>+>,,\{


Try it online!

Lower right part is letting length(input) - 1 elements to the output. Top right part buffers the input for too long inputs, as the row would otherwise attach to itself. Top left we get a 3 for each iteration: this splits off the first three elements and lets the head wait for 3 extra steps before copying it into the output and then rejoining with the main row. Because the head blocks the tile while waiting, the other 2 elements go into the + before joining the row again. # Prolog (SWI), 47 46 bytes

-1 byte thanks to Wheat Wizard

[A,B|T]/[A|R]:-T=[C|U],S is B+C,[S,A|U]/R;T=R.


Try it online!

### Explanation

We define / as an infix predicate that takes a list as its left argument and sets its right argument to the -rot transformed list.

[A,B|T]/[A|R] :-


The left argument must have at least two elements, A and B. Any elements beyond the second are put in T. The right argument will always start with A; the rest of it will be R, which we calculate in one of two ways:

T=[C|U], S is B+C, [S,A|U]/R


Recursive case: if T has at least one element, we put the first element of T into C and the rest of T into U. Next, we calculate the sum of B and C and put it in S. Then we do a recursive call with the list [S,A|U]: the sum S, followed by the first element A, followed by all the elements in U. The result of that recursive call is put in R.

; T=R


If T is empty, the unification T=[C|U] fails, and we fall back to the base case: R is the empty list (i.e. T).

# Vyxal, 8 bytes

÷^!‹(…∇+


Try it Online!

Woo using a stack based language to solve a stack based problem. Outputs each item on a newline. 11 bytes to output as list: ÷^!‹(:⅛∇+)¾

Also, look ma, no letters (and flags)! Funnily enough, I don't think there's any flag combination that would get this under 8 bytes.

## Explained

÷^!‹(…∇+
÷        # Push every item of the input onto the stack
^       # and reverse the stack to make the list indicative of the stack (Ṙ÷ achieves the same thing, but we're going 100% symbolic)
!‹     # Push len(stack) - 1
(    # and that many times:
…   #    print the top of the stack without popping
∇  #    perform rot. Fun fact: I added rot to vyxal after seeing forth/factor as LoTM
+ #    add the top two items


# Python 3, 6158 57 bytes

lambda a:[a[~i%2]+sum(a[i:1:-2])for i in range(1,len(a))]


Try it online!

-3 bytes thanks to @MarcMush

-1 byte thanks to @ovs, by shifting the range by 1

a is the original sequence and b is the -rot transform (both 0-based):

b is define like this :

n is even : b(n) = a(0) + (sum of all odd terms from a(3) to a(n+1))

n is odd : b(n) = a(1) + (sum of all even terms from a(2) to a(n+1))

• 58 bytes Aug 24 at 8:46
• 57 bytes by shifting the range by 1
– ovs
Aug 24 at 9:30

# JavaScript, 42 bytes

Saved 4 bytes prior to posting by following DLosc's lead and taking the input integers as individual arguments rather than as a single array.

f=(x,y,z,...a)=>[x,...1/z?f(y+z,x,...a):a]


Try it online!

Or, if outputting a comma delimited string with a trailing comma is allowed then:

# JavaScript, 40 bytes

f=(x,y,z,...a)=>x+[,1/z?f(y+z,x,...a):a]


Try it online!

## Perl 5, 57 56 + 4 (-apl options) = 60 bytes

$F[$_-1]+=$F[$_],$F[$_]=$F[$_-2]for 2..$#F;pop@F;$_="@F"


Try it online!

# C (clang), 44 39 bytes

f(*a,l){for(;--l;a=*a++)a+=a;}


Try it online!

Saved 5 bytes thanks to AZTECCO!!!

Inputs a pointer to a finite sequence of integers and its length (since pointers in C carry no length info), and computes its -rot transform in place.

# Retina 0.8.2, 40 bytes

\d+
$* +1(1*),(1*,)(1*)$1¶$3$2$1 %\G1  Try it online! Link includes footer that spaces the results out. Takes input as a comma-separated list of non-negative integers due to limitations of unary, and outputs a newline-separated list (+4 bytes for newline-separated input or +5 bytes for comma-separated output). Explanation: \d+$*


Convert to unary.

+1(1*),(1*,)(1*)
$1¶$3$2$1


Make a copy of the first number, then rotate it below the sum of the third and second numbers. Repeat until there are only two numbers left.

%\G1


Convert the first number on each line to decimal. This outputs the initial first number and all of the copied sums, but avoids duplicating the penultimate sum.

# tinylisp, 75 bytes

(d F(q((S)(c(h S)(i(t(t S))(F(c(a(h(t S))(h(t(t S))))(c(h S)(t(t(t S))))))(


Defines a function F that takes a list and returns a list. Try it online!

### Explanation

Pretty straightforward, once you fight your way through all the parentheses:

(d F                      ; Define F
(q                       ; to be a list representing a function
((S)                    ; that takes one argument, S:
(c                     ;  Cons
(h S)                 ;  the first element of S to the following list:
(i (t (t S))          ;   If the tail of tail of S is not empty:
(F                   ;    Call F recursively, with an argument of
(c                  ;    cons...
(a                 ;     the result of adding
(h (t S))         ;     the second element of S and
(h (t (t S))))    ;     the third element of S
(c                 ;    ... to the cons of...
(h S)             ;     the first element of S and
(t (t (t S))))))  ;     S without its first three elements
()                   ;   Else, empty list


The same thing (but snazzier and less golfy) is 92 bytes in tinylisp's descendant language Appleseed:

(def F(q((S)(cons(head S)(if(ttail S)(F(cons(sum(take 2(tail S)))(cons(head S)(drop 3 S))))(


Try it online!

f(a:b:c:d)=a:f(b+c:a:d);f(a:_)=[a]


Try it online!

This takes the straight forward approach. All the other fancy approaches just don't really end up saving any bytes in Haskell.

• @AZTECCO I'm not sure what you are asking. I don't do f a=a because it appends an extra value to the end. You seem to answer that in your comment. Aug 24 at 12:40
• Exactly.. Sorry I was wondering.. Took a moment to figure out why Aug 24 at 13:22
• I think this works for 33
– xnor
Aug 25 at 2:55

# Ruby, 47 38 34 bytes

->a,b,*l{l.map{|x|a,b=b+x,a;b}<<a}


Try it online!

Variadic function accepting at least 2 parameters.

# jq, 53 bytes

[while(.;.+=.|(.//.)=.|.[1:])|.]


Try it online!

Explanation:

Based on example input: [1, 2, 3]

[
while(                  While
.                the array has at least two items
;
.+=.          add the second and third number and store them on second position.
|(.//.)       Choose third element if it is not null else first element
=.           and set its value to the value of the first number.
|.[1:]              Drop the first element.
)
|                       Now we have the evolution of the updated array, e.g. [[1,2,3],[5,1]]
.                    take the first element of each array
]                           [1,5]

• Bounty started. Sep 2 at 8:59

# APL (Dyalog Classic), 50 bytes

{⎕←1↑⍵⋄({(3↓⍵),⍨(+/2↑1⌽3↑⍵),1↑⍵}⍣{⎕←1↑⍺⋄(⍴⍺)<3})⍵}


Try it online!

Explanation:

(+/2↑1⌽3↑⍵),1↑⍵ take the first three elements, rotate them, sum the first two and stick the third (which was originally the first element) on the end again so (a b c) -> (b c a) -> (b+c a)
(3↓⍵),⍨ concatenate this with the rest of the list
⍣{⎕←1↑⍺⋄(⍴⍺)<3} the above gets run until the list is less than 3 elements


Note: locally this seems to iterate one more time, but in tio.run it does not, unsure why. This is my first code golf attempt so certainly a lot to be improved on! Happy to hear from APL experienced users how this could be better, I dont like my use of ⎕ in this solution

• Welcome to Code Golf, and nice first answer! Be sure to check out our Tips for golfing in APL page for ways you can golf your program, and feel free to drop by the APL Orchard if you'd like to discuss the language or golfing in it Sep 5 at 11:58
• Dyalog Unicode has Dyalog 17.0 which it recommended to use for most APL solutions. Dyalog Classic is generally discouraged due to datedness. Sep 5 at 14:36
• APLgolf has a TryAPL runner which supports the latest Dyalog APL version. Sep 5 at 14:37
• There are certainly some simple golfs you could do: {⎕←⊃⍵⋄{((+/2↑1↓⍵),⊃⍵),3↓⍵}⍣{⎕←⊃⍺⋄3>≢⍺}⍵}
Sep 6 at 10:31

# Jelly, 16 bytes

ḣ2S;ɗḢṄ$ḷ"ƊḊḊ$¿Ḣ


Try it online!

Blegh. Full program, outputs each on a separate line

## How it works

ḣ2S;ɗḢṄ$ḷ"ƊḊḊ$¿Ḣ - Main link. Takes a list L on the left
¿  - While:
$- Condition: ḊḊ - The list is non-empty after dequeuing twice Ɗ - Body:$        -     Last 2 links as a monad f(L):
Ḣ          -       First element, X
Ṅ         -       Print and return
ḣ2              -       First 2 elements
S             -       Sum
;            -       Concat with X
ḷ"      -     Replace the first 2 elements of L with this pair
Ḣ - Get the first element of the final pair


# Keg, 16 bytes

÷^(!;|④
,&""&''+


Try it online!

## Explained

÷^     # Push all items of the input onto the stack and reverse the stack
(!;|   # len(stack) - 1 times:
④      #     print the top of the stack without popping
,      #     and print a newline too
&""&'' #     perform rot
+      #     and add the top two items


# Julia 1.0, 37 bytes

a\b=a
\(a,b,c,r...)=[a;\(b+c,a,r...)]


the numbers are taken as separate arguments, and Julia's multiple dispatch makes it really easy to separate between 2 arguments (first method) and 3 or more arguments (second method)

Try it online!

# Scala, 66 bytes

s=>Seq.iterate(s,s.size-1)(s=>s(1)+s(2)::s(0)::s.drop(3))map(_(0))


Try it in Scastie!

# Japt, 8 bytes

å+
j1
ån


Try it

# Charcoal, 3125 22 bytes

≔ΦＥθΣ…θ⊕κ⊖κθＩＥθ↨…θ⊕κ±¹


Try it online! Link is to verbose version of code. Explanation: Now a port of @Lynn's Jelly answer.

≔ΦＥθΣ…θ⊕κ⊖κθ


Calculate the cumulative sums of the input, i.e. the sums of all of its nontrivial prefixes, but then remove the second sum.

ＩＥθ↨…θ⊕κ±¹


Calculate their cumulative differences, which is done by interpreting their nontrivial prefixes in base -1.

# BQN, 9 bytesSBCS

-˜⊑∾2↓+


Try it here.

Based on Lynn's solution.

-˜⊑∾2↓+
2↓+ # drop 2 elements from the plus scan
∾     # joined to
⊑      # first element of input
-˜       # swapped subtraction scan


# C++14 (or newer), 81 bytes

[](auto&v){for(int i=1,t;++i<v.size();v[i]=t)t=v[i-2],v[i-1]+=v[i];v.pop_back();}


A lambda function that modifies the passed std::vector by reference.

sub f{my($a,$b,$c,@r)=@_;($a,@r?f($b+$c,$a,@r):$b+$c)}  Try it online! # Python 2, 65 bytes l=input();print l while l[2:]:k=l+l;print k;l[:3]=k,l  Try it online! -17 thanks to @ovs -3 from me on ovs improvement # J, 16 bytes 1{1-/\.&.|.\.+/\  Try it online! Translated from Lynn’s Jelly solution # Zsh, 72 50 bytes for _ ({2..$#}){printf $1\ ;2=$[$3+$2];3=\$1;shift}


Used shell parameters instead of variables, saved 22 bytes!

# 05AB1E, 10 bytes

R[=.g<#Š+


A port of @Lynn's top Jelly answer is 10 bytes as well:

ηO¯1ǝ˜Å»s-


Explanation:

R           # Reverse the (implicit) input-list
# Pop and dump all items separated to the stack
[         # Start an infinite loop:
=        #  Print the top item with trailing newline (without popping)
.g      #  Get the amount of items on the stack
<     #  If this is 2:
#    #   Stop the infinite loop
Š       #  Triple swap the top three items (a,b,c to c,a,b)
+      #  Add the top two items together

η           # Get the prefixes of the (implicit) input-list
O          # Sum each inner prefix together
# Remove the second item by:
¯1ǝ       #  Replacing the second item (at index 1) with an empty list
˜      #  And then flatten the list of lists
Å»    # Cumulative left-reduce the list by:
s   #  Swapping the two items
-  #  And subtracting them from one another
# (after which the list is output implicitly as result)


# Whitespace, 58 bytes (12 bytes in Binary Whitespace)

LSSTLSLSTLSTSSLSLTTTSLSSLTSSSSLSTLSTSSLTTTSLTSSLSLTTTSLSLL


where S is space (ASCII 32), T is tab (ASCII 9), and L is line feed (ASCII 10).

Whitespace is a stack-based language, which would seem ideal for this challenge, however it provides very limited stack instructions—none of which can modify the stack below the top two elements. The heap can be used as scratch space though. For this challenge, only one heap address is needed, which we'll call the accumulator acc in the pseudocode.

The program ends once the stack underflows. Label 1 is not necessary, but it makes the program a callable procedure to follow Code Golf rules.

1:                  # LSSTL
dup printi      # SLS TLST
0 swap store    # SSL SLT TTS
_:                  # LSSL
+ dup printi    # TSSS SLS TLST
0 retrieve swap # SSL TTT SLT
0 swap store    # SSL SLT TTS
jmp _           # LSLL


Notes on syntax:

• _ represents a label with no digits. It is unique from label 0.
• A raw digit literal represents a push instruction.

Pseudocode:

func f(stack) {
print(stack.top())
var acc = stack.pop()  # heap address 0
loop {
var x = stack.pop() + stack.pop()
print(x)
acc, x = x, acc
stack.push(x)
}
}


## Binary Whitespace, 12 bytes

Whitespace has a trinary alphabet (space, tab, LF), but it can be represented with a binary alphabet with a simple mapping. Space becomes 0, tab becomes 10, and LF becomes 11. All trailing zeros on the last byte are ignored. If the final character ends with 0 (i.e. space or tab), then append a 1 to the bit stream. This encoding is implemented by Nebula.

If other code golf languages can pick arbitrary encodings, then this should be fair :).

11000110 11010110 10001101 11010100
11001110 00001101 01101000 11101010
01110001 10111010 10011011 11000000


## Running

These are the five provided test cases. Run the program with one of these prefixed. Digits are outputted without delimiters to save bytes.

1. SSSTTL SSSTSL SSSTL LSTTL
2. SSTTL SSSTL SSTTL SSSTL SSTTL SSSTL SSTTL SSSTL LSTTL
3. SSSTSSTL SSSTSSSL SSSTTTL SSSTTSL SSSTSTL SSSTSSL SSSTTL SSSTSL SSSTL LSTTL
4. SSSTSSSSSSSL SSSTSSSSSSL SSSTSSSSSL SSSTSSSSL SSSTSSSL SSSTSSL SSSTSL SSSTL LSTTL
5. SSSTL SSL SSTTL SSL SSSTL SSL SSTTL SSL SSSTL LSTTL
3 2 1                call 1  # => 15
-1 1 -1 1 -1 1 -1 1  call 1  # => 1001-12-2
9 8 7 6 5 4 3 2 1    call 1  # => 1551011171926
128 64 32 16 8 4 2 1 call 1  # => 169224186169
1 0 -1 0 1 0 -1 0 1  call 1  # => 1-1101-110


The interpreter must allow empty labels and argument literals. The reference interpreter wspace (and thus TIO) does not support this; Nebula and Whitelips do.