aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2020-11-29 18:09:11 +0000
committerGitHub <noreply@github.com>2020-11-29 18:09:11 +0000
commit2d77a41a573354f71849ccc627eac0ac834805f4 (patch)
treee6a5d4d5a99fa3670ab9d171ec6991a397ecb5ee
parent8f4c1b97453d02492a7738b1f0cb6c7358af4ae9 (diff)
parent8178fe5e04e95cfbc20c8bb2d4210bc848cb76af (diff)
downloadperlweeklychallenge-club-2d77a41a573354f71849ccc627eac0ac834805f4.tar.gz
perlweeklychallenge-club-2d77a41a573354f71849ccc627eac0ac834805f4.tar.bz2
perlweeklychallenge-club-2d77a41a573354f71849ccc627eac0ac834805f4.zip
Merge pull request #2866 from jeongoon/master
[ch-088/jeongoon] Perl, Raku, Haskell, Go, Common-lisp, Elm solution added.
-rw-r--r--challenge-086/jeongoon/haskell/ch-1.hs42
-rw-r--r--challenge-087/jeongoon/haskell/ch-1.hs6
-rw-r--r--challenge-087/jeongoon/haskell/ch-2.hs106
-rw-r--r--challenge-088/jeongoon/common-lisp/ch-1.lsp29
-rw-r--r--challenge-088/jeongoon/common-lisp/ch-2.lsp105
-rw-r--r--challenge-088/jeongoon/elm/elm.json24
-rw-r--r--challenge-088/jeongoon/elm/src/Ch1.elm18
-rw-r--r--challenge-088/jeongoon/elm/src/Ch2.elm79
-rw-r--r--challenge-088/jeongoon/elm/src/Main.elm129
-rw-r--r--challenge-088/jeongoon/fish/ch-1.fish16
-rw-r--r--challenge-088/jeongoon/go/ch-1.go47
-rw-r--r--challenge-088/jeongoon/go/ch-2.go94
-rw-r--r--challenge-088/jeongoon/haskell/ch-1.hs13
-rw-r--r--challenge-088/jeongoon/haskell/ch-2.hs81
-rw-r--r--challenge-088/jeongoon/perl/ch-1.pl20
-rw-r--r--challenge-088/jeongoon/perl/ch-2.pl74
-rw-r--r--challenge-088/jeongoon/raku/ch-1.raku15
-rw-r--r--challenge-088/jeongoon/raku/ch-2.raku75
18 files changed, 971 insertions, 2 deletions
diff --git a/challenge-086/jeongoon/haskell/ch-1.hs b/challenge-086/jeongoon/haskell/ch-1.hs
new file mode 100644
index 0000000000..59a46bb9ec
--- /dev/null
+++ b/challenge-086/jeongoon/haskell/ch-1.hs
@@ -0,0 +1,42 @@
+import System.Environment
+import System.Exit
+import Data.Char (isNumber)
+import Data.Maybe (isNothing, catMaybes)
+import Data.List (sort)
+
+{- tested with:
+runhaskell ch-1.hs 1 3 2 -1 -2 -3 6 7 9 1
+1 as 3 - 2 = 1
+-}
+
+usageMessage = "Usage: runhaskell ch-1.hs "
+ ++ "<target diff(positive integer)> <integer> ..."
+
+pairDifference _ [] = Nothing
+pairDifference target ls = pairdiff target (head sorted) (tail sorted) 1
+ where
+ sorted = sort ls
+ pairdiff _ _ [] _ = Nothing
+ pairdiff t f rst@(r:_) i = -- t: target, f: first, i: index
+ if i >= (length rst) then Nothing
+ else case ((rst !! i) - f) `compare` t of
+ LT -> pairdiff t f rst (succ i)
+ GT -> pairdiff t r rst 1
+ EQ -> Just (f, (rst !! i))
+
+main = do
+ (catMaybes.map (\nStr ->
+ -- poor parser
+ if (all (`elem` "0123456789+-") nStr)
+ then Just(read nStr :: Int)
+ else Nothing )) `fmap` getArgs
+ >>= ( \ints ->
+ let d = (head ints) in
+ if (length ints) < 2
+ then die usageMessage
+ else if d < 0
+ then die usageMessage
+ else case pairDifference d (tail ints) of
+ Nothing -> putStrLn "0"
+ Just (a,b) -> putStrLn $ "1 as " ++ (show b) ++ " - "
+ ++ (show a) ++ " = " ++ (show d) )
diff --git a/challenge-087/jeongoon/haskell/ch-1.hs b/challenge-087/jeongoon/haskell/ch-1.hs
index dc2d24e980..23879e69f2 100644
--- a/challenge-087/jeongoon/haskell/ch-1.hs
+++ b/challenge-087/jeongoon/haskell/ch-1.hs
@@ -1,6 +1,5 @@
import System.Environment
import System.Exit
-import Data.Char (isNumber)
import Data.Maybe (catMaybes)
import Data.List (sort, sortBy)
@@ -8,6 +7,7 @@ import Data.List (sort, sortBy)
(only shows one answer)
-}
+
answerLongestConsecutiveSequence :: [Int] -> [Int]
answerLongestConsecutiveSequence =
( head
@@ -22,7 +22,9 @@ answerLongestConsecutiveSequence =
main = do
(catMaybes.map (\nStr ->
- if (all isNumber nStr) then Just(read nStr :: Int)
+ -- poor parser
+ if (all (`elem` "0123456789+-") nStr)
+ then Just(read nStr :: Int)
else Nothing )) `fmap` getArgs
>>= (\nums ->
if length nums < 1 then
diff --git a/challenge-087/jeongoon/haskell/ch-2.hs b/challenge-087/jeongoon/haskell/ch-2.hs
new file mode 100644
index 0000000000..02328a8458
--- /dev/null
+++ b/challenge-087/jeongoon/haskell/ch-2.hs
@@ -0,0 +1,106 @@
+import System.Exit
+import Data.List (isPrefixOf, groupBy, subsequences, union
+ , intersperse, replicate)
+import Data.Char (digitToInt)
+import qualified Data.Map as M
+
+{- tested with:
+echo '[000111][111111][001001][001111][001111]' | runhaskell ch-2.hs
+
+-}
+
+-- solution
+getMatrixFromStdin :: IO [[Int]]
+getMatrixFromStdin = ( convertToInteger
+ -- . filterEmptyRow
+ . parseMatrixLines
+ . toMatrixLines ) `fmap` getContents
+ where
+ parseMatrixLines = map (filter (not.isPrefixOf " ").
+ groupBy (\a b -> a == ' ' && a == b).
+ filter (\c -> c `elem` " 10"))
+ toMatrixLines = lines . unlines . groupBy (\_ b -> b /= ']')
+ --filterEmptyRow = filter ((0/=).length)
+ convertToInteger = map (map (\x -> (map digitToInt x)!!0))
+
+ -- a line between column A to B
+data ConsecutivePoints = ConsecutivePoints { begin :: Int,
+ end :: Int }
+ deriving (Eq, Ord, Show)
+
+groupByConsecutiveNumber_ :: (Eq a, Num a) => [a] -> [[a]]
+groupByConsecutiveNumber_ =
+ foldl (\acc x -> if ((not.null) acc)
+ then if (x -(last (last acc))) == 1
+ then (init acc) ++ [(last acc) ++ [x]]
+ else acc ++ [[x]]
+ else [[x]] ) []
+
+getConsecutivePointsFromMatrix :: [[Int]] -> [(ConsecutivePoints, Int)]
+getConsecutivePointsFromMatrix =
+ ( foldr (\x acc -> let (pts, r) = x
+ in acc ++ (map (\p -> (p, r)) pts) ) []
+ . zipWithRowNum -- -> [([ConsecutivePoints], Int)]
+ . map ( map toConsecutivePoints
+ . consecutiveLinesFromIndices
+ . binariesToIndices ) )
+ where
+ subsequences' = filter ((0<).length) . subsequences
+ binariesToIndices :: [Int] -> [Int]
+ binariesToIndices row = foldl (\acc x -> if ((1==).snd) x
+ then acc ++ [(fst x)]
+ else acc ) [] (zip [0..] row)
+ consecutiveLinesFromIndices :: [Int] -> [[Int]]
+ consecutiveLinesFromIndices = ( foldr (++) [] -- flatten
+ . map subsequences'
+ . groupByConsecutiveNumber_ )
+ zipWithRowNum = (flip zip) [0..]
+
+ toConsecutivePoints :: [Int] -> ConsecutivePoints
+ toConsecutivePoints = (\xs -> ConsecutivePoints (head xs) (last xs))
+
+groupByConsecutivePoints :: [(ConsecutivePoints, Int)]
+ -> [(ConsecutivePoints,[Int])]
+groupByConsecutivePoints ls = (M.toList . M.fromListWith union)
+ $ map (\(k,v) -> (k,[v])) ls
+
+groupByArea :: [(ConsecutivePoints, [Int])]
+ -> [((ConsecutivePoints, [Int]), Int)]
+groupByArea =
+ foldr (++) []
+ . map (\(ps , rs) ->
+ map (\rs' -> ((ps, rs'), ((length rs')
+ * ((end ps) - (begin ps) + 1))))
+ (groupByConsecutiveNumber_ rs))
+
+findMaximumAreas :: [((ConsecutivePoints, [Int]), Int)]
+ -> [((ConsecutivePoints, [Int]), Int)]
+findMaximumAreas = foldr (\x@(_, area) acc ->
+ let maxarea = if null acc then 0
+ else (snd.head) acc
+ in if area > maxarea then [x]
+ else if area == maxarea then acc ++ [x]
+ else acc) []
+showMaxAreas :: [((ConsecutivePoints, [Int]), Int)] -> [[String]]
+showMaxAreas =
+ map (\((cpts, rs), area) ->
+ if area == 1 then []
+ else let nc = (end cpts) - (begin cpts) + 1
+ nr = length rs
+ in (replicate nr.intersperse ' '. replicate nc) '1')
+
+-- testing
+main = do
+ aSample <- getMatrixFromStdin;
+ putStrLn "Given Matrix:"
+ mapM_ (putStrLn.unwords.map show) aSample
+
+ if length aSample < 1
+ then die "0 as given data is not sufficient"
+ else let visibleMaxAreas = ( showMaxAreas
+ . findMaximumAreas
+ . groupByArea
+ . groupByConsecutivePoints
+ . getConsecutivePointsFromMatrix ) aSample
+ in if null visibleMaxAreas then putStrLn "0"
+ else mapM_ (mapM_ putStrLn) visibleMaxAreas
diff --git a/challenge-088/jeongoon/common-lisp/ch-1.lsp b/challenge-088/jeongoon/common-lisp/ch-1.lsp
new file mode 100644
index 0000000000..2ca1933fb3
--- /dev/null
+++ b/challenge-088/jeongoon/common-lisp/ch-1.lsp
@@ -0,0 +1,29 @@
+;; tested with sbcl --script ch-1.lsp 5 2 1 4 3
+
+;;; Comment:
+;; I thought (sort x #'<) is sorted in place of x
+;; however, it didn't work properly until I did (setq x (sort x #'<))
+
+
+(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-1.lsp <integer> ..."))
+
+(when (< (length *cmdline*) 1) (print-usage) (quit))
+
+(defparameter *integer-list* (map 'list #'parse-integer (rest *cmdline*)))
+
+;; (solution ...)
+(let ((p (reduce #'* *integer-list*)))
+ (format t "~A~%" (map 'list #'(lambda (x) (/ p x)) *integer-list*)))
+
+(quit)
diff --git a/challenge-088/jeongoon/common-lisp/ch-2.lsp b/challenge-088/jeongoon/common-lisp/ch-2.lsp
new file mode 100644
index 0000000000..8c926259de
--- /dev/null
+++ b/challenge-088/jeongoon/common-lisp/ch-2.lsp
@@ -0,0 +1,105 @@
+;; tested with:
+;; echo "[a b c][d e f][g h i] | sbcl --script ch-2.lsp
+
+(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))
+(defparameter *rows-list* '())
+(defvar row '())
+(defvar wrd nil)
+
+;; read from stdin
+(loop for line = (read-line *standard-input* nil)
+ while line
+ do(loop for ch in (coerce line 'list)
+ do(if (char= ch #\[)
+ Nil ;; ignore
+ (if (or (char= ch #\]) (char= ch #\Newline))
+ (progn
+ (when (not (null wrd))
+ (let ((word-str (coerce wrd 'string)))
+ (if (null row)
+ (setq row (list word-str))
+ (nconc row (list word-str))))
+ (setq wrd '()))
+ (when (not (null row))
+ (if (null *rows-list*)
+ (setq *rows-list* (list row))
+ (nconc *rows-list* (list row)))
+ (setq row '())))
+ (if (char= ch #\Space)
+ ;; add a word to row
+ (when (not (null wrd))
+ (let ((word-str (coerce wrd 'string)))
+ (if (null row)
+ (setq row (list word-str))
+ (nconc row (list word-str))))
+ (setq wrd '()))
+ ;; else: add a char to word
+ (progn
+ (if (null wrd)
+ (setq wrd (list ch))
+ (nconc wrd (list ch)))))))))
+
+(defparameter *num-rows* (length *rows-list*))
+(defparameter *num-cols* (length (first *rows-list*)))
+
+;; convert it into 2 dimensional array
+(defvar *matrix* (make-array (list *num-rows* *num-cols*)
+ :initial-contents *rows-list*))
+
+;; confirm input
+(format t "given matrix:~%")
+(dotimes (r *num-rows*)
+ (setq row (loop for c from 0 below *num-cols*
+ collect (aref *matrix* r c)))
+ (format t "[~{~a~^ ~}]~%" row))
+
+;; ( solution ... )
+;; this solution is only for reading
+;; so I haven't check for any side effect
+(defun get-spiral-array (mat) ;; take 2 dimensional array
+ (let* ((num-rows (array-dimension mat 0))
+ (num-cols (array-dimension mat 1))
+ (sarray '())) ;; result
+ (loop for o from 0
+ for row-end = (1- (+ o num-rows))
+ for col-end = (1- (+ o num-cols))
+ do (progn
+ ;; north
+ (let ((north-side (loop for c from o upto col-end
+ collect (aref mat o c))))
+ (if (null sarray)
+ (setq sarray north-side)
+ (nconc sarray north-side)))
+ ;; east
+ (let ((east-side (loop for r from (1+ o) upto row-end
+ collect (aref mat r col-end))))
+ (when (not (null east-side))
+ (nconc sarray east-side)
+ ;; south
+ (let ((south-side
+ (loop for c from (1- col-end) downto o
+ collect (aref mat row-end c))))
+ (when (not (null south-side))
+ (nconc sarray south-side)
+ ;; west
+ (let ((west-side
+ (loop for r from (1- row-end) above o
+ collect (aref mat r o))))
+ (when (not (null west-side))
+ (nconc sarray west-side))))))))
+ ;; go inner
+ do (progn (setq num-rows (- num-rows 2)
+ num-cols (- num-cols 2)))
+ while (and (< 0 num-rows) (< 0 num-cols)))
+
+ sarray)) ;; return
+
+(format t "[~{~a~^ ~}]~%" (get-spiral-array *matrix*))
diff --git a/challenge-088/jeongoon/elm/elm.json b/challenge-088/jeongoon/elm/elm.json
new file mode 100644
index 0000000000..dea3450db1
--- /dev/null
+++ b/challenge-088/jeongoon/elm/elm.json
@@ -0,0 +1,24 @@
+{
+ "type": "application",
+ "source-directories": [
+ "src"
+ ],
+ "elm-version": "0.19.1",
+ "dependencies": {
+ "direct": {
+ "elm/browser": "1.0.2",
+ "elm/core": "1.0.5",
+ "elm/html": "1.0.0"
+ },
+ "indirect": {
+ "elm/json": "1.1.3",
+ "elm/time": "1.0.0",
+ "elm/url": "1.0.0",
+ "elm/virtual-dom": "1.0.2"
+ }
+ },
+ "test-dependencies": {
+ "direct": {},
+ "indirect": {}
+ }
+}
diff --git a/challenge-088/jeongoon/elm/src/Ch1.elm b/challenge-088/jeongoon/elm/src/Ch1.elm
new file mode 100644
index 0000000000..18baf715d0
--- /dev/null
+++ b/challenge-088/jeongoon/elm/src/Ch1.elm
@@ -0,0 +1,18 @@
+module Ch1 exposing (..)
+
+import List as L
+
+errEmptyList = "Empty List"
+errSomeIsNotPostive = "Some of Element is not Postive Interger"
+
+arrayOfProduct : List Int -> Result String (List Int)
+arrayOfProduct ints =
+ let len = (L.length ints)
+ in
+ case len of
+ 0 -> Err errEmptyList
+ 1 -> Ok [1] -- not in the spec; probably correct answer
+ _ -> if (L.any (\x -> x < 1) ints) == True then
+ Err errSomeIsNotPostive
+ else let p = L.foldr (*) 1 ints
+ in Ok (L.map (\x -> p // x) ints) -- // -> int div.
diff --git a/challenge-088/jeongoon/elm/src/Ch2.elm b/challenge-088/jeongoon/elm/src/Ch2.elm
new file mode 100644
index 0000000000..1841c81750
--- /dev/null
+++ b/challenge-088/jeongoon/elm/src/Ch2.elm
@@ -0,0 +1,79 @@
+module Ch2 exposing (..)
+
+import List as L
+import String as S
+import Array as A
+import Result as R
+
+errEmptyMatrix = "Matrix is Empty"
+
+parseMatrix : String -> Result String (List (List String))
+parseMatrix str =
+ let parsed = str -- Elm's nice syntax: read from top to bottom
+ |> S.split "]"
+ |> S.join "\n"
+ |> S.lines
+ |> L.map (S.replace "[" ""
+ >> S.words >> L.filter (S.isEmpty >> not))
+ |> L.filter (L.isEmpty >> not)
+ in if L.isEmpty parsed
+ || (case L.head parsed of
+ Nothing -> True
+ Just fr -> L.isEmpty fr) then
+ Err errEmptyMatrix
+ else
+ Ok parsed
+
+getSpiralArray_ : (List (List String)) -> Int -> Int -> Int -> List String
+getSpiralArray_ mat nr nc o = -- number of rows, number of column
+ let re = o + nr - 1 -- abs index number of row end
+ ce = o + nc - 1 -- abs index number of column end
+ north = case (L.drop o >> L.head) mat of
+ Nothing -> []
+ Just rw -> (L.take (o+nc) >> L.drop o) rw
+ east = if nr <= 1 then []
+ else mat
+ |> L.drop (o+1)
+ |> L.take (nr-1)
+ |> L.filterMap (L.drop ce >> L.head)
+ south = {-if L.isEmpty east then []
+ else-}
+ if nc <= 1 then []
+ else case (L.drop re >> L.head) mat of
+ Nothing -> []
+ Just rw -> rw |> L.reverse
+ |> L.drop (o+1) |> L.take (nc-1)
+ west = {-if L.isEmpty south then []
+ else-}
+ if nr <= 2 then []
+ else mat
+ |> L.drop (o+1)
+ |> L.take (nr-2)
+ |> L.reverse
+ |> L.filterMap (L.drop o >> L.head)
+
+ nr2 = nr - 2
+ nc2 = nc - 2
+
+ in ( if re < 0 || ce < 0 then []
+ else north :: if L.isEmpty east then []
+ else east :: if L.isEmpty south then []
+ else south :: if L.isEmpty west then []
+ else west
+ :: [ getSpiralArray_
+ mat nr2 nc2 (o+1) ] )
+ |> L.concat
+
+getSpiralArray : (List (List String)) -> List String
+getSpiralArray mat =
+ let nr = L.length mat
+ nc = case L.head mat of
+ Nothing -> -1
+ Just rw -> L.length rw
+ in if nr > 0 && nc > 0 then getSpiralArray_ mat nr nc 0
+ else []
+
+getSpiralArrayFromString : String -> Result String (List String)
+getSpiralArrayFromString str =
+ str |> parseMatrix
+ |> R.map getSpiralArray
diff --git a/challenge-088/jeongoon/elm/src/Main.elm b/challenge-088/jeongoon/elm/src/Main.elm
new file mode 100644
index 0000000000..7a051aca5f
--- /dev/null
+++ b/challenge-088/jeongoon/elm/src/Main.elm
@@ -0,0 +1,129 @@
+{- Tested with:
+elm make src/Main.elm
+# and access elm/index.html in a web browser(firefox in my case)
+# which shows Task1 and Task2 altogether
+# or ...
+elm reactor
+# and access localhost:8000 (again in a web browser)
+# and click `Main.elm'
+-}
+
+module Main exposing (..)
+
+import Browser
+import Html exposing (..)
+import Html.Attributes exposing (..)
+import Html.Events exposing (onInput)
+
+import String as S
+import List as L
+import Result as R
+
+-- Solutions ...
+import Ch1 exposing (..)
+import Ch2 exposing (..)
+
+-- Main
+
+main =
+ Browser.sandbox { init = init, update = update, view = view }
+
+-- Model
+type alias Model =
+ { ch1IntListStr : String
+ , ch1Result : Result String (List Int)
+ , ch2MatrixStr : String
+ , ch2Result : Result String (List String)
+ }
+
+init : Model
+init = Model "" (Err "") "" (Err "")
+
+-- Update
+
+type Task = Task1
+type Msg = ArrayProductValueChanged String
+ | SpiralMatrixValueChanged String
+
+getPositiveIntegerListFromString : String -> Result String (List Int)
+getPositiveIntegerListFromString str =
+ let trimed_str = S.trim str
+ sls = (S.split " " trimed_str)
+ ints = L.filterMap S.toInt sls
+ in if S.length trimed_str == 0 then
+ Err "" -- indicate initial state
+ else if (L.length sls) == (L.length ints) then Ok ints
+ else Err "Some element doesn't look like a POSITIVE integer"
+
+update : Msg -> Model -> Model
+update msg m =
+ case msg of
+ ArrayProductValueChanged nv ->
+ let res = (getPositiveIntegerListFromString nv
+ |> R.andThen Ch1.arrayOfProduct)
+ in { m | ch1IntListStr = nv
+ , ch1Result = res }
+ SpiralMatrixValueChanged nv ->
+ let res = Ch2.getSpiralArrayFromString nv
+ in { m | ch2MatrixStr = nv
+ , ch2Result = res }
+
+-- View
+
+view : Model -> Html Msg
+view m =
+ div [ style "padding" "20px", style "width" "90%" ]
+ [ h1 [] [ text "Task1: Array Product" ]
+ , viewInput "text" "Positive Integers" m.ch1IntListStr
+ ArrayProductValueChanged
+ , displayAnswerCh1 m.ch1Result
+ , h1 [] [ text "Task2: Spiral Matrix" ]
+ , viewInputTextArea "Please Input a matrix data.\nex)\n[a b c]\n[d e f]\n[g h i]"
+ m.ch2MatrixStr SpiralMatrixValueChanged
+ , displayAnswerCh2 m.ch2Result
+ ]
+
+viewInput : String -> String -> String -> (String -> msg) -> Html msg
+viewInput t p v toMsg =
+ div [ style "dispay" "inline-block" ]
+ [ input [ size 150, type_ t, placeholder p, value v, onInput toMsg ] []]
+
+viewInputTextArea : String -> String -> (String -> msg) -> Html msg
+viewInputTextArea p v toMsg =
+ div [ style "display" "inline-block" ]
+ [ textarea [ rows 5, cols 150
+ , placeholder p, value v, onInput toMsg ] [] ]
+
+displayAnswerCh1 : Result String (List Int) -> Html msg
+displayAnswerCh1 result =
+ displayAnswer "Result"
+ (case result of
+ Ok ints -> Ok ("(" ++ (S.join ","
+ (L.map S.fromInt ints)) ++")")
+ Err e -> Err e)
+
+displayAnswerCh2 : Result String (List String) -> Html msg
+displayAnswerCh2 result =
+ displayAnswer "Result"
+ (case result of
+ Ok words -> Ok ("(" ++ (S.join "," words) ++ ")")
+ Err e -> Err e)
+
+
+displayAnswer : String -> Result String String -> Html msg
+displayAnswer entryString result =
+ case result of
+ Ok msg -> div []
+ [ viewReadOnlyTextArea "green" msg ]
+ Err e ->
+ if e == ""
+ then div []
+ [ viewReadOnlyTextArea "blue"
+ (entryString ++ ": please input all the entries") ]
+ else div []
+ [ viewReadOnlyTextArea "red" e ]
+
+viewReadOnlyTextArea : String -> String -> Html msg
+viewReadOnlyTextArea color str =
+ textarea [ readonly True, style "color" color
+ , rows 15, cols 150, value str ] []
diff --git a/challenge-088/jeongoon/fish/ch-1.fish b/challenge-088/jeongoon/fish/ch-1.fish
new file mode 100644
index 0000000000..f7b957360a
--- /dev/null
+++ b/challenge-088/jeongoon/fish/ch-1.fish
@@ -0,0 +1,16 @@
+#!/usr/bin/env fish
+
+set all_product 1
+set M ()
+
+for x in $argv
+ set all_product (math "$all_product x $x")
+end
+
+set i 1
+for x in $argv
+ set M[$i] (math -s0 "$all_product / $x")
+ set i (math "$i + 1")
+end
+
+echo "[$M]"
diff --git a/challenge-088/jeongoon/go/ch-1.go b/challenge-088/jeongoon/go/ch-1.go
new file mode 100644
index 0000000000..c18be3d9a1
--- /dev/null
+++ b/challenge-088/jeongoon/go/ch-1.go
@@ -0,0 +1,47 @@
+package main
+
+import (
+ "os"
+ "fmt"
+ "strconv"
+)
+
+func usage() {
+ fmt.Println( "Usage: go run ch-1.go <integer> ..." )
+}
+
+func main() {
+ switch len(os.Args[1:]) {
+ case 0:
+ usage()
+ os.Exit(1);
+ case 1:
+ fmt.Println("1")
+ os.Exit(0);
+ }
+
+ var ns []int
+
+ for _, nstr := range os.Args[1:] {
+ n, err := strconv.Atoi(nstr)
+ if err == nil {
+ ns = append(ns, n)
+ } else {
+ fmt.Fprintln(os.Stderr, nstr, "is ignored: ", err)
+ }
+ }
+
+ p := 1
+ for _, v := range ns {
+ p *= v
+ }
+
+ var ms []int
+
+ for _,v := range ns {
+ ms = append(ms, (p/v))
+ }
+
+ fmt.Println(ms)
+ os.Exit(0)
+}
diff --git a/challenge-088/jeongoon/go/ch-2.go b/challenge-088/jeongoon/go/ch-2.go
new file mode 100644
index 0000000000..bd0773749c
--- /dev/null
+++ b/challenge-088/jeongoon/go/ch-2.go
@@ -0,0 +1,94 @@
+/* tested with:
+ * echo "[a b c][d e f][g h i]" | go run ch-2.go
+ * echo "[a b c d][e f g h][i j k l]" | go run ch-2.go
+ */
+
+package main
+
+import (
+ "os"
+ "bufio"
+ "fmt"
+ "strings"
+)
+
+func usage() {
+ fmt.Println( "Usage: echo [a b c][d e f][g h i][j k l]' | go run ch-2.go" )
+}
+
+func parseMatrix (raw string) [][]string {
+ var mat [][]string
+
+ lines := strings.Split(raw, "\n")
+ for _, line := range lines {
+ sublines := strings.Split(line, "]")
+
+ for _, sl := range sublines {
+ if len(sl) < 1 {
+ continue
+ }
+ ws := strings.Split(sl, " ")
+ var words []string
+ for _, w := range ws {
+ if len(w) < 1 {
+ continue
+ }
+ words = append(words,
+ strings.Replace(w, "[", "", 1))
+ }
+ mat = append(mat, words)
+ }
+
+ }
+ return mat
+}
+
+// translate from ch-2.lsp
+func getSpiralArray (mat [][]string) []string {
+ var sarr []string
+
+ num_rows := len(mat)
+ num_cols := len(mat[0])
+ for o := 0 ; num_rows > 0 && num_cols > 0; o++ {
+ row_end := o + num_rows -1
+ col_end := o + num_cols -1
+ // north
+ sarr = append(sarr, mat[o][o:col_end+1]...)
+ // east
+ if num_rows > 1 {
+ for r := o+1; r <= row_end; r++ {
+ sarr = append(sarr, mat[r][col_end])
+ }
+ // south
+ if num_cols > 1 {
+ for c := col_end -1; c >= o; c-- {
+ sarr = append(sarr, mat[row_end][c])
+ }
+ // west
+ if num_rows > 2 {
+ for r := row_end -1; r > o; r-- {
+ sarr = append(sarr, mat[r][o]);
+ }
+ }
+ }
+ }
+
+ // go inner
+ num_rows -= 2
+ num_cols -= 2
+ }
+
+ return sarr
+}
+
+func main() {
+ reader := bufio.NewReader(os.Stdin)
+ matrixString, _ := reader.ReadString('')
+ matrix := parseMatrix(matrixString)
+ if len(matrix) < 1 {
+ usage()
+ os.Exit(1)
+ }
+
+ fmt.Println(getSpiralArray(matrix))
+}
diff --git a/challenge-088/jeongoon/haskell/ch-1.hs b/challenge-088/jeongoon/haskell/ch-1.hs
new file mode 100644
index 0000000000..d3d52dce8a
--- /dev/null
+++ b/challenge-088/jeongoon/haskell/ch-1.hs
@@ -0,0 +1,13 @@
+import System.Environment
+import System.Exit
+import Data.Char (isNumber)
+import Data.Maybe (catMaybes)
+
+arrayOfProduct [] = [1] -- assume 1 as spec doesn't consider this case
+arrayOfProduct ns = let total = product ns in map (total `div`) ns
+
+main = do
+ ns <- (catMaybes.map (\nStr ->
+ if (all isNumber nStr) then Just(read nStr :: Int)
+ else Nothing )) `fmap` getArgs;
+ print $ arrayOfProduct ns
diff --git a/challenge-088/jeongoon/haskell/ch-2.hs b/challenge-088/jeongoon/haskell/ch-2.hs
new file mode 100644
index 0000000000..691aaad582
--- /dev/null
+++ b/challenge-088/jeongoon/haskell/ch-2.hs
@@ -0,0 +1,81 @@
+import Data.List (groupBy, transpose, unfoldr)
+import Data.Maybe (catMaybes)
+
+{- tested with:
+echo "[a b c d][e f g h][i j k l]" | runhaskell ch-2.hs
+echo "[1 2 3][4 5 6][7 8 9]" | runhaskell ch-2.hs
+echo "[a b][c d][e f]" | runhaskell ch-2.hs
+-}
+
+getMatrixFromStdin :: IO [[String]]
+getMatrixFromStdin =
+ ( map words
+ . filter ((0/=).length) -- 5. (after 3) there is some empty row
+ . map (filter (`notElem` "[]")) -- 4. '[', ']' is not used
+ . lines -- 3. devide it into rows
+ . unlines -- 2. make it "]\n"
+ . groupBy (\_ b -> b/= ']') ) -- 1. devide row by "]"
+ `fmap` getContents
+
+-- cut outside of a matrix
+getInnerMatrix :: [[String]] -> Either String [[String]]
+getInnerMatrix m
+ | length m <= 1 = Left "Too Short In Row"
+ | otherwise = mapCutColumns [] getShorterInRows
+ where
+ mapCutColumns acc [] = Right acc
+ mapCutColumns acc (r:rs) =
+ case getShorterInCols r of
+ Nothing -> Left "Too Short In Column"
+ Just r' -> mapCutColumns (acc ++ [r']) rs
+ getShorterInRows = (init.tail) m -- cut top and bottom
+ getShorterInCols row =
+ if (length row) <= 1 then Nothing
+ else Just $ (init.tail) row
+
+-- read outside cells starting from (0,0) in clockwise
+readAroundMatrixCW :: [[String]] -> [String]
+readAroundMatrixCW [] = []
+readAroundMatrixCW m =
+ foldr1 (++) $
+ getNorth
+ : case findEast of
+ Nothing -> []
+ Just e -> e
+ : case findSouth of
+ Nothing -> []
+ Just s -> s
+ : case findWest of
+ Nothing -> []
+ Just w -> [w]
+ where
+ tm = transpose m
+ getNorth = head m
+ findEast = if (length m) == 1 then Nothing
+ else Just $ (tail.last) tm
+ findSouth = {-if (length m) == 1 then Nothing
+ else-} -- already checked when findEast
+ let lm = (last m)
+ in if (length lm) == 1 then Nothing
+ else Just $ (reverse.init) lm
+ findWest = {-if (length m) == 1 then Nothing
+ else-}
+ let htm = (head tm)
+ in if (length htm) <= 2 then Nothing
+ else Just $ (reverse.tail.init) htm
+
+getSpiralAarray :: [[String]] -> [String]
+getSpiralAarray mat =
+ foldr1 (++)
+ ( unfoldr (\m ->
+ case m of
+ Nothing -> Nothing
+ Just m' -> case (getInnerMatrix m') of
+ Left _ -> Just (outOf m', Nothing)
+ Right m'' -> Just (outOf m', Just m''))
+ (Just mat) )
+ where outOf m = readAroundMatrixCW m
+
+main = do
+ getSpiralAarray `fmap` getMatrixFromStdin
+ >>= print
diff --git a/challenge-088/jeongoon/perl/ch-1.pl b/challenge-088/jeongoon/perl/ch-1.pl
new file mode 100644
index 00