# Is it an exercise set?

We all know that a lot of exercises only affect one half of your body, so you have to do them twice, once for each side. Such exercises have two counterparts, one for the left side and one for the right. However, there's no need to execute the two counterparts consecutively, as long as the exercises for both sides are in the same order. You may as well switch between sides in your exercise program, but it wouldn't make sense to start some exercises with one side and some with the other.

## Challenge

An exercise part is a list of non-zero integers, where its second half consists of the integers of the first half negated and in the same order, and the signs of the integers on each half are equal. The sign of the first half of an exercise part is its leading side.

An exercise set is zero or more exercise parts with the same leading side concatenated together.

Given a list of non-zero integers as input, determine if it is an exercise set. The integers aren't necessarily unique. The list's length isn't necessarily even.

Your solution may not use any of the standard loopholes. You may use any two different consistent values for output. This is , so the shortest solution wins.

## Examples

[-5, -1, -7, -6, -5, 5, 1, 7, 6, 5] is an example of an exercise part. The first half is [-5, -1, -7, -6, -5], and the last half is [5, 1, 7, 6, 5], which is each integer in the first half negated. Additionally, the first half's integers are all of the same sign. This exercise part's leading side is -1.

[3, 6, 5, -3, -6, -5, 1, 6, 4, 3, -1, -6, -4, -3] is an example of an exercise set. Its individual exercise parts are [3, 6, 5, -3, -6, -5] and [1, 6, 4, 3, -1, -6, -4, -3], and they both have leading side 1.

[4, -4, -5, 5], despite only consisting of valid exercise parts, isn't an exercise set, since the first part, [4, -4], has leading side 1, while the second part, [-5, 5], has leading side -1.

## Test cases

Valid test cases:

[]
[1, -1]
[1, -1, 1, -1]
[-6, 6, -5, -4, -3, 5, 4, 3]
[-1, -5, -8, 1, 5, 8, -7, -6, -5, -3, 7, 6, 5, 3]
[-1, -5, -8, 1, 5, 8, -1, 1]


Invalid test cases:

[1]
[1, -2]
[1, 2, -3, -1, -2, 3]
[1, 2, 3, -3, -1, -2]
[-1, -5, -8, 1, 5, 8, 7, 6, 5, 3, -7, -6, -5, -3]
[1, 2, 3, 5, 1, 2, 3, 5]
[1, 2, -5, 4, -6, 5, 5, -6]
[1, 2, -1, 3, -2, -3]
[1, -2, 1]
[-1, -1, 1]
[1, -1, 1]

• The empty case is an annoyance. And to interpret the words of the challenge I'm not sure if there is a valid way to assign "not exercising at all" to either one side or the other of "is it an exercise set?" But to be honest I'm just whining. – ngm May 24 '18 at 13:55
• @ngm Was just about to comment this.. Empty list is an annoying edge case.. Personally I would state the input contains at least one item. Apart from that nice challenge, though! – Kevin Cruijssen May 24 '18 at 13:57
• @ngm It's truthy by terms of vacuous truth. Consider it to be proper relaxation. ;) – Erik the Outgolfer May 24 '18 at 14:03
• It's nice to know I can golf and exercise at the same time. – ngm May 24 '18 at 14:06
• @ngm "It's nice to know I can golf and exercise at the same time." We got more of those kind of challenges. ;) – Kevin Cruijssen May 24 '18 at 14:11

# Python 2, 69 67 bytes

a,b=x=[[],[]];k=0
for n in input():x[n>0]+=n*n,n*k>0;k=n
print a==b


Try it online!

# Jelly, 10 bytes

