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. ((positive? (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.
70. (test-max-prod-three)
Success #stdin #stdout 0.03s 8952KB
stdin
Standard input is empty
stdout
failed assertion:
(+ 1 1)
expected: 3
returned: 2