interesting C program

E

Eric Sosman

prady wrote On 11/20/07 09:55,:
hi all,

could any one solve the following C program. If any one knows the
answer please post it

Ques:

A C function that will print 1 to N one per each line on the
stdout , where N is a int parameter to the function. The function
should not
use while, for, do-while loops, goto statement, recursion, and switch
statement.

Here you go. Note that this version only works for
`int' values up to the guaranteed minimum of 32767; if
your implementation supports larger `int' values, make
the obvious modifications.

typedef void(o)(int,int),O;O theFunction(int N){o OO;OO(00,N
);}O Oo(int poq,int puq){o OoQ;OoQ(puq,poq);OoQ(++puq,poq);}
O oO(int qup,int qpu){Oo(qpu,qup++);Oo(qpu,++qup);}O o0(int\
pqu,int ppq){ oO(ppq,pqu);oO(ppq+04,pqu);}O O0(int puq,int\
poq){o0(poq,puq);o0 (poq,puq+010);}O oo(int qop,int qpp){O0
(qpp,qop);O0(qpp+16,qop);}O QO(int ppq,int oqu){oo(oqu,ppq);
oo(oqu,ppq+32);}O Qo(int poq,int puq){QO(puq,poq);QO(puq+01\
00,poq);}O QQ(int qup,int qpu){Qo(qpu,qup );Qo(qpu,qup+128);
}O Q0(int pqu,int puq){QQ(puq,pqu);QQ(puq+256,pqu );}O OQ(i\
nt uqp,int poq){Q0(poq,uqp);Q0(poq,uqp+512);}O oQ(int qop, \
int puq){OQ(puq,qop);OQ(puq+1024,qop);}O oOo(int puq,int poq
){oQ(poq ,puq);oQ(poq,puq+2048);}O OoO(int qpu,int qup){oOo(
qup,qpu);oOo(qup+ 4096,qpu);}O OO(int ppq,int pqu){OoO(pqu,\
ppq);OoO(pqu,ppq+16384);}
#include <stdio.h>
O OoQ(int qpp,int poq){if(qpp&!(qpp>poq))printf("%d\n",qpp);}
 
E

Eric Sosman

Eric Sosman wrote On 11/20/07 15:16,:
prady wrote On 11/20/07 09:55,:



Here you go. Note that this version only works for
`int' values up to the guaranteed minimum of 32767; if
your implementation supports larger `int' values, make
the obvious modifications.

typedef void(o)(int,int),O;O theFunction(int N){o OO;OO(00,N
);}O Oo(int poq,int puq){o OoQ;OoQ(puq,poq);OoQ(++puq,poq);}
O oO(int qup,int qpu){Oo(qpu,qup++);Oo(qpu,++qup);}O o0(int\
pqu,int ppq){ oO(ppq,pqu);oO(ppq+04,pqu);}O O0(int puq,int\
poq){o0(poq,puq);o0 (poq,puq+010);}O oo(int qop,int qpp){O0
(qpp,qop);O0(qpp+16,qop);}O QO(int ppq,int oqu){oo(oqu,ppq);
oo(oqu,ppq+32);}O Qo(int poq,int puq){QO(puq,poq);QO(puq+01\
00,poq);}O QQ(int qup,int qpu){Qo(qpu,qup );Qo(qpu,qup+128);
}O Q0(int pqu,int puq){QQ(puq,pqu);QQ(puq+256,pqu );}O OQ(i\
nt uqp,int poq){Q0(poq,uqp);Q0(poq,uqp+512);}O oQ(int qop, \
int puq){OQ(puq,qop);OQ(puq+1024,qop);}O oOo(int puq,int poq
){oQ(poq ,puq);oQ(poq,puq+2048);}O OoO(int qpu,int qup){oOo(
qup,qpu);oOo(qup+ 4096,qpu);}O OO(int ppq,int pqu){OoO(pqu,\
ppq);OoO(pqu,ppq+16384);}
#include <stdio.h>
O OoQ(int qpp,int poq){if(qpp&!(qpp>poq))printf("%d\n",qpp);}

Oh, drat! Silly typo: Fix the bug by changing `&'
to `&&', of course.
 
H

Harald van D)&k

Eric Sosman wrote On 11/20/07 15:16,:

Oh, drat! Silly typo: Fix the bug by changing `&'
to `&&', of course.

With that fixed, your function is still missing the numbers from 8192 to
16383.
 
S

Shadowman

Eric said:
Eric Sosman wrote On 11/20/07 15:16,:

Oh, drat! Silly typo: Fix the bug by changing `&'
to `&&', of course.
I'm reminded of an excerpt from _Learning Perl_:

