Wednesday, November 19, 2014

Solution to the C programming puzzles

There were the two puzzles (posted earlier).

The first one:

Write a method in C, which will print ";", but does not use any semi-colons anywhere. Assume you have printf available.


We can do a print of a semi-colon, using the ascii value, but it does not end there... C programs use semi-colons as statement separators. If statements don't however, and so the code will look like this:



void print() {
  if (printf("%c", 59)) {}
}




The second one:

Write a C program to print "hello world!" 2014 times. The catch is, it must fit inside an 80x25 page and must not use the characters f,o,w,?,&,| (last three are question mark, ampersand and pipe). Assume you have printf available (and don't need to #include the header).

This one is more difficult. The printing is the easy part (and so we assumed we could use printf etc). The size limits do not allow us to write the print 2014 times (and that is a silly solution, anyway). #define etc macro tricks to do that are clever, but still silly :-)

The difficult part is that not using those characters does not allow us to use if statements (or conditionals), for and while loops. There might still be ways to loop and have conditionals, but that is probably weird C territory [that will still be a valid solution to the puzzle].

One way to do things multiple times without using loops is using recursion. But, since we cannot use if, we need a different way to stop the recursion.

Even though we cannot use if, we are allowed (=), so we can at least tell when we have recursed 2014 times, count == 2014 will be 1 or 0, depending on count.

In order to use that, we use function pointers! If count == 2014 is 0, we recurse, otherwise we return. We do this by calling the appropriate function, using the function pointers stored in an array a. a[0] will be a pointer to the recursive function, a[1] will be a pointer to the function which stops the recursion (basically returns).

The code will look something like this:


int stop(int n){}

int print(int n){
  int (*a[2])(int) = { print, stop };
  printf("hell%c %c%crld!",111,119 ,111);
  n++;
  a[n==2014](n);
}

int main(){
  print(0);
}


The code above can be made better by counting down and checking against 0 (instead of 2014), that way we don't have to hardcode 2014.

One could also use integer division, instead of ==. count/2014 is 0 or 1 depending on whether 0 <= count < 2014 etc.

That will get rid of the use of any conditional, including the equality check.

No comments:

Post a Comment