Counting up and down while doubling the increments

Input:

A non-empty list / vector where each element holds a value/character, indicating if you'll count up or down. I'll use 1 and -1, but you may choose whatever you like. You can only use two values, you can't use 1,2,3... and -1,-2,-3..., for up and down respectively.

Challenge:

You'll use the numbers in the geometric series 1, 2, 4, 8, 16, 32.... Every time you start counting up or down, you'll count in increments of 1, then 2, then 4 and so on. If you change and start counting the other way then you'll subtract 1, then 2, then 4 and so on. The output shall be the number you get to in the end.

Examples:

In the example below, the first line is the input, the second line is the numbers you're counting up/down, the third line is the cumulative sum, and the last line is the output.

Example 1:

1   1   1   1   1   1   1   1   1   1
1   2   4   8   16  32  64  128 256 512
1   3   7   15  31  63  127 255 511 1023
1023


Example 2:

1   1   1   1   1   1   -1  -1  -1  -1  1   1   1
1   2   4   8   16  32  -1  -2  -4  -8  1   2   4
1   3   7   15  31  63  62  60  56  48  49  51  55
55


As you can see, the first 1 or -1 "resets" the value we're counting, and consecutive sequences of 1 or -1 means doubling the value.

Example 3:

-1  -1  1   1   -1  -1  -1
-1  -2  1   2   -1  -2  -4
-1  -3  -2  0   -1  -3  -7
-7


Some additional test cases to account for some potential corner cases.

The input is on the first line. The output is on the second.

1
1
-------
-1
-1
-------
-1   1  -1   1  -1   1  -1   1  -1   1  -1   1
0


This is so the shortest submission in each language wins.

Husk, 3 bytes

ṁḋg


Try it online!

Explanation

ṁḋg
ṁ    take sum of
ḋ   base-2 decoding of each group.


MATL, 6 bytes

Y'Wq*s


Explanation

Consider input [1 1 1 1 1 1 -1 -1 -1 -1 1 1 1].

     % Implicit input
% STACK: [1 1 1 1 1 1 -1 -1 -1 -1 1 1 1]
Y'   % Run-length encoding
% STACK: [1 -1 1], [6 4 3]
W    % Exponentiation with base 2, element-wise
% STACK: [1 -1 1], [64 16 8]
q    % Subtract 1
% STACK: [1 -1 1], [63 15 7]
*    % Multiply, element-wise
% STACK: [63 -15 7]
s    % sum of array
% STACK: 55
% Implicit display


Japt, 8 6 bytes

-2 bytes thanks to @ETHproductions

ò¦ xì2


Try it online!

Explanation

Implicit input: [1, 1, 1, -1, -1, -1, -1, 1, 1]

ò¦


Partition input array (ò) between different (¦) elements:
[[1, 1, 1], [-1, -1, -1, -1], [1, 1]]

ì2


Map each partition to itself parsed as an array of base-2 digits (ì): [7, -15, 3]

x


Get the sum (x) of the resulting array: -5

• Nice technique. I believe you can change ®ì2Ãx to xì2 to save two bytes. Commented Jul 26, 2017 at 15:38
• @ETHproductions Man, you've been all over my posts. Thanks again! Commented Jul 26, 2017 at 18:38

Cubix, 65 bytes