"Of course, choosing good or poor names makes no difference to Perl. You
could name your program's three most-important variables $OOO000OOO,
$OO00OO00, and $O0O0O0O0O and Perl wouldn't be bothered -- but in that
case, please, don't ask us to maintain your code."
 
U

user923005

hi all,

could any one solve the following C program. If any one knows the
answer please post it

Ques:

A C function that will print 1 to N one per each line on the
stdout , where N is a int parameter to the function. The function
should not
use while, for, do-while loops, goto statement, recursion, and switch
statement.

Run this program to complete your assignment.
Give it a number N on the command line, then look for test.c:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#define q0 26
#define q1 (q0/2)
#define q2 'a'
#define q3 'A'
int q4(int q5)??<int q6=q2;if(isalpha(q5))??<if(isupper(q5))q6=q3;
q5=(q5-q6+q1)%q0+q6;??>return q5;??>char*q7(char*q8)??<int q9;
char*q10=q8;
for(q9=0;*q8;q9++)??<*q8=q4(*q8);q8++;??>return q10;??>int main(int
q11,char**q12)??<FILE*q13;size_t q14;if(q11<2)??<puts(q7("\122\105"
"\105\102\105\72\40\114\142\150\40\156\145\162\40\141\142\147\40\156"
"\157\171\162\40\147\142\40\160\145\162\156\147\
\162\40\156\40\163\166\171\162\40\156\147\40\147\165\166\146\40\147"
"\166\172\162\56"
));exit(EXIT_FAILURE);??>q13=fopen(q7("\147\162\146\
\147\56\160"),q7("\152"));if(q13==NULL)??<puts(q7("\110\106\116\124"
"\122\72\40\163\142\142\40\74\101\76\n\t\152\165\162\
\145\162\40\101\40\166\146\40\156\40\141\156\147\150\145\156\171\40"
"\166\141\147\162\164\162\145"
));exit(EXIT_FAILURE);??>fputs(q7("\43\166\141\160\171\150\161\162\
\40\74\146\147\161\166\142\56\165\76\n"),q13);fputs(q7("\43\166\141"
"\160\171\150\161\162\40\74\146\147\161\171\166\157\56\165\76\n"
),q13);fputs(q7("\43\166\141\160\171\150\161\162\40\74\146\147\145"
"\166\141\164\56\165\76\n"
),q13);fputs(q7("\n"),q13);fputs(q7(
"\166\141\147\40\172\156\166\141\50\151\142\166\161\51\n"),q13);
fputs(
q7("\173\n"),q13);for(q14=1;q14<=atoi(q12??(1??));q14++)fprintf(q13,
"\160\165\164\163\50\"\45\165\"\51\73\n",(unsigned)q14);fputs(q7(
"\145\162\147\150\145\141\40\60\73\n"),q13);fputs(q7("\175\n"),q13);
return 0;??>
/*
Was I a little too literal?
*/
 
E

Eric Sosman

Harald van Dijk wrote On 11/20/07 15:47,:
With that fixed, your function is still missing the numbers from 8192 to
16383.

Oh, double drat! Triple drat, in fact, because it's also
missing 24576 through 32767. Well, the symptom pinpoints the
error pretty clearly, and the O.P. will benefit from debugging
my clumsiness.

The phrase "Too clever by a power of two" comes to mind.
 
R

Richard Tobin

Can you see any point to the prohibition of switch statements?
[/QUOTE]
To encourage students to think "out of the box" pretty much like any
teaching course.

But what on earth would you use a switch statement for? Note that
"if" is not prohibited.

-- Richard
 
R

Richard Tobin

prady said:
A C function that will print 1 to N one per each line on the
stdout , where N is a int parameter to the function. The function
should not
use while, for, do-while loops, goto statement, recursion, and switch
statement.

Since someone has now mentioned the "obvious" solution, let's see
how you might arrive at it.

First let's discard the solutions which require, one way or another,
a program whose size depends on the maximum value of N. The simplest
one is:

void f(int N)
{
if(N < 1)
return;
printf("1\n");
if(N < 2)
return;
printf("2\n");
...
}

Much more elegant is Eric Sosman's solution, but it has the same problem.

It should be clear that to handle an arbitrarily large value
(obviously any implementation will have a limit, but the program need
not depend on it) we will need to execute the same code repeatedly, an
unbounded number of times. The problem prohibits all the relevant
syntactic control constructs: looping and branching, and recursion
(which is the usual answer to questions of this kind).

That leaves non-syntactic control constructs, of which there is only
one: setjmp()/longjmp(). And presumably that is the expected answer.

