program

C

Christian Bau

Sidney Cadot said:
Consider two programs:

/*** a.c ***/
#include <stdio.h>
int main(void)
{
fopen("somefile","rb");
return 0;
}

/*** b.c ***/
in main(void)
{
return 0;
}

Would it be legal for a compiler (through optimization), to emit the
same code for program a.c and b.c ?

I don't think so. The call to fopen () probably introduces observable
behavior that cannot be optimised away. Even if your C program doesn't
care, the outside world might care.
 
J

Joona I Palaste

Joona I Palaste said:
Ben Pfaff said:
Joona I Palaste said:
Alexander Bartolich <[email protected]> scribbled the following:
#include <limits.h>
#include <stdio.h>
#include <ctype.h>
int main(){int c;int n[1<<CHAR_BIT]={0};while(EOF!=(c=getchar()))
n[tolower(c)]++;printf("a=%d b=%d c=%d\n",n['a'],n['b'],n['c']);
return 0;}

Here's my version. 254 characters.

#include <stdio.h>
#include <ctype.h>
int a[3]={0};int count(void){int c=getchar();return c==EOF?0:((tolower(c)=='a'?
a[0]++:tolower(c)=='b'?a[1]++:tolower(c)=='c'?a[2]++:0),count());}int
main(void){return count(),printf("%d %d %d\n",a[0],a[1],a[2]),0;}
My entry (184 characters):
int main(){int getchar(),printf(const char*,...),tolower();int c,n[4]={0};while
((c=tolower(getchar()))>=0)n[c=='a'?0:c=='b'?1:c=='c'?2:3]++;printf("a=%d,b=%d\
,c=%d\n",*n,n[1],n[2]);}
Well, I have to say your code fits into smaller space, but you not only
use a two-statement function, one of those statements is a while loop.
My version only used one-statement functions, with no loops or if
statements. Now if I could only somehow remove the need for the local
variable c. (Don't suggest making it global...)

I have two more entries. Both consist of only one function.

First version (191 characters), one local variable declaration, one
statement.

#include <stdio.h>
#include <ctype.h>
int a[4]={0};int main(void){int c=tolower(getchar());return c==EOF?(printf(
"%d %d %d\n",a[0],a[1],a[2]),0):(a[c=='a'?0:c=='b'?1:c=='c'?2:3]++,main());}

Second version (200 characters), no local variables, one statement. But
I'm not sure if this is completely ISO compliant because it modifies
main()'s first parameter.

#include <stdio.h>
#include <ctype.h>
int a[4]={0};int main(int c,char**v){return(c=tolower(getchar()))==EOF?(printf
("%d %d %d\n",a[0],a[1],a[2]),0):(a[c=='a'?0:c=='b'?1:c=='c'?2:3]++,main(c,v));
}

I don't think the program could be done (assuming it has to print the
correct output) without using variables at all.

--
/-- Joona Palaste ([email protected]) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"You can pick your friends, you can pick your nose, but you can't pick your
relatives."
- MAD Magazine
 
T

Tak-Shing Chan

As for the counting, I surely agree. However, I/O has side-effects (by
definition), so my gut feeling is that the "as-if" rule should not apply.

I believe that it is optimizable, because the semantic
descriptions are not violated.
For this, I'd welcome a reference.

C99 5.1.2.3. Paragraph 1 states, ``issues of optimization
are irrelevant''. Paragraph 3 states, ``an actual implementation
need not evaluate part of an expression if it can deduce that its
value is not used and that no needed side effects are produced''.
I am quite conviced you are not right about this, although not
absolutely certain.

Allow me to rephrase the point in contention.


Consider two programs:

/*** a.c ***/
#include <stdio.h>
int main(void)
{
fopen("somefile","rb");
return 0;
}

/*** b.c ***/
in main(void)
{
return 0;
}

Would it be legal for a compiler (through optimization), to emit the
same code for program a.c and b.c ?

This question is best asked in comp.std.c.
I think this question is too interesting to be buried deep in a playful
thread. I will re-ask this at top level to get more exposure.

Best regards,

Sidney

Tak-Shing
 
S

Sean Kenwrick