W(?\q.p)w.;0.w;/0>I!U-unP(nwUs;q\^q:;^!u?P(w!u+w.;;>2p!u/@Os..sr\


Try it online!

        W ( ? \
q . p )
w . ; 0
. w ; /
0 > I ! U - u n P ( n w U s ; q
\ ^ q : ; ^ ! u ? P ( w ! u + w
. ; ; > 2 p ! u / @ O s . . s r
\ . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .


Watch it run

As a brief explanation of this:

• Read in each integer (1 or -1) and compare it to previous. If:
• the same push it to the bottom as the start of a counter
• else bring counter to top and increment/decrement it as appropriate.
• Once input is finished bring each counter to the top and handling negatives do 2 ^ counter - 1
• Sum the results and output

JavaScript (ES6), 38 bytes

a=>a.map(e=>r+=d=d*e>0?d+d:e,r=d=0)&&r


R, 32 bytes

sum((2^(R=rle(scan()))$l-1)*R$v)


Try it online!

This is the same method as a few others here.

With the input of -1 -1 1 1 -1 -1 -1

• Do a Run Length Encoding on the input. Results with lengths of 2, 2, 3 and values -1, 1, -1
• Do 2 to power of lengths - 1. Results in 3, 3, 7
• Multiply by the RLE values giving -3, 3, -7
• Return the sum -7

Python 3, 57 56 bytes

-1 byte thanks to @notjagan

f=lambda a,*s,m=1:m*a+(s>()and f(*s,m=(m*2)**(a==s[0])))


Try it online!

• -1 byte with this or this. Commented Jul 24, 2017 at 2:40
• That s>() took me a second. That's really smart. Commented Jul 24, 2017 at 12:26

Jelly, 4 bytes

ŒgḄS


Try it online!

C++14, 58 bytes

[](auto v,int&s){int p=s=0;for(auto x:v)s+=p=x*p<1?x:2*p;}


Takes input via the v argument (std::vector, or any iterable container), outputs to the s argument (by reference). Each element of v must be either 1 or -1.

Example usage and test cases.

Brachylog, 13 bytes

ḅ⟨{ȧᵐ~ḃ}×h⟩ᵐ+


Try it online!

Brachylog uses _ instead of -.

Explanation:

?ḅ⟨{ȧᵐ~ḃ}×h⟩ᵐ+. Predicate (implicit ?.)
?               The input
ḅ              A list where its elements' elements are equal, and when concatenated is ?
ᵐ   The result of mapping this predicate over ?
⟨        ⟩      The result of forking two predicates over ? with a third
{    }           The result of this predicate on ?
ᵐ                The result of mapping this predicate over ?
ȧ                   The absolute value of ?
~               An input where the result of this predicate over it is ?
ḃ                A list that represents the digits of ? in base I (default 2)
h         An object that is the first element of ?
×          A number that is the product of ?
+  A number that is the sum of ?
. The output


Python, 76 72 bytes

f=lambda s,k=1:len(s)and(f(s,s[0])if s[0]*abs(k)/k-1else k+f(s[1:],2*k))


Try it online!

Pyth, 12 bytes

sm*edt^2hdr8


Try it online!

PHP, 51 bytes

while($d=$argv[++$i])$s+=$x=$d*$x>0?2*$x:$d;echo$s;


Run with -n or try it online.

CJam (13 bytes)

{e{(*2b}%1b}


Online test suite. This is an anonymous block (function) which takes an array of ints on the stack and leaves an int on the stack. The last test shows that it handles an empty array correctly, giving 0.

The approach is straightforward run-length encoding followed by a manual run-length decode of each run and base conversion. Using the built-in for run-length decode I get one byte more with {e1/:e~2fb1b} or {e{ae~2b}%1b}.

05AB1E, 6 bytes

γε2β}O


Try it online!

• Ahhh... Base-2 conversion... and I thought I was being cute with lift. γε¬sƶÄ<o*}OO Commented Jul 24, 2017 at 19:21

k#(a:b:c)=k+last(b:[k*2|a==b])#(b:c)
k#_=k


Try it online!

A simple recursion that either doubles the accumulator k or resets it to 1/-1 and adds the values of each step.

Mathematica, 60 bytes

Tr[Last@*Accumulate/@(#[[1]]2^(Range@Tr[1^#]-1)&/@Split@#)]&


Mathematica, 25 bytes

Tr[Fold[#+##&]/@Split@#]&


Java, 91 bytes

int f(int[]a){int s=0,r=0,i=-1;while(++i<a.length)r+=s=s!=0&s>0==a[i]>0?2*s:a[i];return r;}


Pyth, 11 bytes

s.b*t^2NYr8


Try it online

How it works

         r8    run-length encode input
.b            map (N, Y) ↦
^2N           2^N
t              minus 1
*    Y          times Y
s              sum
`