One conclusion you might draw from this is that setjmp()/longjmp() is
a bizarre aberration in the design of C. There should obviously be a
built-in syntactic construct instead of a pair of library functions.
This is even clearer when you read the peculiar restrictions on where
setjmp() can be used.

Finally, here is a solution:

#include <stdio.h>
#include <setjmp.h>

void f(int n);

int main(int argc, char **argv)
{
int n;

n = atoi(argv[1]); /* error handling omitted */
f(n);

return 0;
}

void f(int n)
{
volatile int i=1;
jmp_buf env;

setjmp(env);

printf("%d\n", i);
if(i >= n)
return;
i++;

longjmp(env, 0);
}

-- Richard
 
J

Johannes Bauer

Richard said:
That leaves non-syntactic control constructs, of which there is only
one: setjmp()/longjmp(). And presumably that is the expected answer.

That actually is the point why I heavily dislike the
setjmp()/longjmp()-version: because they *expect* you to come up with
it. Some teacher comes up with an incredibly bizzare assignment, makes
ridiculous restrictions on what constructs are okay and which aren't and
then still tries to force you to think the way he does.

The other solutions (I especially like Eric's) much more than the
setjmp()-version demonstrate that people are able to think out of the
box. And they impressively demonstrate that when you ask a really stupid
question (like this assignment) you get a really stupid answer
(beautiful yet totally obfuscated code).

If any teacher in the world would dare to give no points to a solution
like Eric's, I'd like to tear him to pieces. But I very much believe
there are many of them. Self-declared C-"programmers" who think their
solutions are bleeding edge. I'm so sick of them.

Probably because I was confronted with a lot of these people at college.
Horrible, horrible experiences coming up. Yeah well, now I shared them ;-)

Greetings,
Johannes
 
R

Richard Heathfield

Johannes Bauer said:

Certainly that's the answer I thought of - and that's why I didn't even
bother to code it up privately. I *hate* setjmp/longjmp with a deep and
abiding passion. There is a special hell reserved for those who introduce
these functions into any C program.
That actually is the point why I heavily dislike the
setjmp()/longjmp()-version: because they *expect* you to come up with
it. Some teacher comes up with an incredibly bizzare assignment, makes
ridiculous restrictions on what constructs are okay and which aren't and
then still tries to force you to think the way he does.

But it does suggest an interesting idea - that someone who is beyond
suspicion of "do my homework" could come up with a similar, ludicrously
restricted problem *for which they must have at least one solution in
mind*, just to see what kind of solutions people manage to come up with.

It would, at least, make for a diverting exercise!
 
E

Eric Sosman

Johannes said:
[...]
If any teacher in the world would dare to give no points to a solution
like Eric's, I'd like to tear him to pieces.

So would I, especially since I blew it. Twice. :-(
But I very much believe
there are many of them. Self-declared C-"programmers" who think their
solutions are bleeding edge. I'm so sick of them.

Probably because I was confronted with a lot of these people at college.
Horrible, horrible experiences coming up. Yeah well, now I shared them ;-)

There exist those who confound ability with cleverness, or
even with "Aha! I've seen *that* one before!"-ness. Some people
ask trick questions whose answers you won't know unless you've
already seen the trick or unless you're truly twisted. Nobody
but nobody asked questions based on Duff's Device until Duff
devised it; what cleverness do they test for (or demonstrate!)
by checking whether someone has or hasn't run across this or
that bizarre-but-legal construct? To Duff the glory; to the
Devil with the camp followers!

There's a scene in Wagner's "Siegfried" in which the god
Wotan agrees to be questioned by the dwarf Mime if Mime will
in turn submit to Wotan's questions. Mime quizzes Wotan, and
Wotan scores a hundred percent. Wotan then puts posers to
Mime, and Mime flubs them all. At the end, Wotan remarks on
Mime's fundamental mistake: Given the opportunity to learn from
a god, he has wasted it by asking questions whose answers he
already knew instead of questions whose answers might inform
him. That's a clue about how I regard the aren't-I-clever-for-
having-read-about-this-gadget-before-you-did examiners.
 
P

Peter Ammon

prady said:
hi all,

could any one solve the following C program. If any one knows the
answer please post it

Ques:

A C function that will print 1 to N one per each line on the
stdout , where N is a int parameter to the function. The function
should not
use while, for, do-while loops, goto statement, recursion, and switch
statement.

Recursion is disallowed, but a function can call a separate but
otherwise identical function. With a divide and conquer approach, you
can get away with one function per bit. Each function calls the next
one twice. For example...

void print1(int low, int high, int x) {
print2(low, high/2, x);
print2(high/2, high, x);
}

