13
\$\begingroup\$

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!

\$\endgroup\$
  • 1
    \$\begingroup\$ As I understand it, if you can split it evenly, you should. \$\endgroup\$ – totallyhuman Jul 17 '17 at 16:46
  • \$\begingroup\$ @Mr.Xcoder you split it into three parts (it still doesn't work as per @MagicOctopusUnr's comment: when split in three parts, \$\endgroup\$ – Stephen Jul 17 '17 at 16:46
  • 4
    \$\begingroup\$ Consider using the Sandbox, to avoid such a situation in the future. \$\endgroup\$ – Mr. Xcoder Jul 17 '17 at 16:51
  • 2
    \$\begingroup\$ Whoops! 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. \$\endgroup\$ – racer290 Jul 17 '17 at 17:08
  • 5
    \$\begingroup\$ By default, input is allowed to be taken as a string. Can it be taken as an array of digits? \$\endgroup\$ – Luis Mendo Jul 17 '17 at 22:16

10 Answers 10

7
\$\begingroup\$

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!

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

Jelly, 23 bytes

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

Try it online!

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

\$\endgroup\$
  • \$\begingroup\$ It seems straight-forward but it really isn't tbh... Even difficult in 05AB1E due to the non-default splitting. \$\endgroup\$ – Magic Octopus Urn Jul 17 '17 at 21:37
3
\$\begingroup\$

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.

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

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)&
\$\endgroup\$
2
\$\begingroup\$

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.
\$\endgroup\$
  • 1
    \$\begingroup\$ I'd love to read an explanation \$\endgroup\$ – Felix Dombek Jul 18 '17 at 11:11
  • \$\begingroup\$ @FelixDombek I've added an explanation. \$\endgroup\$ – Dennis Jul 18 '17 at 17:08
1
\$\begingroup\$

MATL, 26 bytes

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

Try it online! Or verify all test cases.

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

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)}
\$\endgroup\$
  • \$\begingroup\$ Welcome to PPCG! Have you read the tips pages? There's a lot of scope for golfing your answer down. \$\endgroup\$ – Neil Jul 18 '17 at 10:15
  • \$\begingroup\$ 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). \$\endgroup\$ – Neil Jul 20 '17 at 12:53
  • \$\begingroup\$ Beautyful! Many things for me to learn in there. \$\endgroup\$ – cdm Jul 23 '17 at 20:51
0
\$\begingroup\$

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)

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

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 */
}
\$\endgroup\$
0
\$\begingroup\$

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

\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – Kevin Cruijssen Jul 18 '17 at 12:00
  • \$\begingroup\$ 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. \$\endgroup\$ – Grax Jul 18 '17 at 14:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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