Dan
Dan

Reputation: 157

Array Splitting Scenario

so I'm currently trying to do this scenario: Given a non-empty array, return true if there is a place to split the array so that the sum of the numbers on one side is equal to the sum of the numbers on the other side. Examples:

canBalance([1, 1, 1, 2, 1]) → true
canBalance([2, 1, 1, 2, 1]) → false
canBalance([10, 10]) → true
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Array_Split
{
    class Program
    {
        public static bool Balance(int[] data)
        {
            int lpoint = 0;
            int rpoint = data.Length - 1;
            int ltotal = data[lpoint];
            int rtotal = data[rpoint];

            while (lpoint < rpoint)
            {
                if (ltotal == rtotal)
                {
                    lpoint++;
                    rpoint--;
                    ltotal = ltotal + data[lpoint];
                    rtotal = rtotal + data[rpoint];

                }
                else if (ltotal < rtotal)
                {
                    lpoint++;
                    ltotal = ltotal + data[lpoint];
                }
                else
                {
                    rpoint--;
                    rtotal = rtotal + data[rpoint];
                }

            }
            if (ltotal == rtotal)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public static void Main(string[] args)
        {
            int[] data2 = new int[] { 1, 1, 1, 2, 1 }; // T
            int[] data3 = new int[] { 2, 1, 1, 2, 1 }; // F
            int[] data4 = new int[] { 10, 10 }; // T

            Console.WriteLine(Balance(data2));
            Console.WriteLine(Balance(data3));
            Console.WriteLine(Balance(data4));
            Console.ReadKey();
        }
    }
}

The expected result should be true, false, true. However, it gives out false, true, true

Upvotes: 2

Views: 92

Answers (3)

Austin T French
Austin T French

Reputation: 5131

A similar solution: But could offer some benefits:

    var sum = balance.ToList().Sum();
    if (sum % 2 == 0)
    {
        var left = 0;
        for (int i = 0; left < sum / 2; i++)
        {
            left+=balance[i];   
        }           
        return (left - (sum - left) == 0);
    }
    return false;

Since in order for a list to be even, it must also have a modulus result of 0, you can save time by skipping those that are obviously not equal on each side.

Sum(5,4,9) % 2 = 0
Sum(5,5,9) % 2 = 1

etc.

And then the code is different, but the algorithm is similar to make certain the left and right match.

Upvotes: 0

Ruzihm
Ruzihm

Reputation: 20249

When the two values are equal, don't change both lpoint and rpoint. Consider what happens in {1,2,1} - they would both try to "claim" the value 2 at index 1, and you would incorrectly return true for that array. So instead, just change lpoint(or rpoint--just not both):

if (ltotal == rtotal)
{
    lpoint++;
    ltotal = ltotal + data[lpoint];    
}
else if ...

Because you're doing the same as whenltotal < rtotal, you can combine it with that block by checking ltotal <= rtotal:

if (ltotal <= rtotal)
{
    lpoint++;
    ltotal = ltotal + data[lpoint];
}
else
{
    rpoint--;
    rtotal = rtotal + data[rpoint];
}

Also, you shouldn't wait for lpoint to equal rpoint to end your loop - that means both sides need to claim some center index/value, which is against the rules. Instead, stop your loop when the points are adjacent:

while (lpoint + 1 < rpoint)

Upvotes: 3

Sam Axe
Sam Axe

Reputation: 33738

I gave this a shot just for fun.

using System;
using System.Linq;
using System.Collections.Generic;


namespace SO_58400592_array_split {
    class Program {
        private static List<int[]> _testCases = new List<int[]>() {
            {new int[] {1,1,1,2,1}},
            {new int[] {2,1,1,2,1}},
            {new int[] {10,10}}
        };

        static void Main(string[] args) {
            for (int index = 0; index < _testCases.Count; index++) {
                Console.WriteLine(CanSplitArray(_testCases[index]));
            }
        }



        static bool CanSplitArray(int[] model) {
            //  special case of 2 elements
            if(2 == model.Length) {
                return model[0] == model[1];
            }

            // sum the model
            int sum = model.Sum();

            //  caculate the value from each end
            int leftSum = 0;
            int rightSum = sum;
            //  start at the first index and end at the penultimate index.
            for (int index = 1; index < model.Length - 1; index++) {
                leftSum += model[index - 1];
                rightSum -= model[index - 1];
                if (leftSum == rightSum) {
                    return true;
                }
            }

            return false;
        }   //  CanSplitArray()

    }   //  Program
}       //  ns

Upvotes: 1

Related Questions