klier@ucbarpa.Berkeley.EDU (Pete Klier) (03/10/89)
*********************** main(m,n){scanf("%d",&n);for(m=n>0^n>9;n&&m*=n--;); printf(m?"Answer=%d\n":"error\n",m);} *********************** with help from Jeff Conroy (jmconroy@ernie.Berkeley.EDU) the expression "m=n>0^n>9" is equivalent to "m = (n > 0) && (n <= 9)" (check it out) so "m" is 1 (initially) iff n is within range, 0 otherwise. If m is 0 in the body of the loop, then the expression (n&&m*=n--) is 0, since (m*=n--) is 0. Otherwise, we have an ordinary factorial loop, which begins with m == 1. Pete Klier klier@ernie.Berkeley.EDU
kjell@saturn.ucsc.edu (Kjell Post) (03/10/89)
In article <28336@ucbvax.BERKELEY.EDU> klier@ucbarpa.Berkeley.EDU (Pete Klier) writes: > >*********************** >main(m,n){scanf("%d",&n);for(m=n>0^n>9;n&&m*=n--;); >printf(m?"Answer=%d\n":"error\n",m);} >*********************** > But you changed the output. I also get an error compiling this on an ISI68K. As someone pointed out, my earlier solution breaks when arguments are supplied at the command line. I therefore propose the following as the shortest version: main(n,m){for(n=scanf("%d\n",&m);m>1&m<10;n*=m--); printf(m-1?"error\n":"answer is %d\n",n);} When written on a single line it should count to 91 characters. I would also like to add the rule that the program should compile without warnings from cc and lint (except for "scanf returns value which is always ignored" which is always ignored). -- For athletes and programmers, ! Kjell E. Post a woman is the end of their career. ! CIS/CE ! University of California, Santa Cruz -- A.Wickberg ! Email: kjell@saturn.ucsc.edu
djones@megatest.UUCP (Dave Jones) (03/11/89)
From article <28336@ucbvax.BERKELEY.EDU>, by klier@ucbarpa.Berkeley.EDU (Pete Klier): > > *********************** > main(m,n){scanf("%d",&n);for(m=n>0^n>9;n&&m*=n--;); > printf(m?"Answer=%d\n":"error\n",m);} > *********************** > > with help from Jeff Conroy (jmconroy@ernie.Berkeley.EDU) > Awesome. Truely awesome. I don't think this entry will be surpassed. By the way, this looks a little like some of the code in the original 4.2BSD Pascal compiler.
bader+@andrew.cmu.edu (Miles Bader) (03/11/89)
From klier@ucbarpa.Berkeley.EDU (Pete Klier): > > main(m,n){scanf("%d",&n);for(m=n>0^n>9;n&&m*=n--;); > printf(m?"Answer=%d\n":"error\n",m);} > > with help from Jeff Conroy (jmconroy@ernie.Berkeley.EDU) The compiler on this machine give the following error; is it wrong? E "fact.c",L1/C44: (syntactic) unexpected symbol:'*=' -Miles
tim@crackle.amd.com (Tim Olson) (03/12/89)
In article <YY6_v5y00UkaI0ZW1_@andrew.cmu.edu> bader+@andrew.cmu.edu (Miles Bader) writes: | From klier@ucbarpa.Berkeley.EDU (Pete Klier): | > | > main(m,n){scanf("%d",&n);for(m=n>0^n>9;n&&m*=n--;); | > printf(m?"Answer=%d\n":"error\n",m);} | > | > with help from Jeff Conroy (jmconroy@ernie.Berkeley.EDU) | | The compiler on this machine give the following error; is it wrong? | | E "fact.c",L1/C44: (syntactic) unexpected symbol:'*=' Interesting -- the program *is* incorrect, because && has higher precedence than *= so it is parsed as: (n&&m) *= n-- which is illegal because (n&&m) is not an lvalue. Our MetaWare and Green Hills compilers catch it, but every pcc-based compiler I tried compiled it with no warnings. Looking at the assembly-language generated, it appears that it compiled as: n && (m*=n--) What do other compilers out there do? -- Tim Olson Advanced Micro Devices (tim@amd.com)
bph@buengc.BU.EDU (Blair P. Houghton) (03/12/89)
In article <24820@amdcad.AMD.COM> tim@amd.com (Tim Olson) writes: >In article <YY6_v5y00UkaI0ZW1_@andrew.cmu.edu> bader+@andrew.cmu.edu (Miles Bader) writes: >| From klier@ucbarpa.Berkeley.EDU (Pete Klier): >| > >| > main(m,n){scanf("%d",&n);for(m=n>0^n>9;n&&m*=n--;); >| > printf(m?"Answer=%d\n":"error\n",m);} > >Interesting -- the program *is* incorrect, because && has higher >precedence than *= so it is parsed as: > (n&&m) *= n-- >which is illegal because (n&&m) is not an lvalue. Our MetaWare and >Green Hills compilers catch it, >What do other compilers out there do? Depends on your attitude. 1. The cc on the uVAXen (Ultrix) passes it unnoticed. 2. While cc on the Encore (Umax) says "junk.c", line 1: Operand must be an lvalue 3. Lint always says junk.c(8): warning: precedence confusion possible: parenthesize! I view the uVAX as utilizing a heuristically-extended version of the "maximal munch" rule, where the syntax has made it obvious that the lvalue given isn't an lvalue, so it looks for the next obvious interpretation. Groovy. Whatever turns you on, man. I view the Encore as applying the tokenize-first, interpret-later version of the "maximal munch" rule. I'm a bit of a code-fascist myself, so I'd go with this one. Lint? Well, I had to give it a "-h" in order to get it to talk. Don't you just hate weasely informants? --Blair "Don't you just hate computer narcs?"
steve@umigw.MIAMI.EDU (steve emmerson) (03/13/89)
In article <24820@amdcad.AMD.COM> tim@amd.com (Tim Olson) opines that the expression "n&&m*=n--" is incorrect C: >Interesting -- the program *is* incorrect, because && has higher >precedence than *= so it is parsed as: > > (n&&m) *= n-- > >which is illegal because (n&&m) is not an lvalue. I belive the correctness of a expression is determined by whether or not the expression can be *generated from* the grammer's production rules; not whether or not a given implementation of a compiler can parse it. The given expression is correct C as it can be generated by the following rules: expresion -> expression1 binop expression2 expression1 -> identifier -> n binop -> && expression2 -> lvalue asgnop expression lvalue -> identifier -> m asgnop -> *= expression -> lvalue-- -> identifier-- -> n-- Thus, expression -> n && m *= n-- Precedence rules are needed only when there is more than one way to generate a given expression and (consequently) more than one way to parse it. They appear to be unnecessary for the above expression. -- Steve Emmerson Inet: steve@umigw.miami.edu [128.116.10.1] SPAN: miami::emmerson (host 3074::) emmerson%miami.span@star.stanford.edu UUCP: ...!ncar!umigw!steve emmerson%miami.span@vlsi.jpl.nasa.gov "Computers are like God in the Old Testament: lots of rules and no mercy"
gwyn@smoke.BRL.MIL (Doug Gwyn ) (03/14/89)
In article <218@umigw.MIAMI.EDU> steve@umigw.miami.edu (steve emmerson) writes: >In article <24820@amdcad.AMD.COM> tim@amd.com (Tim Olson) opines that the >expression "n&&m*=n--" is incorrect C: >I belive the correctness of a expression is determined by whether or not >the expression can be *generated from* the grammer's production rules; not >whether or not a given implementation of a compiler can parse it. Right. >The given expression is correct C as it can be generated by the following >rules: I didn't much like your particular production. Using the pANS grammar, the conclusion that the parse is NOT effectively "(n&&m) *= n--" is a correct deduction; the key point is that "n&&m" cannot possibly be parsed as anything that is allowed as the left operand of the assignment expression (called a "unary expression" in the pANS grammar). However, the grammar does not support the production you gave, either. At least one set of parentheses would have to be added to obtain a valid expression. The phrase-structure grammar does not in general allow arbitrary expressions as operands, only limited classes of expressions.
peter@ficc.uu.net (Peter da Silva) (03/15/89)
From klier@ucbarpa.Berkeley.EDU (Pete Klier): > main(m,n){scanf("%d",&n);for(m=n>0^n>9;n&&m*=n--;); > printf(m?"Answer=%d\n":"error\n",m);} Give up one character and it works: main(m,n){scanf("%d",&n);for(m=n>0^n>9;n?m*=n--:0;); printf(m?"Answer=%d\n":"error\n",m);} -- Peter da Silva, Xenix Support, Ferranti International Controls Corporation. Business: uunet.uu.net!ficc!peter, peter@ficc.uu.net, +1 713 274 5180. Personal: ...!texbell!sugar!peter, peter@sugar.hackercorp.com.
tps@chem.ucsd.edu (Tom Stockfisch) (03/15/89)
In article <218@umigw.MIAMI.EDU> steve@umigw.miami.edu (steve emmerson) writes: >[argument that "n&&m*=n--" is not equivalent to (n&&m) *= n-- and thus >not illegal, because: ] >Precedence rules are needed only when there is more than one way to >generate a given expression and (consequently) more than one way to parse >it. They appear to be unnecessary for the above expression. This idea seems to me to admit too many wierd constructs. For instance, why couldn't you argue that the following expressions are legal? EXPRESSION EQUIVALENT TO a + 1[0] (a + 1)[0] a + b = c a + (b = c) *a + 5 = 0 *(a + 5) = 0 -- || Tom Stockfisch, UCSD Chemistry tps@chem.ucsd.edu