Server Help

Non-Subspace Related Coding - C coding challenge

Bak - Tue Aug 04, 2009 11:35 pm
Post subject: C coding challenge
found these online, thought they were fun so I'll share. no cheating! I'll do one at a time; there's 5 total.

challenge #1: write strlen function without any types in the function body (types such as 'int' or 'char' or 'char*')

here's standard version for reference:
Code: Show/Hide
int strlen(char* s)
{
  int len = 0;

  for (int x = 0; s[x]; ++x)
    ++len;

  return len;
}

Dr Brain - Wed Aug 05, 2009 6:38 am
Post subject:
Took me a few minutes of trying to figure out how to get an extra hidden parameter into the declaration, but recursion is the answer.

Code: Show/Hide
int strlen(char *s)
{
   if (*s) return strlen(s+1) + 1;
   else return 0;
}


Note: I didn't compile or test it, but it gets the general idea across.
Bak - Wed Aug 05, 2009 9:12 am
Post subject:
That's right. Next one is a little easier, but try to do it without cheating (if you cheat don't post answer).

Challenge #2: what's the following code output and why:

Code: Show/Hide
printf("%c", 1["dr brain"]+1);

Dr Brain - Wed Aug 05, 2009 1:27 pm
Post subject:
s

The brackets don't care about order, so 1["dr brain"] is the same as "dr brain"[1], so that whole expression is 'r'+1 or 's'.
Bak - Thu Aug 06, 2009 9:22 am
Post subject:
Challenge #3: Write a program that only prints "dr brain won #2" and has exit code 100 when the process terminates. Don't use any semicolons.
Doc Flabby - Thu Aug 06, 2009 9:45 am
Post subject:
pretty sure this isnt the right way to solve this one icon_smile.gif
Code: Show/Hide

int main()
{
   return printf("dr brain won #2 \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b \b\n")
}

Samapico - Thu Aug 06, 2009 10:22 am
Post subject:
That doesn't compile... return requires a ;

in VS anyway
Samapico - Thu Aug 06, 2009 10:23 am
Post subject:
I'd do something like


if ( exit( printf("dr brain won #2")+85 ) )
{
}

But exit returns a void, so it doesn't compile either
Dr Brain - Thu Aug 06, 2009 11:04 am
Post subject:
Took a lot of head banging to come up with this:

Code: Show/Hide

int main()
{
    if (!pthread_create(malloc(sizeof(pthread_t)), NULL, exit, printf("dr brain won #2\n") + 100 - 16)) {while(1){}}
}


I'd wager there's a better solution than this.
Samapico - Thu Aug 06, 2009 11:10 am
Post subject:
+ 100 - 16 ? lol
Dr Brain - Thu Aug 06, 2009 11:44 am
Post subject:
I had to add a \n at the end because zsh freaks out if it's missing, so it was 16 instead of 15.
Samapico - Thu Aug 06, 2009 11:59 am
Post subject:
...

My point was, + 84 would be simpler tongue.gif
Though I can see the why... but still
Hakaku - Thu Aug 06, 2009 2:44 pm
Post subject:
Samapico wrote:
I'd do something like


if ( exit( printf("dr brain won #2")+85 ) )
{
}

But exit returns a void, so it doesn't compile either

Couldn't you just put this in a while loop instead? As in (not sure if the 1 should go before or after)...

while (exit( printf("dr brain won #2\n")+84 ), 1)
{
}


edit: + \n
Dr Brain - Thu Aug 06, 2009 2:55 pm
Post subject:
Yes, the comma operator was the missing piece of the puzzle. I'd completely forgotten that it existed. Kudos for a more elegant solution.
Initrd.gz - Thu Aug 06, 2009 9:40 pm
Post subject:
Cuz just maybe we don't want to use semicolons in C biggrin.gif
Bak - Thu Aug 06, 2009 11:21 pm
Post subject:
yeah comma operator was the trick, although pthread version was pretty original, i'll post next one in a little bit

if (printf("dr brain won #2"), exit(100), 0) {}
Bak - Thu Aug 06, 2009 11:38 pm
Post subject:
Challenge #4: What's the following code print and why:

Code: Show/Hide
#include <stdio.h>

int i(int i, int ii)
{
   return ii == i;
}

int main()
{
   int (*ii)(int, int) = i;
   int i = 0;

   if (i++ == ++i)
      printf("%i", i + 1);
   else
      printf("%i", i);

   if (ii(i++, ++i))
      printf("%i", i + 1);
   else
      printf("%i", i);

   if (ii(++i, i))
      printf("%i", i + 1);
   else
      printf("%i", i);

   return 0;
}

Samapico - Thu Aug 06, 2009 11:49 pm
Post subject:
Never seen that comma operator... well... except in a for statement...

