fork download
  1. ; maximum product of three
  2.  
  3. (define (take n xs)
  4. (let loop ((n n) (xs xs) (ys '()))
  5. (if (or (zero? n) (null? xs))
  6. (reverse ys)
  7. (loop (- n 1) (cdr xs)
  8. (cons (car xs) ys)))))
  9.  
  10. (define (last xs)
  11. (cond ((null? xs) (error 'last "empty input"))
  12. ((null? (cdr xs)) (car xs))
  13. (else (last (cdr xs)))))
  14.  
  15. (define-syntax assert
  16. (syntax-rules ()
  17. ((assert expr result)
  18. (if (not (equal? expr result))
  19. (for-each display `(
  20. #\newline "failed assertion:" #\newline
  21. expr #\newline "expected: " ,result
  22. #\newline "returned: " ,expr #\newline))))))
  23.  
  24. (define (max-prod-three xs)
  25. (let ((len (length xs)) (xs (sort xs <)))
  26. (cond ((< len 3) (error 'max-prod-three "insufficient input"))
  27. ((= len 3) (apply * xs))
  28. ((not (negative? (car xs)))
  29. (apply * (take 3 (reverse xs))))
  30. ((negative? (last xs))
  31. (apply * (take 3 (reverse xs))))
  32. ((and (negative? (car xs)) (positive? (cadr xs)))
  33. (apply * (take 3 (reverse xs))))
  34. ((and (negative? (cadr xs))
  35. (negative? (caddr (reverse xs))))
  36. (* (car xs) (cadr xs) (last xs)))
  37. ((and (negative? (cadr xs))
  38. (positive? (caddr (reverse xs))))
  39. (max (apply * (take 3 (reverse xs)))
  40. (* (car xs) (cadr xs) (last xs))))
  41. (else (error 'max-prod-three "missed case")))))
  42.  
  43. (define (test-max-prod-three)
  44. (assert (+ 1 1) 3) ; testing assert
  45. (assert (max-prod-three '(1 2 3)) 6)
  46. (assert (max-prod-three '(-1 -2 -3)) -6)
  47. (assert (max-prod-three '(1 2 3 4)) 24)
  48. (assert (max-prod-three '(-1 2 3 4)) 24)
  49. (assert (max-prod-three '(1 -2 3 4)) 12)
  50. (assert (max-prod-three '(1 2 -3 4)) 8)
  51. (assert (max-prod-three '(1 2 3 -4)) 6)
  52. (assert (max-prod-three '(-1 -2 -3 -4)) -6)
  53. (assert (max-prod-three '(1 -2 -3 -4)) 12)
  54. (assert (max-prod-three '(-1 2 -3 -4)) 24)
  55. (assert (max-prod-three '(-1 -2 3 -4)) 24)
  56. (assert (max-prod-three '(-1 -2 -3 4)) 24)
  57. (assert (max-prod-three '(1 2 3 4 5)) 60)
  58. (assert (max-prod-three '(-1 -2 -3 -4 -5)) -6)
  59. (assert (max-prod-three '(1 2 -3 -4 -5)) 40)
  60. (assert (max-prod-three '(-1 -2 3 4 5)) 60)
  61. (assert (max-prod-three '(-1 -2 -3 4 5)) 30)
  62. (assert (max-prod-three '(1 -2 3 -4 5)) 40)
  63. (assert (max-prod-three '(-1 2 -3 4 -5)) 60)
  64. (assert (max-prod-three '(1 2 3 4 -5)) 24)
  65. (assert (max-prod-three '(-1 2 3 4 5)) 60)
  66. (assert (max-prod-three '(-1 -2 -3 -4 5)) 60)
  67. (assert (max-prod-three '(1 -2 -3 -4 -5)) 20)
  68. (assert (max-prod-three '(1 2 3 4 5 6 7)) 210)
  69. (assert (max-prod-three '(0 1 2 3)) 6)
  70. (assert (max-prod-three '(0 -1 -2 -3)) 0))
  71.  
  72. (test-max-prod-three)
Success #stdin #stdout 0.04s 43616KB
stdin
Standard input is empty
stdout
failed assertion:
(+ 1 1)
expected: 3
returned: 2