blob: 10db378780828dcce0f4c32988d421abb4b73a54 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
;; ( solution ... )
(defun max-list (a-list)
(let* ((cur-max)
(size (length a-list)))
(loop for x in a-list collect
(if (or (null cur-max) (< cur-max x)) (setq cur-max x) cur-max))))
(defun haskell/init (a-list) (reverse (rest (reverse a-list))))
(defun trapped-water-data (histogram-data)
(let* ((histo-size (length histogram-data))
(lefts (rest (max-list (haskell/init histogram-data))))
(rights (reverse (rest (max-list (reverse (rest histogram-data))))))
(mids (haskell/init (rest histogram-data)))
(waters-only (map 'list (lambda (l m r) (- (min l r) m)) lefts mids rights)))
(cons 0 (nconc waters-only '(0)))))
;; modified from ch-075 :: ch-2.lsp
(defun print-histogram-with-water (histogram-data water-data)
(let* ((histogram-size (length histogram-data))
(max-height (apply #'max histogram-data))
(word-width (1+ (length (format nil "~d" max-height))))
(fmt-string (format nil "~~~d@a" word-width)))
(loop for y from max-height downto 1 collect
(let* ((line (format nil fmt-string y)) ;; first column: y scale
)
;; whitespace or sharpmark
(map nil
(lambda (x-data w-data)
(let* ((current-word
(format nil fmt-string
(if (>= x-data y) "#"
(if (>= (+ x-data w-data) y) "~"
"")))))
(setq line(concatenate 'string line current-word))))
histogram-data water-data)
(format t "~a~%" line)
line))
(format t "~a~%" (make-string (* word-width (1+ histogram-size))
:initial-element #\_))
(format t fmt-string "")
(map nil
#'(lambda (x-data) (format t fmt-string x-data)) histogram-data)
(format t "~%")))
; ( testing ... )
(defun get-command-line ()
(or
#+CLISP *args*
#+SBCL *posix-argv*
#+LISPWORKS system:*line-arguments-list*
#+CMU extensions:*command-line-words*
nil))
(defparameter *cmdline* (get-command-line))
(defun print-usage ()
(format t "Usage: sbcl --script ch-2.lsp <at least three histogram data> ..."
(first *cmdline*)))
(when (< (length *cmdline*) 4) (print-usage) (quit))
(defparameter *histogram-data* (map 'list #'parse-integer (rest *cmdline*)))
;;(format t "~a~%" *histogram-data*)
(defvar *water-data* (trapped-water-data *histogram-data*))
(format t "Total capacity: ~a~%" (reduce '+ *water-data*))
(print-histogram-with-water *histogram-data* *water-data*)
|