So basically, the value returned by the whole expression is the result of the part after the last comma?


And holy shit, that's a lot of i's
Samapico - Fri Aug 07, 2009 12:00 am
Post subject:
hmm... ii would be a pointer to the function...

i++ == ++i
would be false, and increments i twice...

> 2

you call ii with (2, 3), which returns false, i becomes 4

> 4

you call ii with ... I guess it depends in which order arguments are evaluated. ......... hmmmmm hold on a second. I think they're evaluated in reverse order... which means my past reasoning doesn't work.


The first if block is fine...
>2
the next one...
i = 2
second argument evaluated first, gives 3, then first argument, gives 3 also; i becomes 4 after
so... it returns true
> 5

now i = 4
you call ii with (5, 4) -> false
> 5

So...
output:
> 255
Bak - Fri Aug 07, 2009 1:41 am
Post subject:
Quote:
So basically, the value returned by the whole expression is the result of the part after the last comma?
yeah

It gets even more confusing in C++ where you can do operator overloading. Consider the following code:

Code: Show/Hide
#include <stdio.h>

struct EqualInt
{
   int i;

   EqualInt operator++() { ++i; return *this; } // preincrement
   EqualInt operator++(int) { EqualInt copy = *this; ++i; return copy; } // post increment
};

bool operator==(const EqualInt &left, const EqualInt &right)
{
   return left.i == right.i;
}

int main()
{
   EqualInt a;

   int i = 0;

   if (i++ == ++i)
      printf("true\n");
   else
      printf("false\n");

   if (a++ == ++a)
      printf("true\n");
   else
      printf("false\n");

   return 0;
}


the int's get evaluated from left to right, but the a's comparison is actually a function call to operator==, so they get evaluated from right to left and the code ends up printing false then true. This is even the case if you move the operator== into the struct, so it actually ends up constructing the parameter before it constructs the the instance it will be calling.

It's impossible to know if (i++ == ++i) is true or false unless you know the types.
Samapico - Fri Aug 07, 2009 2:30 pm
Post subject:
So did I get it or not? tongue.gif
Bak - Fri Aug 07, 2009 4:21 pm
Post subject:
Yes, you could also compile and check icon_wink.gif

Anyways, Challenge #5 (last one):

Here is a swap function:
Code: Show/Hide
void swap(int* a, int* b)
{
   int temp = *a;
   *a = *b;
   *b = temp;
}


Now rewrite the body of the function to have the same functionality but only using one semicolon, no commas, and not containing "if" anywhere in the body.
JoWie - Fri Aug 07, 2009 5:28 pm
Post subject:
Code: Show/Hide

void swap(int* a, int* b)
{
   *a ^= (*b ^= (*a ^= *b));
}



assuming a != b



or (safe but lame version)

Code: Show/Hide

void swap(int* a, int* b)
{
   #define lol ;
   int temp = *a lol
   *a = *b lol
   *b = temp lol
}

Bak - Fri Aug 07, 2009 6:41 pm
Post subject:
can you do it without assuming a != b?

lol@lame version too
Doc Flabby - Fri Aug 07, 2009 7:02 pm
Post subject:
Code: Show/Hide

void swap(int* a, int* b)
{
       a==b ?   b = a :  *a ^= (*b ^= (*a ^= *b));
}



^^
Bak - Fri Aug 07, 2009 7:54 pm
Post subject:
almost

Code: Show/Hide
..\main.c:6: warning: use of conditional expressions as lvalues is deprecated
..\main.c:6: error: invalid operands to binary ^
..\main.c:6: error: invalid operands to binary ^
..\main.c:6: error: invalid lvalue in assignment

JoWie - Sat Aug 08, 2009 3:12 am
Post subject:
Code: Show/Hide

void swap(int* a, int* b)
{
   a != b && (*a ^= (*b ^= (*a ^= *b)));
}


The only problem with this code, incase you haven't noticed, is that there aren't enough Sequence points. So it has a wrong answer on some compilers
Bak - Sat Aug 08, 2009 11:48 am
Post subject:
good enough
Anonymous - Wed Aug 12, 2009 1:42 pm
Post subject:
Zero semicolons

void swap(int *a, int *b)
{
#define fi i##f
fi (*a != *b) fi (*b = (*b ^ *a)) fi (*a = (*b ^ *a)) fi (*b = (*b ^ *a)) {}
}
Bak - Wed Aug 12, 2009 8:49 pm
Post subject:
orly
Anonymous - Thu Aug 13, 2009 3:14 am
Post subject:
yarly
All times are -5 GMT
View topic
Powered by phpBB 2.0 .0.11 © 2001 phpBB Group