views:

3838

answers:

13

I found this question online and have been struggling to come up with an answer to it on my own.

Bonus question I found. Write hello world in C without using a semicolon.

+2  A: 

Here's a hint.

Crashworks
+7  A: 

Answer to bonus question:

#error "Hello world"
liori
You can't actually run that as an executable now can you?
Skizz
Well, the question did not state anything about being compilable... still it prints the string.
liori
+12  A: 

The bonus question is quite easy:

#include <stdio.h>
int main (int argc, char *argc [])
{
  while (printf ("Hello world!\n") == 0)
  {
  }
}

although there are lots of semi-colons in the #include'd file - is that OK?

Skizz

Skizz
Haven't thought of that :-)
liori
+5  A: 

Since 0 in C means false you could just do something like the following. All three args would have to be positive.

I'm very rusty at C. so, Pseudo C:

ct=0;
while(var1 && var2 && var3){
    var1--;
    var2--;
    var3--;
    ct++;
}
printf("%d",ct);
Tom Hubbard
I guess you need a subtraction there.
liori
Yeah, that would help.
Tom Hubbard
I'm not sure why the downvote, since this answer essentially duplicates the one below it.
rtperson
Same fail as the other--any var starting below 0 screws you up.
Bill K
@rtperson, it was an infinite loop for three values over zero when first posted.
Nosredna
+31  A: 

Smallest number (for non-negative numbers):

int smallest(int a, int b, int c) {
  int s = 0;
  while (a && b && c) {
    s++;
    a--; b--; c--;
  }
  return s;
}

Hello world:

#include <stdio.h>

int main() {
  if (printf("Hello world")) {}
}

Edit:

A variation of the above function working for all integers:

int smallest(int a, int b, int c) {
  int test = INT_MIN;
  while ((a-test) && (b-test) && (c-test))
    test++;
  return test;
}
sth
technically you're comparing each variable to 0
hasen j
But I'm not using any comparison operators...
sth
Fail if any of the values start out below zero.
Bill K
owned sir. .
I think it could be fixed if you add MAXINT+1 to each variable before the thing starts, then subtract MAXINT+1 before you return
Bill K
(Not quite right I think, but something like that should work. Maybe without the +1 because that would make it go negative and screw up the entire works)
Bill K
Add MAXINT + 1? What if one of your numbers is MAXINT?
Nosredna
um.. with the values 1, 2, 3 your "fixed" version takes 7 seconds on my box. (2 with optimizations).
Evan Teran
Of course this is not efficient. But if you'd want a fast function for real use, you would just use comparison operators...
sth
A: 

Answer to Bonus Question

abelenky
+24  A: 

You can use bit twiddling to get the min or two integers, also unlike the other answers which use repeated subtraction, this solution supports negative numbers.

(min/max from http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax)

#include <limits.h>
#include <stdio.h>

int main() {
    int x = 2;
    int y = 1;
    int z = 3;
    int r;

    r = y + ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1)));
    r = z + ((r - z) & ((r - z) >> (sizeof(int) * CHAR_BIT - 1)));

    printf("%d\n", r);
}

NOTE: this depends on integers being implemented with 2's complement. I think this is fair game since we are talking about using tricks to do something which has an obvious and simpler solution anyway.

Evan Teran
+1 This one actually works for negative numbers too.
Matt Kane
+18  A: 

Without using a comparison operator and handles negative numbers (using minmax)

int main() {
    int v1 = smallest(-12, 12, 13);
    int v2 = smallest(-12, -14, -13);
    int v3 = smallest(11, 12, 13);
}

int smallest(int a, int b, int c)
{
   return min(min(a, b), c);
}

int min(int a, int b)
{
    a -= b;
    a &= a >> 31;
    a += b;
    return a;
}
Gavin Miller
awesomest! I was trying a bit shifting solution and it descended quickly into hell. Glad I hit "load new answers" before submitting.
Bill K
Of course, you're assuming that ints aren't larger than 32 bits (not required by the standard).
Nick Bastin
Chuck
+3  A: 

Another example:

void main()
{
   if(printf("Hello World!")){}
}

Yet another example:

void main()
{
    printf("Hello World!") nosemicolon
}

Compile with:

gcc -Dnosemicolon=; ctest.c -o ctest
Secko
In your second example you are still using a semicolon. If this was allowed then you could turn all the comparison operators into macros and cheat for the first challenge.
dreamlax
I just thought it would be fun. It's just a way of excluding it from the code.
Secko
Please don't use void main(), even in joke code.
kmm
@kmm A joke is a joke!
Secko
I liked the joke. hehehe
bgbg
+3  A: 

Here's my smallest of three solution. It doesn't use the inefficent while loop and appears to cope with negative values. I haven't tested it thoroughly but the maths looks OK to me:

#include <stdio.h>

int myabs (int a)
{
  return (((~a) + 1) & (a >> 31)) | (a & ~(a >> 31));
}

int smaller (int a, int b)
{
  return (a + b - myabs (a - b)) / 2;
}

int main (int argc, char *argv [])
{
  int
    a, b, c;

  if (argc != 4)
  {
    printf ("Error\n");
  }
  else
  {
    a = atoi (argv [1]);
    b = atoi (argv [2]);
    c = atoi (argv [3]);

    printf ("Smallest of %d, %d and %d is %d\n", a, b, c, smaller (smaller (a, b), c));
  }
}

Skizz

Skizz
Isn't != a comparison operator?
Nosredna
@Nosredna it is!
Secko
Yeah I'm sure he just forgot because it could pretty easily be changed to if(!(argc - 4))--and that has nothing to do with the algorithm to implement the math part anyway.
Bill K
another implementation of abs: http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs
Christoph
Great job for implementing abs, but I think it would be allowable to get abs() from the math lib as well.
Nosredna
+1  A: 

Not the fastest implementation, but more general (ie computes the minimum of an arbitrary number of integers), works with negative numbers and reasonably clear:

#include <limits.h>

int sign(int x)
{
    // portable, no branching:
    return (x > 0) - (x < 0);

    // non-portable, no comparisons:
    return +1 | (x >> (sizeof(int) * CHAR_BIT - 1));
}

int abs(int x)
{
    return sign(x) * x;
}

int min2(int a, int b)
{
    return ((a + b) - abs(a - b)) / 2;
}

int _min(unsigned n, int values[n])
{
    int m = INT_MIN;
    while(n--) m = min2(m, values[n]);
    return m;
}

#define min(...) \
    _min(sizeof((int []){ __VA_ARGS__ }) / sizeof(int), (int []){ __VA_ARGS__ })

extern int printf(const char *, ...)

int main(void)
{
    printf("%i", min(-5, 1, -2));
}
Christoph
your sign function uses comparison operators...
@ilproxyil: that's true; but the requirement 'don't use comparison operators' is pretty arbitrary; a far more useful requirement would be 'don't use branching'; anyway, I added a comparison-free version
Christoph
A: 

Reference: http://stackoverflow.com/questions/476800/comparing-two-integers-without-any-comparison

Next, we can raise a question to compare four integers. :)

arsane
A: 

int main() { int v1 = smallest(-12, 12, 13); int v2 = smallest(-12, -14, -13); int v3 = smallest(11, 12, 13); }

int smallest(int a, int b, int c) { return min(min(a, b), c); }

int min(int a, int b) { a -= b; a &= a >> 31; a += b; return a; }

Above program is working, but i dint get logic......why shifting 31 times???

shivu