Ben Pfaff said:
Joona I Palaste said:
Alexander Bartolich <[email protected]> scribbled the following:
begin followup to Joona I Palaste:
OK, I bid $300.
Cool.
So the financial damage of this piece of code is $50 per line.
OTOH I have some doubts whether the OP can compile, run, format,
present and explain it.
#include <limits.h>
#include <stdio.h>
#include <ctype.h>
int main(){int c;int n[1<<CHAR_BIT]={0};while(EOF!=(c=getchar()))
n[tolower(c)]++;printf("a=%d b=%d c=%d\n",n['a'],n['b'],n['c']);
return 0;}

Here's my version. 254 characters.

#include <stdio.h>
#include <ctype.h>
int a[3]={0};int count(void){int c=getchar();return c==EOF?0:((tolower(c)=='a'?
a[0]++:tolower(c)=='b'?a[1]++:tolower(c)=='c'?a[2]++:0),count());}int
main(void){return count(),printf("%d %d %d\n",a[0],a[1],a[2]),0;}

My entry (184 characters):

int main(){int getchar(),printf(const char*,...),tolower();int c,n[4]={0};while((c=tolower(getchar()))>=0)n[c=='a'?0:c=='b'?1:c=='c'?2:3]++;printf("a=%d,b=
%d\
,c=%d\n",*n,n[1],n[2]);}
--

Can anyone beat 144 characters? (It assumes ASCII though) ......


#include<stdio.h>
int n[256];int main(){int c;while((c=getchar())>=0)
n[c]++;printf("a=%d,b=%d,c=%d\n",n[97]+n[65],n[98]+n[66],n[99]+n[67]);}


Sean
 
S

Sean Kenwrick

Morris Dovey said:
Ben said:
Pfui! Then it becomes cheaper to add the #include and drop two
prototypes. I'll follow your lead and drop the explicit void arg list
for main() and substitute *n for n[0]:

#include <stdio.h>
int
c,n[4]={0},toupper(),main(){while(0<(c=toupper(getchar())))++n[c-'A'?c-'B' ?c-'C'?3:2:1:0];printf("A=%d
B=%d C=%d\n",*n,n[1],n[2]);return 0;}

Those mods bring the character count down to 166.

Beat this (assumes ASCII though...)...144 chars

#include<stdio.h>
int n[256];int main(){int c;while((c=getchar())>=0)
n[c]++;printf("a=%d,b=%d,c=%d\n",n[97]+n[65],n[98]+n[66],n[99]+n[67]);}


Sean
 
S

Sean Kenwrick

Sean Kenwrick said:
Morris Dovey said:
Ben said:
Pfui! Then it becomes cheaper to add the #include and drop two
prototypes. I'll follow your lead and drop the explicit void arg list
for main() and substitute *n for n[0]:

#include <stdio.h>
int
c,n[4]={0},toupper(),main(){while(0<(c=toupper(getchar())))++n[c-'A'?c-'B' ?c-'C'?3:2:1:0];printf("A=%d
B=%d C=%d\n",*n,n[1],n[2]);return 0;}

Those mods bring the character count down to 166.

Beat this (assumes ASCII though...)...144 chars

#include<stdio.h>
int n[256];int main(){int c;while((c=getchar())>=0)
n[c]++;printf("a=%d,b=%d,c=%d\n",n[97]+n[65],n[98]+n[66],n[99]+n[67]);}


Sean

By assuming getchar() returns -1 on end of file and letting C assume
implicit int return for main() I can get it down to 131 chars:

#include<stdio.h>
int
n[257];main(){while(n[getchar()+1]++>=0);printf("a=%d,b=%d,c=%d\n",n[98]+n[6
6],n[99]+n[67],n[100]+n[68]);}

Sean
 
J

Joona I Palaste

Sean Kenwrick said:
Sean Kenwrick said:
Morris Dovey said:
Ben Pfaff wrote:
prototypes. I'll follow your lead and drop the explicit void arg list
for main() and substitute *n for n[0]:

#include <stdio.h>
int
c,n[4]={0},toupper(),main(){while(0<(c=toupper(getchar())))++n[c-'A'?c-'B' ?c-'C'?3:2:1:0];printf("A=%d
B=%d C=%d\n",*n,n[1],n[2]);return 0;}

Those mods bring the character count down to 166.

Beat this (assumes ASCII though...)...144 chars

#include<stdio.h>
int n[256];int main(){int c;while((c=getchar())>=0)
n[c]++;printf("a=%d,b=%d,c=%d\n",n[97]+n[65],n[98]+n[66],n[99]+n[67]);}
By assuming getchar() returns -1 on end of file and letting C assume
implicit int return for main() I can get it down to 131 chars:
#include<stdio.h>
int
n[257];main(){while(n[getchar()+1]++>=0);printf("a=%d,b=%d,c=%d\n",n[98]+n[6
6],n[99]+n[67],n[100]+n[68]);}

Well, my version might be 191 characters (60 more than yours), but I
still like it better. It consists of one function which only consists
of one statement, and it's completely ISO compliant as well.
 
S

Sean Kenwrick

Sean Kenwrick said:
Sean Kenwrick said:
Morris Dovey said:
Ben Pfaff wrote:



Pfui! Then it becomes cheaper to add the #include and drop two
prototypes. I'll follow your lead and drop the explicit void arg list
for main() and substitute *n for n[0]:

#include <stdio.h>
int
c,n[4]={0},toupper(),main(){while(0<(c=toupper(getchar())))++n[c-'A'?c-'B'
?c-'C'?3:2:1:0];printf("A=%d
B=%d C=%d\n",*n,n[1],n[2]);return 0;}

Those mods bring the character count down to 166.

Beat this (assumes ASCII though...)...144 chars

#include<stdio.h>
int n[256];int main(){int c;while((c=getchar())>=0)
n[c]++;printf("a=%d,b=%d,c=%d\n",n[97]+n[65],n[98]+n[66],n[99]+n[67]);}


Sean

By assuming getchar() returns -1 on end of file and letting C assume
implicit int return for main() I can get it down to 131 chars:

#include<stdio.h>
int
n[257];main(){while(n[getchar()+1]++>=0);printf("a=%d,b=%d,c=%d\n",n[98]+n[6
6],n[99]+n[67],n[100]+n[68]);}

Sean

I just realised I can get rid of the >=0 in the while condition:

#include<stdio.h>
int
n[257];main(){while(++n[getchar()+1]);printf("a=%d,b=%d,c=%d\n",n[98]+n[66],
n[99]+n[67],n[100]+n[68]);}


128 chars world record!!!!

:)
Sean
 
S

Sean Kenwrick

Sean Kenwrick said:
Ben Pfaff said:
Joona I Palaste said:
Alexander Bartolich <[email protected]> scribbled the following:
begin followup to Joona I Palaste:
OK, I bid $300.

Cool.
So the financial damage of this piece of code is $50 per line.
OTOH I have some doubts whether the OP can compile, run, format,
present and explain it.

#include <limits.h>
#include <stdio.h>
#include <ctype.h>
int main(){int c;int n[1<<CHAR_BIT]={0};while(EOF!=(c=getchar()))
n[tolower(c)]++;printf("a=%d b=%d c=%d\n",n['a'],n['b'],n['c']);
return 0;}

Here's my version. 254 characters.

#include <stdio.h>
#include <ctype.h>
int a[3]={0};int count(void){int c=getchar();return c==EOF?0:((tolower(c)=='a'?
a[0]++:tolower(c)=='b'?a[1]++:tolower(c)=='c'?a[2]++:0),count());}int
main(void){return count(),printf("%d %d %d\n",a[0],a[1],a[2]),0;}

My entry (184 characters):

int main(){int getchar(),printf(const char*,...),tolower();int c,n[4]={0};while
((c=tolower(getchar()))>=0)n[c=='a'?0:c=='b'?1:c=='c'?2:3]++;printf("a=%d,b=
%d\
,c=%d\n",*n,n[1],n[2]);}
--

Can anyone beat 144 characters? (It assumes ASCII though) ......


#include<stdio.h>
int n[256];int main(){int c;while((c=getchar())>=0)
n[c]++;printf("a=%d,b=%d,c=%d\n",n[97]+n[65],n[98]+n[66],n[99]+n[67]);}


Sean
Got it down to 128 chars...

#include<stdio.h>
int
n[257];main(){while(++n[getchar()+1]);printf("a=%d,b=%d,c=%d\n",n[98]+n[66],
n[99]+n[67],n[100]+n[68]);}

Sean
 
J

Joona I Palaste

Sean Kenwrick said:
I just realised I can get rid of the >=0 in the while condition:
#include<stdio.h>
int
n[257];main(){while(++n[getchar()+1]);printf("a=%d,b=%d,c=%d\n",n[98]+n[66],
n[99]+n[67],n[100]+n[68]);}

128 chars world record!!!!

Is there anything saying you have to output the a=, b= and c=? I can
shorten your program to 122 characters:

#include<stdio.h>
int
n[257];main(){while(++n[getchar()+1]);printf("%d,%d,%d\n",n[98]+n[66],
n[99]+n[67],n[100]+n[68]);}

--
/-- Joona Palaste ([email protected]) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"Parthenogenetic procreation in humans will result in the founding of a new
religion."
- John Nordberg
 
J

Joona I Palaste

Joona I Palaste said:
Sean Kenwrick said:
I just realised I can get rid of the >=0 in the while condition:
#include<stdio.h>
int
n[257];main(){while(++n[getchar()+1]);printf("a=%d,b=%d,c=%d\n",n[98]+n[66],
n[99]+n[67],n[100]+n[68]);}
128 chars world record!!!!
Is there anything saying you have to output the a=, b= and c=? I can
shorten your program to 122 characters:
#include<stdio.h>
int
n[257];main(){while(++n[getchar()+1]);printf("%d,%d,%d\n",n[98]+n[66],
n[99]+n[67],n[100]+n[68]);}

It can be made even shorter.

#include<stdio.h>
int
n[323];main(){while(++n[getchar()+67]);printf("%d,%d,%d\n",n[32]+*n,n[33]+
n[1],n[34]+n[2]);}

117 characters! Now *this* is a new world record!
 
J

Joona I Palaste

The programs Sean and I have presented here are fundamentally flawed.
They get stuck in infinite loops.
I just realised I can get rid of the >=0 in the while condition:
#include<stdio.h>
int
n[257];main(){while(++n[getchar()+1]);printf("a=%d,b=%d,c=%d\n",n[98]+n[66],
n[99]+n[67],n[100]+n[68]);}

Notice the while loop condition. ++n[getchar()+1] is only even going to
equal 0 if n[getchar()+1] equalled -1 before evaluation of the
expression, but nothing in Sean's code sets it to -1.
128 chars world record!!!!
Is there anything saying you have to output the a=, b= and c=? I can
shorten your program to 122 characters:
#include<stdio.h>
int
n[257];main(){while(++n[getchar()+1]);printf("%d,%d,%d\n",n[98]+n[66],
n[99]+n[67],n[100]+n[68]);}
It can be made even shorter.
#include<stdio.h>
int
n[323];main(){while(++n[getchar()+67]);printf("%d,%d,%d\n",n[32]+*n,n[33]+
n[1],n[34]+n[2]);}

These also suffer from the same problem.
117 characters! Now *this* is a new world record!

I think the smallest working program (of this kind) would be, assuming
Sean's assumptions, something like this:

#include <stdio.h>
int
n[257]={-1,0};main(){while(++n[getchar()+1]);printf("%d,%d,%d\n",n[98]+
n[66],n[99]+n[67],n[100]+n[68]);}

129 characters, if I counted them right.

--
/-- Joona Palaste ([email protected]) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"You have moved your mouse, for these changes to take effect you must shut down
and restart your computer. Do you want to restart your computer now?"
- Karri Kalpio
 
J

Jirka Klaue

Sean said:
Got it down to 128 chars...

#include<stdio.h>
int
n[257];main(){while(++n[getchar()+1]);printf("a=%d,b=%d,c=%d\n",n[98]+n[66],
n[99]+n[67],n[100]+n[68]);}

It doesn't work. Well, it doesn't terminate. :)

Jirka
 
J

Jirka Klaue

Joona said:
I think the smallest working program (of this kind) would be, assuming
Sean's assumptions, something like this:

#include <stdio.h>
int
n[257]={-1,0};main(){while(++n[getchar()+1]);printf("%d,%d,%d\n",n[98]+

n[257]={-1};
n[66],n[99]+n[67],n[100]+n[68]);}

Jirka
 
J

Joona I Palaste

Jirka Klaue said:
Joona said:
I think the smallest working program (of this kind) would be, assuming
Sean's assumptions, something like this:

#include <stdio.h>
int
n[257]={-1,0};main(){while(++n[getchar()+1]);printf("%d,%d,%d\n",n[98]+
n[257]={-1};
n[66],n[99]+n[67],n[100]+n[68]);}

I thought of that as well, but wasn't sure. I did manage to cut down
Sean's program a lot by using +67 instead of +1 in the getchar() call,
but it wouldn't work here, since there's no way in C to initialise an
array with only the 67th element defined.
 
D

Daniel Haude

On Sun, 18 Jan 2004 20:43:23 +0000,
in Msg. said:
If we adopt the conventions that we only ever bid *up* for homework
questions and that subsequent bids always supersede existing bids until a
bid is finally accepted by the OP, perhaps we can distribute a few more
cluons into the newbie community.

Sort of along the lines of the Monty Python sketch, "Stop the Film"? It
lets us take advantage of the time element intrinsic in homework
assigmnents.

--Daniel
 
M

Morris Dovey

Sean said:
Can anyone beat 144 characters? (It assumes ASCII though) ......

Not a good assumption.

How would you know the OP's homework wouldn't be tested (and
graded) on, say, an EBCDIC machine on which EOF == -42?
 
C

CBFalconer

Sean said:
Morris Dovey said:
Ben said:
Pfui! Then it becomes cheaper to add the #include and drop two
prototypes. I'll follow your lead and drop the explicit void
arg list for main() and substitute *n for n[0]:

#include <stdio.h>
int
c,n[4]={0},toupper(),main(){while(0<(c=toupper(getchar())))++n[c-'A'?c-'B' ?c-'C'?3:2:1:0];printf("A=%d
B=%d C=%d\n",*n,n[1],n[2]);return 0;}

Those mods bring the character count down to 166.

Beat this (assumes ASCII though...)...144 chars

#include<stdio.h>
int n[256];int main(){int c;while((c=getchar())>=0)
n[c]++;printf("a=%d,b=%d,c=%d\n",n[97]+n[65],n[98]+n[66],n[99]+n[67]);}

I think we can remove the ASCII dependance and make it compliant:

#include<stdio.h>
int n[256];int main(){int c;while((c=getchar())>=0)n[c]++;
printf("a=%d,b=%d,c=%d\n",n['a']+n['A'],n['b']+n['B'],n['c']+n['C']);
return 0;}

I added 15 chars. and tested it:

c:\c\junk>gcc junk.c

c:\c\junk>a <junk.c
a=5,b=3,c=8

I suspect changing the exit test to ">0" would not be noticed in
practice, and remove another char. We could delete the \n from
the printout, and depend on program exit to flush buffers, for
another 2. Result 156 chars, compliant and portable!
 
C

CBFalconer

Sean said:
.... snip ...

I just realised I can get rid of the >=0 in the while condition:

#include<stdio.h>
int
n[257];main(){while(++n[getchar()+1]);printf("a=%d,b=%d,c=%d\n",n[98]+n[66],
n[99]+n[67],n[100]+n[68]);}

128 chars world record!!!!

Doesn't work. EOF != -1. ++n[anything] != 0.
 
S

Sean Kenwrick

Joona I Palaste said:
The programs Sean and I have presented here are fundamentally flawed.
They get stuck in infinite loops.
I just realised I can get rid of the >=0 in the while condition:
#include<stdio.h>
int
n[257];main(){while(++n[getchar()+1]);printf("a=%d,b=%d,c=%d\n",n[98]+n[66],
n[99]+n[67],n[100]+n[68]);}

Notice the while loop condition. ++n[getchar()+1] is only even going to
equal 0 if n[getchar()+1] equalled -1 before evaluation of the
expression, but nothing in Sean's code sets it to -1.
128 chars world record!!!!
Is there anything saying you have to output the a=, b= and c=? I can
shorten your program to 122 characters:
#include<stdio.h>
int
n[257];main(){while(++n[getchar()+1]);printf("%d,%d,%d\n",n[98]+n[66],
n[99]+n[67],n[100]+n[68]);}
It can be made even shorter.
#include<stdio.h>
int
n[323];main(){while(++n[getchar()+67]);printf("%d,%d,%d\n",n[32]+*n,n[33]+
n[1],n[34]+n[2]);}

These also suffer from the same problem.
117 characters! Now *this* is a new world record!

Actually my program works fine . Once getchar() returns -1 it will
continue to return -1 thereafter until n[0] wraps around the integer limit
and becomes 0 again!!!

I didn't quite get the logic of the above since your would be countinf in
positions n[122] for 'A' and n[154] for 'a', so then *n and n[32] won't
contain anything useful...

But you gave me an idea and my latest record is as follows:

#include<stdio.h>
n[257],*p;main(){while(++n[getchar()+1]);p=n+66;printf("%d,%d,%d\n",*p+p[32]
,p[1]+p[33],p[2]+p[34]);}

121 characters (counting the newline/CR after the #include <stdio.h>)

woohooo!!

Sean
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,265
Latest member
TodLarocca

Latest Threads

Top