16
\$\begingroup\$

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]
\$\endgroup\$
6
  • 4
    \$\begingroup\$ 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. \$\endgroup\$
    – ngm
    Commented May 24, 2018 at 13:55
  • 1
    \$\begingroup\$ @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! \$\endgroup\$ Commented May 24, 2018 at 13:57
  • 2
    \$\begingroup\$ @ngm It's truthy by terms of vacuous truth. Consider it to be proper relaxation. ;) \$\endgroup\$ Commented May 24, 2018 at 14:03
  • 2
    \$\begingroup\$ It's nice to know I can golf and exercise at the same time. \$\endgroup\$
    – ngm
    Commented May 24, 2018 at 14:06
  • \$\begingroup\$ @ngm "It's nice to know I can golf and exercise at the same time." We got more of those kind of challenges. ;) \$\endgroup\$ Commented May 24, 2018 at 14:11

12 Answers 12

5
\$\begingroup\$

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!

\$\endgroup\$
4
\$\begingroup\$

Jelly, 10 bytes

ṁṠŒg$+2/FẸ

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Java 8, 186 183 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)
\$\endgroup\$
3
\$\begingroup\$

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!

\$\endgroup\$
0
3
\$\begingroup\$

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]
\$\endgroup\$
0
2
\$\begingroup\$

Python 2, 147 130 113 112 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
\$\endgroup\$
1
  • 2
    \$\begingroup\$ 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]. \$\endgroup\$
    – Dennis
    Commented May 24, 2018 at 14:42
2
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

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
     
\$\endgroup\$
0
1
\$\begingroup\$

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!

\$\endgroup\$
1
\$\begingroup\$

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!


Inspiration was @KevinCruijssen's answer

Also thanks to him for correcting 2 test cases of mine

\$\endgroup\$
2
  • \$\begingroup\$ 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. \$\endgroup\$ Commented May 24, 2018 at 15:49
  • \$\begingroup\$ @KevinCruijssen : Thanks, done \$\endgroup\$ Commented May 24, 2018 at 15:55
1
\$\begingroup\$

Stax, 13 bytes

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

Run and debug it

\$\endgroup\$
0
\$\begingroup\$

APL (Dyalog Classic), 48 bytes

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

Try it online!

\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.