3
\$\begingroup\$

Challenge:

Write the smallest program (in characters) that resolves quadratic equations i.e. ax² + bx + c = 0

Rules:

Given 3 numbers in R comma-delimited on STDIN: a,b,c (a != 0), print on STDOUT the 2 roots in C, one per line.

R stands for real numbers, C for complex numbers.

Examples:

Input         Output

1,0,0         r1=0     also accepted: r1=(-0-sqrt(0))/2
              r2=0

1,2,1         r1=-1    also accepted: r1=(-2-sqrt(0))/2
              r2=-1

1,1,1         r1=(-1-isqrt(3))/2  also accepted: r1=(-1-sqrt(-3))/2 or r1=-0.5-0.866i
              r2=(-1+isqrt(3))/2
\$\endgroup\$
  • \$\begingroup\$ What does isqrt mean? Are there any constraints on the output format (e.g. canonical forms) or is any expression which resolves to the roots valid? \$\endgroup\$ – Peter Taylor Nov 28 '11 at 16:01
  • \$\begingroup\$ @Peter Taylor: isqrt stands for i * squareRoot(3). The output have to be on 2 lines as shown in the output column of examples. \$\endgroup\$ – Toto Nov 28 '11 at 16:06
  • \$\begingroup\$ But would r1=(-2-sqrt(0))/2 be an acceptable output line? How about r1=(-1-sqrt(-3))/2 ? \$\endgroup\$ – Peter Taylor Nov 28 '11 at 17:27
  • \$\begingroup\$ @Peter Taylor: I see what you mean, yes both output are acceptable. \$\endgroup\$ – Toto Nov 28 '11 at 18:35
  • \$\begingroup\$ I implemented this using a Casio fx-7000G - rskey.org/detail.asp?manufacturer=Casio&model=fx-7000G - (not sure the extact model). I remember there being only 32 steps for a program and the version I came up with was 31 (including the data entry). \$\endgroup\$ – Skizz Nov 29 '11 at 13:47
8
\$\begingroup\$

R, 19 chars

polyroot(scan(n=3))

or more strictly following the I/O requirements in 58 chars:

r=polyroot(rev(scan(sep=",")));cat("r1=",r[1],"\nr2=",r[2])

edit: reversed coefficients

\$\endgroup\$
  • \$\begingroup\$ Great, now just format the output correctly too... \$\endgroup\$ – Tommy Dec 3 '11 at 0:16
  • \$\begingroup\$ cat(paste("r",1:2,"=",polyroot(rev(scan(se=",",qui=T))),sep=""),sep="\n") You need to rev the coefficients (two of the three examples were palindromic, so it wasn't obvious). Also, added quiet=TRUE to scan to suppress "Read 3 items" and shortened all arguments to minimum possible (which was se instead of sep for scan. \$\endgroup\$ – Brian Diggs Dec 3 '11 at 0:33
6
\$\begingroup\$

J, 21

J's got a verb to do exactly that: p. It does complex to complex, but your problem is a subset of that.

echo"0>{:p.|.".1!:1[3

As always with J solutions here, I/O and formatting take up 90% of the solution.

\$\endgroup\$
  • 4
    \$\begingroup\$ Whoever downvoted this: why? If it's buggy, post a comment. If you have a problem with "challenges" which are solved in 1 character in a language which is used in the real world then downvote the question, not the answer. \$\endgroup\$ – Peter Taylor Nov 29 '11 at 8:09
  • \$\begingroup\$ @J B: Nice one, +1 \$\endgroup\$ – Toto Nov 29 '11 at 9:05
  • \$\begingroup\$ It looks really nice, but I don't know if it follow the contest rules (load from stdin and output r1=) \$\endgroup\$ – JBernardo Nov 29 '11 at 14:10
  • \$\begingroup\$ @JBernardo: it follows the rules strictly as far as STDIN goes. STDOUT is a bit more relaxed, but acceptable IMHO: it assumes interactive J, and outputs in a format different from the example, but that's in line with my interpretation of word "example"'s meaning. \$\endgroup\$ – J B Nov 29 '11 at 16:41
  • \$\begingroup\$ Oh, I hadn't noticed the poster required one answer per line. That at least I can fix easily. \$\endgroup\$ – J B Nov 29 '11 at 16:43
4
\$\begingroup\$

Python 3, 79 chars

a,b,c=eval(input())
d=(b*b-4*a*c)**.5/2/a
x=-b/2/a
print('r1=',x+d,'\nr2=',x-d)

Python's imaginary unity is j and not i. I used Python 3 because the power operator works also on negative numbers.

BTW, is it really needed to write r1= ... and r2= ... ?

\$\endgroup\$
  • \$\begingroup\$ +1, It's OK for j instead of i. r1= is part of the challenge. \$\endgroup\$ – Toto Nov 29 '11 at 9:07
1
\$\begingroup\$

Perl, 96 87 Characters

($a,$b,$c)=eval<>;$_=abs($_=$b*$b-4*$a*$c)**.5/2/$a.i x($_<0);$b/=-2*$a;die"r1=$b+$_
r2=$b-$_"

The line break is intentional, as is a space.

Edit: By reformatting output, I can shorten this to:

($a,$b,$c)=eval<>;$_="sqrt(".($b*$b-4*$a*$c)."))/".2*$a;$b*=-1;die"r1=($b+$_
r2=($b-$_"
\$\endgroup\$
1
\$\begingroup\$

Perl, 76 characters (+1 command line switch)

perl -pe '($a,$b,$c)=eval;$d=($b/=-$a)**2-4*$c/$a;$_="-+";s!.!r@+=($b$&sqrt($d))/2\n!g'

Replacing the \n with a literal newline allows a further trivial one-character reduction.

Sample input / output:

1,0,0
r1=(0-sqrt(0))/2
r2=(0+sqrt(0))/2
1,2,1
r1=(-2-sqrt(0))/2
r2=(-2+sqrt(0))/2
1,1,1
r1=(-1-sqrt(-3))/2
r2=(-1+sqrt(-3))/2
1,0,-1
r1=(0-sqrt(4))/2
r2=(0+sqrt(4))/2
2,1,1
r1=(-0.5-sqrt(-1.75))/2
r2=(-0.5+sqrt(-1.75))/2

Yeah, it's not exactly Wolfram Alpha, but I believe it should qualify as acceptable output.

\$\endgroup\$
0
\$\begingroup\$

D (160 chars)

import std.complex;import std.stdio;void main(){real a,b,c;readf("%f,%f,%f",&a,&b,&c);Complex!real j=sqrt(b*b-4*a*c)/2/a,i=-b/2/a;write("r1=",i+j,"\nr2=",i-j);}
\$\endgroup\$
0
\$\begingroup\$

Perl, 101 chars

First stab:

perl -E 'my($x,$y,$z)=pop=~/\d+/g;printf"r%d=(%+d%ssqrt(%d))/%d\n",++$p,-$y,$_,$y**2-4*$x*$z,2*$x for qw/- +/;' 1,2,1
\$\endgroup\$
  • \$\begingroup\$ The last $x in printf should be $x*2, and last double quote " a single one ' \$\endgroup\$ – Toto Nov 29 '11 at 9:04
  • \$\begingroup\$ @M42 : Right. Bitten by the Windows "" issue again. \$\endgroup\$ – Zaid Nov 29 '11 at 9:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.