1

Am trying to represent two arrays integer members summation into one as the below example:

      int[] array1 = {1,0}
      int[] array2 = {5} 
      int[] result = {1,5}
  OR
      int[] array1 = {2,4}
      int[] array2 = {3,6} 
      int[] result = {6,0}

(minding the summation carry as well)) and so on ... , below is my attempt , am but it didn't pass all test scenarios , any missing part ?

public static int[] Process(int[] arr1, int[] arr2)
{
    int sum = 0;
    int length1 = 0;
    int length2 = 0;
    int size = 0;
    int carry = 0;

    if (arr1.Length > arr2.Length) { size = arr1.Length; }
    else { size = arr2.Length; }

    int[] RepArray = new int[size+1];

    for (int i = 0; i < size; i++)
    {

        sum = ( (length1 - i >= 0) ? arr1[length1  - i] : 0) + ( (length2 - i >= 0) ? arr2[length2 - i] : 0) + carry;

        RepArray[(size - i)] = sum % 10;
        carry = sum / 10;
    }

    return RepArray;


}
Wesam
  • 932
  • 3
  • 15
  • 27
  • could you please share the input for which you are getting error? – Vimit Dhawan Sep 15 '19 at 18:38
  • {1,2,3} and {1,2}; but the error or the input are not the point , the point is the logic it self – Wesam Sep 15 '19 at 18:43
  • How do you know the size in advance without considering how many digits the carry might add? – גלעד ברקן Sep 15 '19 at 18:57
  • Can you explain the rules ie how does {1,0} + {5} = {1,5} ? And for the love of $DEITY -why are you doing this?? – iakobski Sep 15 '19 at 19:02
  • @גלעדברקן using this line of code (the biggest array length +1 ) int[] RepArray = new int[size+1]; – Wesam Sep 15 '19 at 19:08
  • @iakobski 10 + 5 = 15 ( array = {1,5} ) 24 + 36 = 60(4+6 have a carry of 1 , we move it to 2+3 so it is 2+3+1) which adds up to 60 = {6,0} – Wesam Sep 15 '19 at 19:11
  • 1
    Ok so ignoring my second question why don’t you simply convert the array into a single number, do the arithmetic then convert it back to this odd array representation? – iakobski Sep 15 '19 at 19:22
  • @iakobski , that is the whole point of algorithm / data-structure questions buddy , is to solve them this way . i could have just used one of many ready .net libraries . plus the addition of single numbers will result in different result ex (2+3 = 5 , 4+6 = 10 , 5+10 = 15 or 510({5,10}) not 60 which is wrong here) – Wesam Sep 15 '19 at 19:37
  • The closest thing to a real question in your post is your mention of `IndexOutOfRangeException`. See marked duplicate for debugging advice. Beyond that, architecturally it seems to me your main problem is that you need to take into account different array lengths where you have fewer significant digits in a number than in another. This means working your way from the end of the arrays, with an index dedicated to each array, and when you run out of elements (i.e. the array index is < 0), treating that as `0`. – Peter Duniho Sep 15 '19 at 23:51

2 Answers2

2
static void Main(string[] args)
{
    int[] left = { 1, 0 };
    int[] right = { 5 };
    int[] actual = Sum(left, right);
    int[] expected = { 1, 5 };
    bool ok = actual.SequenceEqual(expected); // true
}

static int[] Sum(int[] left, int[] right)
{
    var length = Math.Max(left.Length, right.Length);
    left = Pad(left, length);
    right = Pad(right, length);
    var max = length - 1;

    bool carry = false;
    var stack = new Stack<int>(left.Zip(right, (Left, Right) => new { Left, Right })
        .Reverse()
        .Select((i, index) =>
        {
            var res = i.Left + i.Right;
            if (carry)
                res++;
            carry = res > 9 && index < max;
            if(carry)
                res %= 10;
            return res;
        }));

    var last = stack.Pop();
    return stack.Concat(new[]
                        {
                            last % 10,
                            last / 10 // remove this line to prevent array expanding
                        })
                .Reverse()
                .SkipWhile(i => i == 0) // remove this line to prevent array shrinking
                .ToArray();
}

static int[] Pad(int[] array, int length) =>
    new string(array.Select(i => i.ToString().Single()).ToArray())
        .PadLeft(length, '0')
        .Select(c => int.Parse(c.ToString()))
        .ToArray();

Or as @iakobski said:

static void Main(string[] args)
{
    int[] left = { 1, 0 };
    int[] right = { 5 };
    int[] actual = Sum(left, right);
    int[] expected = { 1, 5 };
    bool ok = actual.SequenceEqual(expected); // true

    int[] Sum(int[] arg1, int[] arg2) =>
        ToArray(ToInt(arg1) + ToInt(arg2));

    int ToInt(int[] array) =>
        int.Parse(new string(array.Select(i => i.ToString().Single()).ToArray()));

    int[] ToArray(int i) =>
        i.ToString().Select(c => int.Parse(c.ToString())).ToArray();
}
CSDev
  • 3,177
  • 6
  • 19
  • 37
0

Iterative approach:

private static int[] process(int[] arr1, int[] arr2) {
  int len = Math.max(arr1.length, arr2.length);
  int[] shorter = arr1.length < len ? arr1 : arr2;
  int[] longer = arr1.length == len ? arr1 : arr2;
  int offset = longer.length - shorter.length;

  int[] result = new int[len];
  int carry = 0;

  for (int i = shorter.length - 1; i >= 0; i--) {
    int sum = shorter[i] + longer[offset + i] + carry;
    carry = (sum > 9) ? 1 : 0;
    result[offset + i] = sum - 10 * carry;
  }

  for (int j = offset - 1; j >= 0; j--) {
    int sum = longer[j] + carry;
    carry = (sum > 9) ? 1 : 0;
    result[j] = sum - 10 * carry;
  }

  if (carry > 0) {
    return resizeByOne(carry, result);
  }

  return result;
}

private static int[] resizeByOne(int positionZero, int[] digitsSum) {
  int[] resized = new int[digitsSum.length + 1];
  resized[0] = positionZero;
  for (int i = 1; i < resized.length; i++) {
    resized[i] = digitsSum[i - 1];
  }
  return resized;
}

BigInteger approach:

private static int[] process(int[] arr1, int[] arr2) {
  BigInteger num1 = toNumber(arr1);
  BigInteger num2 = toNumber(arr2);
  BigInteger sum = num1.add(num2);
  return toArray(sum);
}

private static int[] toArray(BigInteger number) {
  String digits = number.toString();
  return IntStream.range(0, digits.length())
                  .map(digits::charAt)
                  .map(Character::getNumericValue)
                  .toArray();
}

private static BigInteger toNumber(int[] digits) {
  return new BigInteger(
          Arrays.stream(digits)
                .mapToObj(String::valueOf)
                .collect(Collectors.joining()));
}
Oleksii Zghurskyi
  • 3,967
  • 1
  • 16
  • 17