aboutsummaryrefslogtreecommitdiff
path: root/challenge-079
diff options
context:
space:
mode:
authorMyoungjin JEON <jeongoon@gmail.com>2020-09-25 22:58:17 +1000
committerMyoungjin JEON <jeongoon@gmail.com>2020-09-25 22:58:17 +1000
commit147fe8c1d051b49dce906d6eb355a64a204dc1b3 (patch)
tree1f69f6beca32a1d9ef214cbb084c2e6f423bf77b /challenge-079
parent80a00a8d1c7a3d0be6779b61371e4b7454d896a4 (diff)
downloadperlweeklychallenge-club-147fe8c1d051b49dce906d6eb355a64a204dc1b3.tar.gz
perlweeklychallenge-club-147fe8c1d051b49dce906d6eb355a64a204dc1b3.tar.bz2
perlweeklychallenge-club-147fe8c1d051b49dce906d6eb355a64a204dc1b3.zip
[ch-079/jeongoon] ch-2.hs ch-2.lsp added.
Diffstat (limited to 'challenge-079')
-rw-r--r--challenge-079/jeongoon/common-lisp/ch-2.lsp67
-rw-r--r--challenge-079/jeongoon/haskell/ch-2.hs59
2 files changed, 126 insertions, 0 deletions
diff --git a/challenge-079/jeongoon/common-lisp/ch-2.lsp b/challenge-079/jeongoon/common-lisp/ch-2.lsp
new file mode 100644
index 0000000000..10db378780
--- /dev/null
+++ b/challenge-079/jeongoon/common-lisp/ch-2.lsp
@@ -0,0 +1,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*)
diff --git a/challenge-079/jeongoon/haskell/ch-2.hs b/challenge-079/jeongoon/haskell/ch-2.hs
new file mode 100644
index 0000000000..69c74f1f8d
--- /dev/null
+++ b/challenge-079/jeongoon/haskell/ch-2.hs
@@ -0,0 +1,59 @@
+import System.Environment
+import System.Exit
+import Data.List (unfoldr, zipWith3)
+import Data.Char (isNumber)
+import Data.Maybe (isNothing, catMaybes)
+
+-- tested with: runhaskell ch-2.hs 2 1 4 1 2 5 6 8 2 1 3 4 8 1 3 2 9 3 7 3 1 2
+
+trappedRainWaterData hs
+ | length hs < 3 = Nothing
+ | otherwise =
+ let lefts = (tail.scanl1 max.init) hs
+ rights = (init.scanr1 max.tail) hs
+ mids = (init.tail) hs
+ -- padding front and back with zero to match the length of histogram
+ in Just $ 0 : (zipWith3 (\l m r -> (min l r) - m) lefts mids rights) ++ [0]
+
+-- modified from ch-075 :: ch-2.hs
+printHistogramWithWater :: [Int] -> [Int] -> IO ()
+printHistogramWithWater hdata wdata = do
+ mapM_ putStrLn lineBuffers where
+ hdataLen = length hdata
+ maxH = maximum hdata
+ lineBuffers = unfoldr forYaxis maxH
+ forYaxis (y)
+ -- footer
+ | y == 0 = Just( replicate (wordWidth * (hdataLen +1)) '_', y-1 )
+ | y == -1 = Just( whiteSpace
+ ++ (foldl (\acc x ->
+ acc ++ (fixedNumber x)) "" hdata) , y-1 )
+ | y < -1 = Nothing
+ -- data
+ | otherwise = Just( yScale ++ allColumnData, y-1 )
+ where
+ wordWidth = ((length.show) maxH) +1
+ whiteSpace = replicate wordWidth ' '
+ yScale = fixedNumber y
+ fixedNumber n = (preWhiteSpace n) ++ (show n)
+ padding = (replicate (wordWidth - 1) ' ')
+ sharpMark = padding ++ ['#']
+ waterMark = padding ++ ['~']
+ preWhiteSpace n = replicate (wordWidth - (length (show n))) ' '
+ allColumnData =
+ foldl (\acc (h, w) ->
+ acc ++ (if h >= y
+ then sharpMark
+ else if (h+w) >= y then waterMark else whiteSpace )) ""
+ (zip hdata wdata)
+
+main = do
+ hdata <- (catMaybes.map (\nStr ->
+ if (all isNumber nStr) then Just(read nStr :: Int)
+ else Nothing )) `fmap` getArgs;
+ let maybeWdata = trappedRainWaterData hdata in
+ case maybeWdata of
+ Nothing -> putStrLn "Too short histogram data (lenght must be> 2)"
+ Just wdata -> do
+ putStrLn $ "Total capacity: " ++ ((show.sum) wdata)
+ printHistogramWithWater hdata wdata