how do I increment a number in C?

A friend of mine has just started learning C and we were both soundly mocking some of his fellow students work which included such gems such as:



int add(int a, int b)
{
    return a + b;
}


I offhandedly pointed out that it would have been far better done as:



int increment_by_one(int a)
{
    return a + 1;
}

int add(int a, int b)
{
    for (int i = 0; i < b; i = increment_by_one(i))
        a = increment_by_one(a);
    return a;
}


This sort of got me thinking about just how arcane and byzantine you could make incrementing a number. Here is one of my earlier attempts:



// This code creates an array one bigger than the input and successively fills in the array with incrementing numbers and returns the final one.
 int make_this_number_bigger_by_one(int a)
 {
     int* p = malloc(increment_by_one(a));
     *p = 1;
     int* q = p;
     for(int i = 0; i < a; i = increment_by_one(i))
         *++q = increment_by_one(*q); //fills the next cell in the array with the increment of the current cell
     return p[a];
 }


This is O(n) in time, O(n) in space, contains a massive memory leak and *++q = increment_by_one(*q); might quite possibly be undefined as to whether it increments before or after the rhs is evaluated. Pretty spiffy IMHO.

The next attempt was:



 //POSSIBLE BUG: This function may not return if the [Collatz conjecture](http://en.wikipedia.org/wiki/Collatz_conjecture) is false. Please report any non-terminating behaviour to <my_email>
int this_number_is_too_small_and_feels_inadequate_comma_make_it_feel_bigger_function (int a)
{
    int b = generate_random_number();
    start:
    if (b == 1)
        goto end;
    if (!(b % 2))
    {
        b /= 2;
        goto start;
    }
    b = 3 * make_this_number_bigger_by_one(b); // b = 3b + 1
    goto start;
    end:
    return a + b;
 }


Finally for the night, I came up with:



//Note: The correctness of this code relies on [Goldbach's conjecture](http://en.wikipedia.org/wiki/Goldbach%27s_conjecture) being wrong. No warranty or certificability of fitness of this code is either given nor implied. Use this code at your own risk
int create_a_number_which_is_bigger_than_the_input_number_but_no_bigger_than_is_absolutely_neccesary(int a)
{
    int n = 2;
    start:
    //increment n by 2
    n = this_number_is_too_small_and_feels_inadequate_comma_make_it_feel_bigger_function(this_number_is_too_small_and_feels_inadequate_comma_make_it_feel_bigger_function(n));
    //check for each possible sum to n
    for (int i = 2; i < n - 1; i = this_number_is_too_small_and_feels_inadequate_comma_make_it_feel_bigger_function(i))
    {
        //if both i and n - i are primes, then this number fulfils goldbach's conjecture, go to the next number.
        if (is_prime(i) && is_prime(n - i))
            goto start;
    }
    return a + n - i;
}


Anybody else willing to have a crack at this? Gratuitous use of gotos is encouraged. build upon the previous posters increment code whenever possible. Generally clear and concise (although not neccesarily efficient) code is rewarded.

Winning entries will be featured on my friend’s final year written exam.

I had it written down, but my dog ate it. Sorry.

Here’s a nice one for your call stack:


int addNatural( int a, int b )
{
    if ( b == 0 )
    {
        return a;
    }
    else
    {
        return addNatural( a + 1, b - 1 );
    }
}

int subtract( int a, int b )
{
    if ( b == 0 )
    {
        return a;
    }
    else
    {
        return subtract( a - 1, b - 1 );
    }
}

int add( int a, int b )
{
    if ( a * b == 0 )
    {
        if ( a == 0 )
        {
            return add( b, a );
        }
        else
        {
            return addNatural( a, b );
        }
    }
    else if ( a * b > 0 )
    {
        if ( a + b < 0 )
        {
            return -addNatural( -a, -b );
        }
    }
    else
    {
        if ( a > b )
        {
            return add( b, a );
        }
        else
        {
            return subtract( a, -b );
        }
    }
}


int increment_by_one(int a)
{
    int result = a;
    while (result - a != 1) {
        result = rand();
    }
}

Assuming a good PRNG the average case is 2[sup]# of bits in an int - 1[/sup] cycles to complete.

::sigh::


return result;

I don’t know C, but I know bad programming.
How about this :


