diff options
| author | Myoungjin JEON <jeongoon@gmail.com> | 2020-11-29 22:46:46 +1100 |
|---|---|---|
| committer | Myoungjin JEON <jeongoon@gmail.com> | 2020-11-29 22:46:46 +1100 |
| commit | 8178fe5e04e95cfbc20c8bb2d4210bc848cb76af (patch) | |
| tree | b087467fa501c5576ed7328368a52dfba37b7be8 | |
| parent | 71c1105173866e6b2419a40255465ef74a1fc280 (diff) | |
| download | perlweeklychallenge-club-8178fe5e04e95cfbc20c8bb2d4210bc848cb76af.tar.gz perlweeklychallenge-club-8178fe5e04e95cfbc20c8bb2d4210bc848cb76af.tar.bz2 perlweeklychallenge-club-8178fe5e04e95cfbc20c8bb2d4210bc848cb76af.zip | |
[ch-088/jeongoon] Perl, Raku, Haskell, Go, Common-lisp, Elm Solution added
| -rw-r--r-- | challenge-088/jeongoon/common-lisp/ch-1.lsp | 29 | ||||
| -rw-r--r-- | challenge-088/jeongoon/common-lisp/ch-2.lsp | 105 | ||||
| -rw-r--r-- | challenge-088/jeongoon/elm/elm.json | 24 | ||||
| -rw-r--r-- | challenge-088/jeongoon/elm/src/Ch1.elm | 18 | ||||
| -rw-r--r-- | challenge-088/jeongoon/elm/src/Ch2.elm | 79 | ||||
| -rw-r--r-- | challenge-088/jeongoon/elm/src/Main.elm | 129 | ||||
| -rw-r--r-- | challenge-088/jeongoon/fish/ch-1.fish | 16 | ||||
| -rw-r--r-- | challenge-088/jeongoon/go/ch-1.go | 47 | ||||
| -rw-r--r-- | challenge-088/jeongoon/go/ch-2.go | 94 | ||||
| -rw-r--r-- | challenge-088/jeongoon/haskell/ch-1.hs | 13 | ||||
| -rw-r--r-- | challenge-088/jeongoon/haskell/ch-2.hs | 81 | ||||
| -rw-r--r-- | challenge-088/jeongoon/perl/ch-1.pl | 20 | ||||
| -rw-r--r-- | challenge-088/jeongoon/perl/ch-2.pl | 74 | ||||
| -rw-r--r-- | challenge-088/jeongoon/raku/ch-1.raku | 15 | ||||
| -rw-r--r-- | challenge-088/jeongoon/raku/ch-2.raku | 75 |
15 files changed, 819 insertions, 0 deletions
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 0000000000..63478dc908 --- /dev/null +++ b/challenge-088/jeongoon/perl/ch-1.pl @@ -0,0 +1,20 @@ +#!/usr/bin/env perl +# -*- Mode: cperl; cperl-indent-level:4 tab-width: 8; indent-tabs-mode: nil -*- +# -*- coding: utf-8 -*- + +use strict; use warnings; +use v5.26; + +use List::Util qw(product); +use Scalar::Util qw(looks_like_number); + +my @n = grep {looks_like_number $_ and $_ > 0} @ARGV; + +warn "some value ignored." if scalar @ARGV != scalar @n; + +my $p = product @n; + +say "[", + join( ",", + map { $p / $_ } @n ), + "]"; diff --git a/challenge-088/jeongoon/perl/ch-2.pl b/challenge-088/jeongoon/perl/ch-2.pl new file mode 100644 index 0000000000..d8c3510b2f --- /dev/null +++ b/challenge-088/jeongoon/perl/ch-2.pl @@ -0,0 +1,74 @@ +#!/usr/bin/env perl +# -*- Mode: cperl; cperl-indent-level:4 tab-width: 8; indent-tabs-mode: nil -*- +# -*- coding: utf-8 -*- + +# tested with: +# echo "[a b c e f][g h i j k ][l m n o p][q r s t u]" | perl ch-2.pl + +use strict; use warnings; +use v5.26; + +++$|; + +sub readMatrixFromStdin () { + my @matrix = (); + while (<STDIN>) { + push @matrix, map { s/\[//g; + [ split /\s+/ ] } ( grep { !/^$/ } + split "\n", + join "\n", + split /\]/ ); + } + + @matrix +} + +# translated from ch-2.go +sub getSpiralArrayFromMatrixRef ($) { + my @mat = @{$_[0]}; # copy + + my $num_rows = scalar @mat; + my $num_cols = scalar @{$mat[0]}; + + my @spiral_array; + for ( my $o = 0; $num_rows > 0 && $num_cols > 0; ++$o ) { + my ($row_end, $col_end) = map { $o + $_ -1 } $num_rows, $num_cols; + + # north + push @spiral_array, @{$mat[$o]}[$o .. $col_end]; + # east + if ( $num_rows > 1 ) { + push @spiral_array, + map { $_->[$col_end] } @mat[ $o + 1 .. $row_end ]; + # south + if ( $num_cols > 1 ) { + push @spiral_array, + @{$mat[$row_end]}[ reverse $o .. ($col_end -1) ]; + # west + if ( $num_rows > 2 ) { + push @spiral_array, + map { $_->[$o] } reverse @mat[ $o + 1 .. $row_end - 1 ]; + } + } + } + # go inner matrix + $num_rows -= 2; + $num_cols -= 2; + } + + @spiral_array +} + + +my @matrix = readMatrixFromStdin; +say STDERR "given matrix:"; +say STDERR "[@$_]" for @matrix; +say STDERR "\n"; + +#my $c = 0; +#say "@{[$c++]}: @$_" for @matrix; + +say "[", + ( join " ", + getSpiralArrayFromMatrixRef( \@matrix ) ), + "]"; diff --git a/challenge-088/jeongoon/raku/ch-1.raku b/challenge-088/jeongoon/raku/ch-1.raku new file mode 100644 index 0000000000..a308637c3f --- /dev/null +++ b/challenge-088/jeongoon/raku/ch-1.raku @@ -0,0 +1,15 @@ +#!/usr/bin/env raku +# -*- Mode: Raku; indent-tabs-mode: nil; coding: utf-8 -*- +# vim: set et ts=4 sw=4: + +# tested with: +# raku jeongoon/ch-1.raku 5 2 1 4 3 +# raku jeongoon/ch-1.raku 2 1 4 3 +# raku jeongoon/ch-1.raku 100 + +multi sub MAIN (*@postive-integer where { @postive-integer.all ~~ Int + and @postive-integer.all > 0 + and @postive-integer.elems > 0 } ) { + my \t = [*] @postive-integer; + @postive-integer.map(t/*).say; +} diff --git a/challenge-088/jeongoon/raku/ch-2.raku b/challenge-088/jeongoon/raku/ch-2.raku new file mode 100644 index 0000000000..d0b6626728 --- /dev/null +++ b/challenge-088/jeongoon/raku/ch-2.raku @@ -0,0 +1,75 @@ +#!/usr/bin/env raku +# -*- Mode: Raku; indent-tabs-mode: nil; coding: utf-8 -*- +# vim: set et ts=4 sw=4: + +use v6.d; + +sub USAGE { + say q:to{__USAGE__}; +Usage: + echo -e "[a b c][d e f][g h i]" | raku ch-2.raku + or input ending with EOF (Ctrl-D or Ctrl-Z) + (you might need to filter the STDERR to get only answer) +__USAGE__ +} + +unit sub MAIN; + +$*ERR.say("Input: (Ctrl-D or Ctrl-Z to finish to input.)"); +my @matrix = do with my @lines = $*IN.lines { + @lines = @lines. + split(/"]" \s* "\n"* | "\n"/). # split rows by newline or `]' + map( -> $ln { next if $ln eq ""; + (S:g/ ^\s+ || '[' || \s+$ // with $ln). + split(/\s+/).Array } ); + + if @lines[0] ~~ Array and @lines[0][0] ne "" { + @lines + } else { + < 1 2 3 4>, + < 5 6 7 8>, + < 9 10 11 12>, + <13 14 15 16> # example 2 + } +} + +# confirm user input +my $ww = @matrix>>.List.flat.max(*.chars).chars; + +$*ERR.say( "given matrix: " ); +$*ERR.say( .map({sprintf("%*s", $ww, $_)}).Array ) for @matrix; +$*ERR.say; + +sub peel-off( @a ) { + my ( $re, $ce ) = @a.end, @a[0].end; + + my @inside = @a[ 1 .. $re.pred; 1 .. $ce.pred ] // Empty; + my @outside = @a[ 0; * ]; # outside of top + + for ( [ 1 .. $re; $ce ], # outside of right + [ $re; $ce.pred, + $ce.pred. + pred ... 0 ], # outside of bottom + [ $re.pred, + $re.pred. + pred ... 1; 0 ] ) # outside of left + -> ( $rr, $cr ) { + last unless all( $rr.elems.so, $cr.elems.so ); # out of range + @outside.append: @a[$rr[*]; $cr[*]]; + } + + @inside, @outside +} + +my @spiral; +my @mat = @matrix.clone; + +my ( $in, $out ); +repeat { + ( $in, $out ) = peel-off( @mat ); + @spiral.append: |$out; + @mat = |$in; + +} while ( @mat[0] andthen { .elems > 0} ); + +@spiral.say; |