ṁṠŒg$+2/FẸ  Try it online! # Java 8, 186183 185 bytes a->{int i=a.length-1,t,j;boolean r=i%2>0,f;if(i<0)return!r;for(f=a[i]<0;i>0;){for(r&=f==(t=a[j=i])<0;j>0&&t>>>31==a[--j]>>>31;);for(t=i-j,i-=2*t;j>=0&j>i;)r&=a[j+t]==-a[j--];}return r;}  +2 bytes due to a bug-fix for test cases of size 3 (almost all permutations of 1 and -1 at the end of my TIO-link). Can definitely be golfed.. The challenge looks to-the-point, but it's pretty hard to implement. Especially the test case [4,-4,-5,5] was annoying to fix.. But it works now. Will golf it down from here. Try it online. Explanation: a->{ // Method with integer-array parameter and boolean return-type int i=a.length-1,j, // Index integers (i starting at the last index) t; // Temp integer boolean r=i%2>0, // Result-boolean, starting at true if the input-list is even f; // Flag-integer if(i<0) // If the input was empty (edge case) return!r; // Return true for(f=a[i]<0; // Set the flag-boolean to "Is the current item negative?" i>0;){ // Loop down over the array for(r&=f==(t=a[j=i])<0; // Set s to the current number // And verify if the initial flag and s have the same sign j>0 // Loop j from i down as long as j is larger than 0, &&t>>>31==a[--j]>>>31;); // and both s and the current item have the same sign // Decreasing j by 1 every iteration for(t=i-j, // Set t to i-j (amount of same signed adjacent values) i-=2*t; // Decrease i by two times t j>=0 // Loop as long as j is larger than or equal to 0, &j>i;) // and also larger than i r&=a[j+t]==-a[j--];} // Verify if the pairs at index j+t and j // are negatives of each other return r;} // Return if r is still true (if all verifications succeeded)  # R, 91 bytes Inputs a whitespace-separated vector of numbers. Outputs FALSE for valid and TRUE for invalid. x=scan() y=x<0 z=rle(y) "if"(sum(x|1),any(x[y]+x[!y],z$v==rev(z$v),z$l[!0:1]-z$l[!1:0]),F)  rle gives the run length encoding, in this case of the sequence of positive and negative values. The completely and totally unfair empty edge case ;) adds a whopping 15 bytes. Many bytes shaved off by @Giuseppe. Here is a 92 byte version expressed as a function which is better for testing: Try it online! # JavaScript (ES6), 54 bytes Optimized version, inspired by Dennis' Python answer. Returns 0 or 1. a=>a.map(b=p=x=>b[+(x<0)]+=[x*x,p*(p=x)>0])|b[1]==b[0]  Try it online! # Original version, 74 bytes a=>a.map(x=>b[i^=p*(p=x)<0&&-~(b[i]+=0)]+=[,x*x],b=[p=0,i=0])|b[1]+0==b[0]  Try it online! ### How? We store the first halves of all exercise parts in b[0] and the second halves in b[1], switching between b[0] and b[1] each time the sign is changing. Entries are squared to get rid of the sign. We prefix each entry with a comma and suffix each part with a 0. There's some extra logic to handle the 'empty input' edge case at basically no cost (see the comment near the end of the source code). a => // given the input array a[] a.map(x => // for each x in a[]: b[i ^= // access b[i]: p * (p = x) // we keep track of the previous entry in p < 0 && // if p and x have opposite signs: -~(b[i] += 0) // append a '0' to b[i] and update i: 0 -> 1, 1 -> 0 ] += [, x * x], // append a comma followed by x² to b[i] b = [p = 0, i = 0] // start with p = 0, i = 0 and b = [0, 0] ) | // end of map() b[1] + 0 // this will append a '0' to b[1] if it was turned into a string // or let it unchanged if it's still equal to zero (integer), // which handles the 'empty input' edge case == b[0] // compare the result with b[0]  # Python 2, 147130113112 106 bytes from itertools import* def f(s):l=[map(abs,g)for v,g in groupby(s+[0],0 .__cmp__)];print l[1::2]==l[:-1:2]  Try it online! Saved: • -27 bytes, thanks to Dennis • lambda n:cmp(n,0) can become 0 .__cmp__. all(a==b for a,b in zip(l[::2],l[1::2])) can become l[:-1:2]==l[1::2]. – Dennis May 24 '18 at 14:42 # Retina 0.8.2, 57 bytes ^\b|,\b$&=
(.)(\d+),(?=\1)
$2_ -|= .$
$&, ^((\w+,)\2)*$


Try it online! Takes comma-separated input, but link includes header that processes test cases. Explanation:

^\b|,\b
$&=  Insert a marker before each positive integer. (.)(\d+),(?=\1)$2_


Change the commas between integers of the same sign to underscores.

-|=


Delete the remaining signs.

.&,


Append a comma if the input is not empty.

^((\w+,)\2)*\$


Check that the string consists of pairs of runs of the same integers.

# Python 2, 111 bytes

x=input()
o=[];p=[]
for a,b in zip(x,x[1:]):
if 0<a*x[0]:
p+=a,-a
if b*a<0:o+=p[::2]+p[1::2];p=[]
print o==x


Try it online!

# JavaScript (Node.js), 155 bytes

b=>eval('i=b.length-1;r=i%2;0>i&&!r;for(f=0>b[i];0<i;){for(r&=f==(s=0>b[j=i]);0<j&&s&0>b[--j]|!s&0<b[j];);t=i-j;for(i-=2*t;0<=j&j>i;)r&=b[j+t]==-b[j--]}r')


Try it online!

Also thanks to him for correcting 2 test cases of mine

• Since yours is inspired from my Java answer, you should change r=0<i to r=i%2, since the test cases [1,-1,1] and [-1,1,-1] are failing at the moment. Byte-count remains the same for JS, though. – Kevin Cruijssen May 24 '18 at 15:49
• @KevinCruijssen : Thanks, done – Muhammad Salman May 24 '18 at 15:55

# Stax, 13 bytes

Ç¥├W╦╣∩T~≥▌╨c


Run and debug it

# Brachylog, 18 14 bytes

~c{ḍz{ṅᵈ¹ṡ}ᵛ}ᵛ


Try it online!

Saved 4 bytes thanks to @ErikTheOutgolfer.

### Explanation

                    Succeed if and only if:
~c                  You can deconcatenate the input list…
{         }ᵛ      …and verify that for each of the sublists:
ḍ                  Split it in half
z                 Zip the elements of each half together
{    }ᵛ          Verify that for each couple:
ṅᵈ¹               The first integer is the negation of the second one
ṡ              Take the sign of the first one
All signs should be equal in a sublist
All leading signs of the sublists should be equal



# APL (Dyalog Classic), 48 bytes

{0::1⋄0≠+/×¨⍵:0⋄(~0∊⊢∨2|⍳∘⍴)2{⍺≡-⍵}/⍵⊂⍨1,2≠/×¨⍵}


Try it online!