0
votes

Scheme

I want to define a function which returns the roots of the quadratic formula, given ax^2+bx+c=0. Return only real roots. The list will have 0, 1, or two unique roots.

(define (quadratic a b c)
    (cond
        ((> (- (* b b) (* 4 (* a c ) ) ) 0 ) (list ( / ( - (sqrt ( - (* b b) (* (* 4 a) c))) b ) ( * 2 a) )
            ( / ( - ( - (sqrt ( - (* b b) (* (* 4 a) c)))) b ) ( * 2 a) ) ) )
        ((= (- (* b b) (* 4 (* a c ) ) ) 0 ) list( / ( - (sqrt ( - (* b b) (* (* 4 a) c))) b ) ( * 2 a) ))
        (else ('( )'))
    )
)

I got

error: unexpected right parenthesis [read]
       #{&read-error}
       #{&i/o-port-error #{input-port #{input-channel "standard input" 0}}}

Is there any better way to solve that?

2
@jenesaisquoi the list is not random, OP is using it to return a list with the answers. - Óscar López

2 Answers

0
votes

You have parentheses problems (obviously, that's what the error states) - for example, you forgot to open one to the left of the second list in your code. This should fix it:

(define (quadratic a b c)
  (cond
    ((> (- (* b b) (* 4 (* a c))) 0)
     (list (/ (- (sqrt (- (* b b) (* (* 4 a) c))) b) (* 2 a))
           (/ (- (- (sqrt (- (* b b) (* (* 4 a) c)))) b) (* 2 a))))
    ((= (- (* b b) (* 4 (* a c))) 0)
     (list (/ (- (sqrt (- (* b b) (* (* 4 a) c))) b) (* 2 a))))
    (else '())))

Also, take notice of the correct way to indent your code - it'll help you find errors like this; a good editor will be useful, too. Let's test the procedure:

(quadratic 1 -3 -4)
=> '(4 -1)
(quadratic 9 12 4)
=> '(-2/3)
(quadratic 3 4 2)
=> '()
0
votes

The previous solution answers correctly to your question. But note that your algorithm performs the same calculation a lot of times, even when it is not necessary (when the determinant is zero), and the code is very difficult to read. So I propose a rewriting of your function that produces the same result more efficiently and, more important, in a more readable way:

(define (quadratic a b c)
  (let ((determinant (- (* b b) (* 4 a c))))
    (if (negative? determinant)
        '()
        (let ((a2 (+ a a)))
          (if (zero? determinant)
              (list (/ (- b) a2))
              (let ((root (sqrt determinant)))
                (list (/ (- root b) a2)
                      (/ (- (- root) b) a2))))))))