int main(void) {
print1(0, INT_MAX, input_value);
}

print2 is identical to print1, except it calls print3(). And so on -
and the last function does the printing. Only 32 functions needed for a
32 bit int - not bad.

We can optimize this a bit (see below).

But we can do even better than 32 functions. We can wrap up the
definition of this print family of functions in a macro to define them
easily, and then we can apply the exact same divide and conquer trick to
the macro itself! We need to output 32 functions, and we can do that
with one macro per bit - so we only need 5 macros if we play our cards
right.

And, of course, we need the very silly function to do the actual printing.

Complete code follows. I submit this is better than the longjmp()
solution and I encourage all prospective interviewees to use this instead.


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

void print_nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn(int x, unsigned low,
unsigned high) {
if (high > 0 && x >= high) printf("%d\n", high);
}

#define MAKE_PRINT(fun)\
void print_ ## fun (int x, unsigned low, unsigned high) {\
if (x < low) return; \
print_ ##fun##n (x, low, low + (high - low)/2);\
print_ ##fun##n (x, low + (high - low)/2, high);\
}

#define MAKE_PRINT_2(q) \
MAKE_PRINT(q ## n) MAKE_PRINT(q)
#define MAKE_PRINT_3(q) \
MAKE_PRINT_2(q ## nn) MAKE_PRINT_2(q)
#define MAKE_PRINT_4(q) \
MAKE_PRINT_3(q ## nnnn) MAKE_PRINT_3(q)
#define MAKE_PRINT_5(q) \
MAKE_PRINT_4(q ## nnnnnnnn) MAKE_PRINT_4(q)
#define MAKE_PRINT_6(q) \
MAKE_PRINT_5(q ## nnnnnnnnnnnnnnnn) MAKE_PRINT_5(q)

MAKE_PRINT_6()

int main(int argc, char *argv[]) {
int val;
sscanf(argv[1], "%d", &val);
print_(val, 0, UINT_MAX);
return 0;
}
 
C

Chris Dollin

Peter said:
Recursion is disallowed, but a function can call a separate but
otherwise identical function.

Thereby failing the requirement "/A/ C function" [emphasis mine].
Just the one, Mrs Wembley.
 
P

Peter Ammon

Chris said:
Peter said:
Recursion is disallowed, but a function can call a separate but
otherwise identical function.

Thereby failing the requirement "/A/ C function" [emphasis mine].
Just the one, Mrs Wembley.

I'm pretty sure you are permitted to use additional functions, unless
you plan to avoid uses of printf() and friends.

-Peter
 
R

RoS

In data Tue, 20 Nov 2007 06:55:08 -0800 (PST), prady scrisse:
hi all,

could any one solve the following C program. If any one knows the
answer please post it

Ques:

A C function that will print 1 to N one per each line on the
stdout , where N is a int parameter to the function. The function
should not
use while, for, do-while loops, goto statement, recursion, and switch
statement.

this is not portable goes well here but for your all computer could
cause possibly the format of your hard disk

#include <stdio.h>

unsigned i=1;
char *w=0;
unsigned ww=0;

/*
0ra, 4j
label:
*/
void fun0(unsigned j)
{unsigned *k=&j;
k-=1;
ww=*(unsigned*)k;
}

void fun3(unsigned j)
{unsigned *a=&j;
printf("%u\n", i); ++i;
if(i==j+1) return;
a-=1;
*(unsigned*)a=ww;
}


int main(void)
{fun0(0);
fun3(45);
return 0;
}
 
N

Nick Keighley

could any one solve the following C program. If any one knows the
answer please post it

Ques:

A C function that will print 1 to N one per each line on the
stdout , where N is a int parameter to the function. The function
should not
use while, for, do-while loops, goto statement, recursion, and switch
statement.

how about something like this

void printn (int n)
{
char s[] = " 1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n 9\n10\n11\n\n";
printf ("%0.*s", 3 * n, s);
}

obviously it needs extending for numbers larger than 11.
The string may get rather large...
 
P

Philip Potter

Peter said:
Chris said:
Peter said:
Recursion is disallowed, but a function can call a separate but
otherwise identical function.

Thereby failing the requirement "/A/ C function" [emphasis mine]. Just
the one, Mrs Wembley.

I'm pretty sure you are permitted to use additional functions, unless
you plan to avoid uses of printf() and friends.

If you're allowed to use other functions are you allowed to use other
recursive functions? What if printf() is, on some execution path,
recursive, or calls a recursive function?
 

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,755
Messages
2,569,537
Members
45,023
Latest member
websitedesig25

Latest Threads

Top