17
\$\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\$
6
  • 1
    \$\begingroup\$ As I understand it, if you can split it evenly, you should. \$\endgroup\$ Commented Jul 17, 2017 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
    Commented Jul 17, 2017 at 16:46
  • 4
    \$\begingroup\$ Consider using the Sandbox, to avoid such a situation in the future. \$\endgroup\$
    – Mr. Xcoder
    Commented Jul 17, 2017 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
    Commented Jul 17, 2017 at 17:08
  • 6
    \$\begingroup\$ By default, input is allowed to be taken as a string. Can it be taken as an array of digits? \$\endgroup\$
    – Luis Mendo
    Commented Jul 17, 2017 at 22:16

14 Answers 14

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\$
0
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\$
1
  • \$\begingroup\$ It seems straight-forward but it really isn't tbh... Even difficult in 05AB1E due to the non-default splitting. \$\endgroup\$ Commented Jul 17, 2017 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\$
3
\$\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\$
2
  • 1
    \$\begingroup\$ I'd love to read an explanation \$\endgroup\$ Commented Jul 18, 2017 at 11:11
  • \$\begingroup\$ @FelixDombek I've added an explanation. \$\endgroup\$
    – Dennis
    Commented Jul 18, 2017 at 17:08
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\$

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

MATL, 26 bytes

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

Try it online! Or verify all test cases.

\$\endgroup\$
0
1
\$\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\$
1
\$\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\$
2
  • \$\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\$ Commented Jul 18, 2017 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\$
    – Grax32
    Commented Jul 18, 2017 at 14:17
1
\$\begingroup\$

05AB1E, 19 bytes

gUSŽU]₂вXèûSX3÷*£OË

Try it online or verify all test cases.

Explanation:

g                  # Get the length of the (implicit) input-integer
 U                 # Pop and store this length in variable `X`
S                  # Convert the (implicit) input-integer to a list of digits
 ŽU]               # Push compressed integer 7769
    ₂в             # Convert it to base-26 as list: [11,12,21]
      Xè           # Index the length `X` into it (modulair 0-based - i.e. lengths=3,6,..
                   # will index into 11; 4,7,.. into 12; and 5,8,.. into 21)
        û          # Palindromize this integer: 11→111; 12→121; 21→212
         S         # Convert it to a list of digits
          X        # Push length `X` again
           3÷      # Integer-divide it by 3
             *     # Multiply it to each digit in the triplet
              £    # Split input-list of digits into three parts of these sizes
               O   # Sum each inner part
                Ë  # And check if the three sums are all equal
                   # (after which the result is output implicitly)

See this 05AB1E tip of mine (sections How to compress large integers? and How to compress integer lists?) to understand why ŽU] is 7769 and ŽU]₂в is [11,12,21].

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

Husk, 16 15 bytes

ËΣCẊ-mi¡+/3L¹0d

Try it online!

Returns 4 for truthy and 0 for falsy.

Explanation

ËΣCẊ-mi¡+/3L¹0d   Input is a number, say n=34725.
           L¹     Length of n (number of digits): 5
         /3       Divide by 3 (gives a rational number): 5/3
       ¡+         Iterate addition of 5/3
             0    starting from 0: [0,5/3,10/3,5,20/3,25/3,10,..]
     mi           Round each to the nearest integer: [0,2,3,5,7,8,10,..]
   Ẋ-             Differences between adjacent elements: [2,1,2,2,1,2,..]
  C           d   Cut the digits of n to chunks of these lengths: [[3,4],[7],[2,5]]
Ë                 Are these lists equal by
 Σ                sum? (Returns 0 or length+1)
\$\endgroup\$
1
\$\begingroup\$

Java 8, 149 143 140 138 137 bytes

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

-9 bytes thanks to @ceilingcat.

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/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 `i` in the range [0, `s1`):
    a+=q[i++];       //   Increase `a` by every `i`'th digit of the input-array
  for(s=l/3*2-~-l%3/2;i<=s;)
                     //  Loop `i` in the range [`s1`, `s2`):
    b+=q[i++];       //   Increase `b` by every `i`'th digit of the input-array
  for(;i<l;)         //  Loop `i` in the range [`s2`, length):
    c+=q[i++];       //   Increase `c` by every `i`'th digit of the input-array
  return a==b&b==c;} //  Return whether `a`, `b` and `c` are all equal

Here is an overview of the 0-indexed \$[n,m)\$ parts for each length:

Length:  Parts:    0-indexed ranges:

 3       1,1,1     [0,1) & [1,1] & [2,3)
 4       1,2,1     [0,1) & [1,2] & [3,4)
 5       2,1,2     [0,2) & [2,2] & [3,5)
 6       2,2,2     [0,2) & [2,3] & [4,6)
 7       2,3,2     [0,2) & [2,4] & [5,7)
 8       3,2,3     [0,3) & [3,4] & [5,8)
 9       3,3,3     [0,3) & [3,5] & [6,9)
10       3,4,3     [0,3) & [3,6] & [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 and including length / 3 * 2 - ((length + 1) % 3 / 2), where ((length + 1) % 3 / 2 is 0 if the length is divisible by 3 and 1 if not (this value is now stored in s);
  • For c we loop from s to length.
\$\endgroup\$
0
1
\$\begingroup\$

L=tn, 35 bytes

cα;Gi≥l/3ö&i≤(2*l/3-1)öGi≠l¤2MαΣA=c

Explanation:

cα;                                  - convert to digit list
   G                                 - Group to string (will be used to group the middle number)
    i≥l/3ö&i≤(2*l/3-1)ö              - The middle number is limited on its start & end index
                       Gi≠l¤2        - Group every item but the middle one
                             MαΣ     - Map to digit sum
                                A=c  - All sums equals to first sum of list

This returns a list, Only valid if empty list = falsy, and non-empty list = truthy

Note: The language is in progress and I did add stuff (specifically ≤ and ≥ operators) to code golf this. It's still competing though.

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

Japt -x, 19 bytes

Input is a string, output is an integer: 0 for false or >0 for true.

ã á3 ˬ¥U«ÓDˬxÃâ Ê

Try it

ã á3 ˬ¥U«ÓDˬxÃâ Ê     :Implicit input of string U
ã                       :Substrings
  á3                    :Permutations of length 3
     Ë                  :Map each D
      ¬                 :  Join
       ¥U               :  Equal to U?
         «              :  AND NOT
          Ó             :  Bitwise NOT of negation of
           DË           :    Map D
             ¬          :      Split
              x         :      Sum
               Ã        :    End map
                â       :    Deduplicate
                  Ê     :    Length
                        :Implicit output of sum of resulting array
\$\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.