How to Add 1 to the Value of Each Array in C


The challenge

Given an array of integers of any length, return an array that has 1 added to the value represented by the array.

  • the array can’t be empty
  • only non-negative, single digit integers are allowed

Return nil (or your language’s equivalent) for invalid inputs.

Examples:

Valid arrays

[4, 3, 2, 5] would return [4, 3, 2, 6]
[1, 2, 3, 9] would return [1, 2, 4, 0]
[9, 9, 9, 9] would return [1, 0, 0, 0, 0]
[0, 1, 3, 7] would return [0, 1, 3, 8]

Invalid arrays

[1, -9] is invalid because -9 is not a non-negative integer

[1, 2, 33] is invalid because 33 is not a single-digit integer

The solution in C

Option 1:

#include <stdlib.h>
#include<string.h>
#include<stdio.h>

int *up_array(const int *arr, unsigned *count){
  int i, retenue=1;
  int *result;
  int* resultbis;
  result=(int*)calloc(100, sizeof(int));
  resultbis=(int*)calloc(100, sizeof(int));
  if(*count==0){
    return NULL;
  }
  for(i=0; i<*count; i++){
    result[i]=arr[i];
  }
  for(i=1; i<=*count; i++){
    resultbis[i]=0;
  }
  resultbis[0]=1;
  
  for(i=*count-1; i>=0; i--){
    if(result[i]<0||result[i]>9){
      return NULL;
    }
    if(retenue==1){
      result[i]+=1;
      retenue=0;
      printf("%d ", result[i]);
        if(result[i]==10){
          result[i]=0;
          retenue=1;
          printf("%d\n", result[i]);
        }
    }
  }
  printf("%d\n", retenue);
  for(i=0; i<*count; i++){
    printf("%d ", result[i]);
  }
  if(retenue==1){
    *count+=1;
    return resultbis;
  }
  return result;
}

Option 2:

#include <stdlib.h>
#include <string.h>

int* up_array(const int* arr, unsigned* count)
{
  if(*count == 0)
    return NULL;
  
  int* res = (int*)calloc(1, *count * sizeof(int));
  int rest = 0;
  for (size_t i = *count; i > 0; --i)
  {
    int actual = arr[i - 1];
    if (actual >= 10 || actual < 0)
    {
      free(res);
      return NULL;
    }
    res[i - 1] += actual + rest;
    rest = 0;
    if (i == *count)
    {
      res[i - 1] += 1;
    }
    if (res[i - 1] >= 10)
    {
      res[i - 1] %= 10;
      rest = 1;
    }
  }

  if (rest > 0)
  {
    int* temp = res;
    res = (int*)calloc(1, (*count + 1u) * sizeof(int));
    res[0] = rest;
    memcpy(res + 1, temp, *count);
    free(temp);
    ++*count;
  }

  return res;
}

Option 3:

#include <stdlib.h>

int *up_array(const int *arr, unsigned *count)
{
  int * sum = malloc(((*count)+1) * sizeof(int));
  int temp_sum = 0;
  int carry = 1;
  
 if((*count) == 0)
     return NULL;
  
  for(int i=(*count)-1;i>=0;i--)
    {

    if(arr[i] < 0 || arr[i] > 9)
      return NULL;
    
    temp_sum = arr[i] + carry;
    if( temp_sum >= 10)
      {
      sum[i] = temp_sum%10;
      carry = temp_sum/10;
    } 
    else
      {
      sum[i] = temp_sum;
      carry = 0; 
    }
  }
  
  if(carry == 1)
    {

    int temp;
    for(int j=(*count);j>1; j--)
      {
      sum[j] = sum[j-1];
     
    }
    sum[0] = carry;
    
    (*count)++;
  }
  
  return sum; 
}

Test cases to validate our solution

#include <criterion/criterion.h>

#define ARRAY_COUNT(a) (sizeof(a) / sizeof((a)[0]))

int *up_array(const int *arr, unsigned *count);
void do_test(const int *arr, unsigned count, const int *expected, unsigned expcount);
void complete_test();

// TODO: Replace examples and use TDD development by writing your own tests.

Test(sample_test, example_tests)
{
    {
        int arr[] = {2,3,9},
            exp[] = {2,4,0};
        do_test(arr, ARRAY_COUNT(arr), exp, ARRAY_COUNT(exp));
    }
    {
        int arr[] = {4,3,2,5},
            exp[] = {4,3,2,6};
        do_test(arr, ARRAY_COUNT(arr), exp, ARRAY_COUNT(exp));
    }
    {
        int arr[] = {1,-9};
        do_test(arr, ARRAY_COUNT(arr), NULL, 0);
    }
    {
        int arr[] = {0,4,2},
            exp[] = {0,4,3};
        do_test(arr, ARRAY_COUNT(arr), exp, ARRAY_COUNT(exp));
    }
    {
        int arr[] = {9,9,9},
            exp[] = {1,0,0,0};
        do_test(arr, ARRAY_COUNT(arr), exp, ARRAY_COUNT(exp));
    }
    {
        int arr[] = {9,2,2,3,3,7,2,0,3,6,8,5,4,7,7,5,8,0,7},
            exp[] = {9,2,2,3,3,7,2,0,3,6,8,5,4,7,7,5,8,0,8};
        do_test(arr, ARRAY_COUNT(arr), exp, ARRAY_COUNT(exp));
    }  
    complete_test();
}