int increment_by_one(int a)
{
    if a == 1 { 
      return 2
     }
    if a == 2 { 
      return 3
     }
    if a == 3 { 
      return 4
     }
    if a == 4 { 
      return 5
     }
    if a == 5 { 
      return 6
     }
    if a == 7 { 
      return 8
     }
    if a == 9 { 
      return 10

    else {
      a = 0;
      increment_by_one(a);
    }
}

Here’s a more explicit increment function:


int increment( int a )
{
    if ( a == 0 )
    {
        return 1;
    }
    else
    {
        return increment( increment( a - 1 ) );
    }
}

Preview is my friend…

I haven’t touched C since I was 16, but how’s this?



i = increment(i);

int increment(int i)
  return mathify(1,i,1);
end

int mathify(int operation, int variable, int adjuster) {
  if (operation == 1) {
    return plus(variable,adjuster);
  } elsif (operation == 2) {
    return minus(variable,adjuster);
  } elsif (operation == 3) {
    return multiply(variable,adjuster);
  } elsif (operation == 4) {
    return divide(variable,adjuster);
  } else {
    printf("Unknown operation discovered in mathify");
    exit(0);
  }
}
int plus (int variable, int adjuster) {
  return variable + adjuster;
}

int minus(int variable, int adjuster) {
  return variable - adjuster;
}

int multiply(int variable, int adjuster) {
  return variable * adjuster;
}

int divide(int variable, int adjuster) {
  return variable / adjuster;
}

I think it needs bugs.

This isn’t bad execution-speed-wise, but it’s certainly nice and obfuscated:



int Increment(int n)
{
    return -(~n);
}


People, this is c!

Nobody’s even approached Shalmanese’s effort because nobody’s allocating memory, throwing void pointers around and taking advantage of the type non-casting!

Let’s see some pointer pointers! Let’s see some mallocs!

Truly bad programming should be language independent.

The code in the OP actually makes sense, if you need a function pointer that adds two numbers. Not that a student would…

Anyway:



char** numbers = //Insert an array containing the string representations of numbers between -9999 and 99999 here
int increment(int base) {
  char* code = malloc(76 + 28 * base);
  strcat("int main(char** argv) {
int init = atoi(argv[0]);
switch(init) {
", code);
  for(int i = 0; i < base; ++i) {
    strcat("case ", code);
    strcat(numbers*, code);
    strcat
  }
  strcat("}
}
", code);

  File* f = fopen("increment.c", O_CREAT | O_RW);
  fprintf(f, "%s", code);
  exec("gcc increment.c increment.out");

  return exec("increment.out");
}

Writes a C program that calculates the increments of interestingly-sized numbers, compile it, run it, and return the result. The nice thing about this code is that once you’ve run it once, incrementing numbers costs “only” one exec; you don’t need to do the file creation twice. Or, you wouldn’t, if I’d bothered to add that part. Also, I think the fopen() call is wrong; it’s been a while since I’ve had to do raw C file I/O.

You guys should consider entering IOCCC’s next efforts.

Obfuscated C Contest

Lots of fun.


int move_to_GQ(int a)
{
    return SDMB_forum + 1;
}

int add(int a, int b)
{
    for (int i = 0; i < b; i = increment_by_one(i))
        a = increment_by_one(a);
    return a;
{Lots of magic + some brussel sprouts
a=Moved to GQ;
}

Uh, SkipMagic, no offense, but this isn’t really a GQ thread, despite how it might appear at first blush. The GQ answer to the question wouldn’t even meet the minimum message length requirements, being, in its entirety,

This thread is more of a contest to produce artfully-bad code, and as such, probably fits better in MPSIMS or IMHO.

You forgot a semicolon.
:wink:

Bumping this because I have a new candidate for most (least?) elegant solution:



//returns a + 1/fraction
double increment_by_fraction(double a, unsigned int fraction);
double increment_by_fraction(double a, unsigned int fraction)
{
	if (!fraction)
		return a + 1.0/((long long) 1 << sizeof(int) * 8);
	else
		return increment_by_fraction(increment_by_fraction(a, fraction << 1), fraction << 1);
}
int increment_by_one(int a)
{
	return (int) increment_by_fraction(a, 1);
}


For the uneducated or simply lazy, the increment_by_fraction function increments by 1/n to a number by recursively calling two child functions which both increment by 1/(n/2). The termination case relies on C’s integer overflow to 0. On a 32 bit machine, it increments a number by 1 by incrementing it by 1/4,294,967,296 4,294,967,296 times. This code also works on machines that are not 32 bit as well as long as long long is bigger than int.

On a 1.6Ghz Pentium M, it takes around 10 minutes to increment 1 number.

Doh, that was in debug mode, in release it’s a demon fast 100 seconds. On my athlon64 desktop, the code should take roughly 50 years to increment (within an order of magnitude or so) and should return an incorrect result is one is using the IEEE 754 spec for doubles… oops.