Triple-balanced numbers

13

1

Description

We consider an integer with at least 3 digits triple-balanced if, when split into three parts, the digits in every part sum up to the same number. We split numbers as follows:

abcdefghi - Standard case: the number of digits is divisable through 3:
abc def ghi

abcdefgh - Number % 3 == 2: The outer groups are both assigned another digit
abc de fgh (the inner group will have one digit less than both outer groups)

abcdefghij - Number % 3 == 1: The inner group is assigned the extra digit
abc defg hij (the inner group will have one digit more than the outer groups)

Challenge

Your task is to write a program, that, given an integer with at least 3 digits, determines whether the given number is triple-balanced and outputs a truthy or falsy value based on it's result.

Test cases

333 -> True
343 -> False
3123 -> True
34725 -> True
456456 -> False
123222321 -> True

This is , so standard loopholes apply and may the shortest answer in bytes win!

racer290

Posted 2017-07-17T16:38:58.170

Reputation: 1 043

1As I understand it, if you can split it evenly, you should. – totallyhuman – 2017-07-17T16:46:25.813

@Mr.Xcoder you split it into three parts (it still doesn't work as per @MagicOctopusUnr's comment: when split in three parts, – Stephen – 2017-07-17T16:46:49.047

@geokavel But then you're violating when split in three parts, – Stephen – 2017-07-17T16:47:40.053

4

Consider using the Sandbox, to avoid such a situation in the future.

– Mr. Xcoder – 2017-07-17T16:51:47.820

2Whoops! I'm sorry for the confusion about the test cases, apparently I had some sort of twist in my head. Now that they are corrected, I hope you vote to reopen my challenge. – racer290 – 2017-07-17T17:08:41.097

5By default, input is allowed to be taken as a string. Can it be taken as an array of digits? – Luis Mendo – 2017-07-17T22:16:43.350

Answers

7

Python 2, 93 88 86 bytes

-4 bytes thanks to @LeakyNun
-2 bytes thanks to @Mr.Xcoder

def g(i):l=-~len(i)/3;print f(i[:l])==f(i[l:-l])==f(i[-l:])
f=lambda a:sum(map(int,a))

Try it online!

ovs

Posted 2017-07-17T16:38:58.170

Reputation: 21 408

3

Jelly, 23 bytes

DµL‘:3‘Ṭ©œṗ⁸U®œṗЀS€€FE

Try it online!

There must be a shorter way that somehow flew over my head...

Leaky Nun

Posted 2017-07-17T16:38:58.170

Reputation: 45 011

It seems straight-forward but it really isn't tbh... Even difficult in 05AB1E due to the non-default splitting. – Magic Octopus Urn – 2017-07-17T21:37:13.963

3

Retina, 89 bytes

^|$
¶
{`¶(.)(.*)(.)¶
$1¶$2¶$3
}`^((.)*.)(.)¶((?<-2>.)*)¶(.)
$1¶$3$4$5¶
\d
$*
^(1+)¶\1¶\1$

Try it online! Link includes test cases. Explanation: The first stage adds newlines at the start and end of the input. The second stage then tries to move digits across the newlines in pairs, however if there aren't enough digits left in the middle then the third stage is able to move them back, causing the loop to stop. The fourth stage then converts each digit separately to unary thus summing them, while the last stage simply checks that the sums are equal.

Neil

Posted 2017-07-17T16:38:58.170

Reputation: 95 035

2

Mathematica, 142 bytes

(s=IntegerDigits@#;c=Floor;If[Mod[t=Length@s,3]==2,a=-1;c=Ceiling,a=Mod[t,3]];Length@Union[Tr/@FoldPairList[TakeDrop,s,{z=c[t/3],z+a,z}]]==1)&

J42161217

Posted 2017-07-17T16:38:58.170

Reputation: 15 931

2

Jelly, 20 bytes

DµL‘:3x2jSạ¥¥LRṁ@ḅ1E

Try it online!

How it works

DµL‘:3x2jSạ¥¥LRṁ@ḅ1E  Main link. Argument: n

D                     Decimal; convert n to base 10, yielding a digits array A.
 µ                    Begin a new chain with argument A.
  L                   Compute the length of A.
   ‘                  Increment; add 1 to the length.
    :3                Divide the result by 3.
                      This yields the lengths of the outer chunks.
      x2              Repeat the result twice, creating an array C.
             L        Compute l, the length of A.
            ¥         Combine the two links to the left into a dyadic chain.
                      This chain will be called with arguments C and l. 
           ¥              Combine the two links to the left into a dyadic chain.
         S                    Take the sum of C.
          ạ                   Compute the absolute difference of the sum and l.
        j                 Join C, using the result to the right as separator.
                      We now have an array of the lengths of all three chunks the
                      digits of n have to be split in.
              R       Range; map each chunk length k to [1, ..., k].
               ṁ@     Mold swapped; takes the elements of A and give them the shape
                      of the array to the right, splitting A into chunks of the
                      computed lengths.
                 ḅ1   Convert each chunk from unary to integer, computing the sum
                      of its elements.
                   E  Test if the resulting sums are all equal.

Dennis

Posted 2017-07-17T16:38:58.170

Reputation: 196 637

1I'd love to read an explanation – Felix Dombek – 2017-07-18T11:11:26.000

@FelixDombek I've added an explanation. – Dennis – 2017-07-18T17:08:43.803

1

MATL, 26 bytes

3:jnZ^!S!tgtYswG48-*Z?da~a

Try it online! Or verify all test cases.

Luis Mendo

Posted 2017-07-17T16:38:58.170

Reputation: 87 464

0

Javascript, 178 bytes

(a)=>{b=a.split(/(\d)/).filter((v)=>v);s=Math.round(b.length/3);f=(m,v)=>m+parseInt(v);y=b.slice(s,-s).reduce(f,0);return b.slice(0,s).reduce(f,0)==y&&y==b.slice(-s).reduce(f,0)}

cdm

Posted 2017-07-17T16:38:58.170

Reputation: 101

Welcome to PPCG! Have you read the tips pages? There's a lot of scope for golfing your answer down.

– Neil – 2017-07-18T10:15:37.293

In case you're still interested, I was able to trim your answer down to 106 bytes: ([...b],s=~b.length/3|0,f=(m,v)=>+m+ +v,y=b.splice(s).reduce(f))=>b.splice(-s).reduce(f)==y&y==b.reduce(f) (take care when copying from comments as Stack Exchange inserts invisible characters). – Neil – 2017-07-20T12:53:14.880

Beautyful! Many things for me to learn in there. – cdm – 2017-07-23T20:51:21.113

0

Java 8, 149 bytes

q->{int l=q.length,s=(l+1)/3,a=0,b=0,c=0,i=0;for(;i<s;a+=q[i++]);for(i=s,s=l/3*2+(l%3<1?0:1);i<s;b+=q[i++]);for(i=s;i<l;c+=q[i++]);return a==b&b==c;}

Takes the input as an int[].

Explanation:

Try it here.

q->{                 // Method with int-array parameter and boolean return-type
  int l=q.length,    //  Length of the input-array
      s=(l+1)/3,     //  (Length + 1) divided by 3
      a=0,b=0,c=0,   //  Three sums starting at 0
      i=0;           //  Index-integer
  for(;i<s;          //  Loop (1) from 0 to `s1` (exclusive)
    a+=q[i++]        //   And increase `a` with the next digit
  );                 //  End of loop (1)
  for(i=s,s=l/3*2+(l%3<1?0:1);i<s;
                     //  Loop (2) from `s1` to `s2` (exclusive)
    b+=q[i++]        //   And increase `b` with the next digit
  );                 //  End of loop (2)
  for(i=s;i<l;       //  Loop (3) from `s2` to `l` (exclusive)
    c+=q[i++]        //   And increase `c` with the next digit
  );                 //  End of loop (3)
  return a==b&b==c;  //  Return if `a`, `b` and `c` are equal
}                    // End of method

Here is an overview of the 0-indexed (exclusive) parts for each length:

Length:  Parts:    0-indexed (exclusive) parts:

 3       1,1,1     0,1 & 1,2 & 2,3
 4       1,2,1     0,1 & 1,3 & 3,4
 5       2,1,2     0,2 & 2,3 & 3,5
 6       2,2,2     0,2 & 2,4 & 4,6
 7       2,3,2     0,2 & 2,5 & 5,7
 8       3,2,3     0,3 & 3,5 & 5,8
 9       3,3,3     0,3 & 3,6 & 6,9
10       3,4,3     0,3 & 3,7 & 7,10
...
  • For a we loop from 0 to (length + 1) / 3) (this value is now stored in s);
  • For b we loop from s to length / 3 * 2 + (0 if length modulo-3 is 0; 1 if length modulo-3 is 1 or 2) (this value is now stores in s);
  • For c we loop from s to length.

(all three loops are 0-indexed exclusive)

Kevin Cruijssen

Posted 2017-07-17T16:38:58.170

Reputation: 67 575

0

JavaScript, 129, 104 bytes

([...n],l=n.length/3+.5|0,r=(b,e=b*-4,z=0)=>n.slice(b,e).map(x=>z-=x)&&z)=>r(0,l)==r(-l)&&r(l,-l)==r(-l)

The function r slices the string based on parameters b and e, and then sums the digits and returns the value.

In order to slice in the correct sizes, we divide the length by 3 and round the result. Calling slice(0,result) gives us the first block, slice(result,-result) gives us the second, and slice(result) gives us the last. Due to the way I am calling slice, I used slice(result,4*result) instead of the last one but it gives the same result.

Finally, I compare the results show the values are equal.

Edit: same principle, better golfing

Grax32

Posted 2017-07-17T16:38:58.170

Reputation: 1 282

Is it possible to change && to & in JavaScript? Both second-hand checks (&&z and &&y[1]==y[2]) doesn't seem to modify values, so if it is possible, it shouldn't affect the result from what I can see. – Kevin Cruijssen – 2017-07-18T12:00:22.210

I will take a look. & is a bit operation vs && being a logical one, so it will change the output to 1 or 0 instead of true or false, but that works great in this case. – Grax32 – 2017-07-18T14:17:57.570

0

Röda, 82 bytes

f s{n=((#s+1)//3)[s[:n],s[n:#s-n],s[#s-n:]]|[chars(_)|[ord(_)-48]|sum]|[_=_,_=_1]}

Try it online!

Explanation:

f s{ /* function declaration */
    n=((#s+1)//3)
    [s[:n],s[n:#s-n],s[#s-n:]]| /* split the string */
    [ /* for each of the three strings: */
        chars(_)|    /* push characters to the stream */
        [ord(_)-48]| /* convert characters to integers */
        sum          /* sum the integers, push the result to the stream */
    ]|
    [_=_,_=_1] /* take three values from the stream and compare equality */
}

fergusq

Posted 2017-07-17T16:38:58.170

Reputation: 4 867