# Triple-balanced numbers

### 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!

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

# Python 2, 9388 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!

# Jelly, 23 bytes

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


Try it online!

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

• It seems straight-forward but it really isn't tbh... Even difficult in 05AB1E due to the non-default splitting. Jul 17 '17 at 21:37

# 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.

# 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)&


## 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)}

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

# 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.

• I'd love to read an explanation Jul 18 '17 at 11:11
• @FelixDombek I've added an explanation. Jul 18 '17 at 17:08

# MATL, 26 bytes

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


# 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 */
}


# 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

• 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. Jul 18 '17 at 12:00
• 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. Jul 18 '17 at 14:17

# 05AB1E, 19 bytes

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


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].

# (non-competing) L=tn, 35

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. So it is not a competing submission.

• Generally better to include (non-competing) in the program title. Nice answer. Aug 22 '20 at 9:21

# Java 8, 149143140138 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.

# 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


# 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)