program

J

Joona I Palaste

Sean Kenwrick said:
Joona I Palaste said:
Joona I Palaste said:
Joona I Palaste <[email protected]> scribbled the following:
Sean Kenwrick <[email protected]> scribbled the following:

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!!!

Sorry, no. You'd have to make your array "unsigned int n[257]" to
guarantee safe wrap-around.
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...

Whoops, I appear to have written a bug in my code... I should have added
a pointer variable p pointing to n[66], something like "int*p=n+66", and
used p instead of n in the printf call.
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]);}

Yes, I was thinking something like that.
 
S

Sean Kenwrick

Jirka Klaue said:
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
It does terminate because once getchar() returns -1 it will continue to do
so and eventually n[0] will wrap round the integer limit back to 0 ;-)

See previous post above for a 121 char version.

Sean
 
M

Morris Dovey

CBFalconer said:
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!

How do you know CHAR_BIT == 8 ?
 
S

Sean Kenwrick

CBFalconer said:
Sean 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]);}

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!
I could write a compliant and portable program, but this thread seemed to be
degenerating into a competition to write the smallest program using whatever
methods and side effects possible. My program which DOES terminate when
n[0] wraps around the integer limit back to 0 :)

I've posted a variation of it that is 121 chars long (including the NL/CR
after the #include)
Can you beat that?

Sean
 
M

Morris Dovey

Sigh. Well, I didn't actually like the global variables anyway. I
think this should be good, portable C code (although less
user-friendly). I'm not too sure about my EOF test.


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

Which would be 162 characters

What if, for example, EOF is defined to be ((1<<CHAR_BIT)+1)?
Perhaps it would be better to do an explicit EOF comparison:

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

Which would be 164 characters; but without the need to worry
about strange EOF values. Is this strictly conforming?
 
M

Morris Dovey

Sean said:
I could write a compliant and portable program, but this thread seemed to be
degenerating into a competition to write the smallest program using whatever
methods and side effects possible.

Sean...

This /is/ comp.lang.c - let's endeavor to maintain our Standards.
 
B

Ben Pfaff

Morris Dovey said:
What if, for example, EOF is defined to be ((1<<CHAR_BIT)+1)?

A positive value? Not possible:

...
EOF
which expands to an integer constant expression, with type int and a negative value,
...
 
B

Ben Pfaff

CBFalconer said:
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 assume C90 because of the explicit return 0:

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

Using UCHAR_MAX+1 or 1<<CHAR_BIT instead of 256 would be more
portable though.
I suspect changing the exit test to ">0" would not be noticed in
practice, and remove another char.

Using 0< works fully (first noticed by Morris Dovey (?)) and
still removes the 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!

My updated version is only 136. (I haven't tested it though.)
 
M

Morris Dovey

Ben said:
A positive value? Not possible:

...
EOF
which expands to an integer constant expression, with type int and a negative value,
...

You're good (like lint with claws!) How about INT_MIN instead?
 
B

Ben Pfaff

Morris Dovey said:
You're good (like lint with claws!) How about INT_MIN instead?

I don't understand why that's a problem. INT_MIN is still less
than 0. Am I missing anything?
 
J

Jeremy Yallop

Morris said:
Sigh. Well, I didn't actually like the global variables anyway. I
think this should be good, portable C code (although less
user-friendly). I'm not too sure about my EOF test.


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

Which would be 162 characters

What if, for example, EOF is defined to be ((1<<CHAR_BIT)+1)?

EOF must be negative, so the test is fine. You can save more
characters by removing the 'return 0' (in C99, at least, and in C89 if
you believe Dan Pop), moving the declarations to file scope (where the
initializer isn't needed) and rearranging the contents of the array.
You do need to terminate the output with a newline, though.

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

146 characters and as close to strictly conforming C99 as possible. A
C89 version could be even shorter, by dropping the declaration of
toupper and the `int' from the definition of main.

Jeremy.
 
M

Morris Dovey

Ben said:
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 assume C90 because of the explicit return 0:

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

Using UCHAR_MAX+1 or 1<<CHAR_BIT instead of 256 would be more
portable though.

True, though "#include <limits.h>" burdens us with 19 characters.

Have we decided that we don't need to (even weakly) prototype
tolower() ?

printf() returns the number of characters transmitted (or -1 if
an error was detected.) We can provide a portable return value by
coding:

return!printf("a=%d,b=%d,c=%d\n",n['a'],n['b'],n['c']);}

Without adding anything to the character count.
 
B

Ben Pfaff

Morris Dovey said:
Ben said:
CBFalconer said:
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 assume C90 because of the explicit return 0:
#include<stdio.h>
int c,n[256];int main(){while(0<(c=tolower(getchar())))n[c]++;
return printf("a=%d,b=%d,c=%d\n",n['a'],n['b'],n['c']);}
Using UCHAR_MAX+1 or 1<<CHAR_BIT instead of 256 would be more
portable though.

True, though "#include <limits.h>" burdens us with 19 characters.

Have we decided that we don't need to (even weakly) prototype
tolower() ?

In C90 no declaration is needed for most functions that return
int, like tolower().
 
M

Morris Dovey

Jeremy Yallop wrote:

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

I like it; but would like it better with an explicit return
value. Adding whitespace for readability (but not for
character-counting purposes), we have something Paul could
actually submit to satisfy his plagerism requirements:

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

Looks safe enough to run on even the DS-9000 under Megaton
'Splosion's Doomsday Operating System (DS9K/MS-DOS).
 
J

Jeremy Yallop

Morris said:
Jeremy Yallop wrote:

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

I like it; but would like it better with an explicit return
value. Adding whitespace for readability (but not for
character-counting purposes), we have something Paul could
actually submit to satisfy his plagerism requirements:

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

Looks safe enough to run on even the DS-9000 under Megaton
'Splosion's Doomsday Operating System (DS9K/MS-DOS).

Well, apart from the use of the uninitialized array :).

Jeremy.
 
M

Morris Dovey

Ben said:
In C90 no declaration is needed for most functions that return
int, like tolower().

Thanks. Glad I asked. I have a personal distaste for incomplete
prototypes, anyway. In "real" code I'd have included ctypes.h
just because I like to have the compiler checking up on me (and
that checking's obviously needed. :)
 
P

Programmer Dude

CBFalconer said:
I'll start as soon as I receive your certified
check for $200 (US) (1 hours work minimum consulting charge).

Hmmmm. I need to raise my rates!
 
R

Richard Heathfield

Morris said:
I have a personal distaste for incomplete
prototypes, anyway. In "real" code I'd have included ctypes.h

Personally said:
just because I like to have the compiler checking up on me (and
that checking's obviously needed. :)

.... just because I like to have the compiler *find* the headers I include.
:)
 

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

No members online now.

Forum statistics

Threads
474,138
Messages
2,570,804
Members
47,349
Latest member
jojonoy597

Latest Threads

Top