aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMyoungjin JEON <jeongoon@gmail.com>2020-08-15 23:10:08 +1000
committerMyoungjin JEON <jeongoon@gmail.com>2020-08-15 23:10:08 +1000
commitfae6d34a11eeb75a7a8ffeca68ea7b6c8e682c52 (patch)
tree9415523bf4b6649994e9a18eb63b1352103d04c8
parent82d56a626e16b0a7dceeba973b3c69e14031d7f9 (diff)
downloadperlweeklychallenge-club-fae6d34a11eeb75a7a8ffeca68ea7b6c8e682c52.tar.gz
perlweeklychallenge-club-fae6d34a11eeb75a7a8ffeca68ea7b6c8e682c52.tar.bz2
perlweeklychallenge-club-fae6d34a11eeb75a7a8ffeca68ea7b6c8e682c52.zip
[ch-073/jeongoon] All done.
-rw-r--r--challenge-073/jeongoon/.gitignore3
-rw-r--r--challenge-073/jeongoon/common-lisp/ch-1.lsp118
-rw-r--r--challenge-073/jeongoon/common-lisp/ch-2.lsp75
-rw-r--r--challenge-073/jeongoon/haskell/JRandomList.hs49
-rw-r--r--challenge-073/jeongoon/haskell/ch-1.hs144
-rw-r--r--challenge-073/jeongoon/haskell/ch-2.hs53
-rw-r--r--challenge-073/jeongoon/perl/ch-1.pl175
-rw-r--r--challenge-073/jeongoon/perl/ch-2.pl49
-rw-r--r--challenge-073/jeongoon/raku/ch-1.raku91
-rw-r--r--challenge-073/jeongoon/raku/ch-2.raku32
10 files changed, 789 insertions, 0 deletions
diff --git a/challenge-073/jeongoon/.gitignore b/challenge-073/jeongoon/.gitignore
new file mode 100644
index 0000000000..a109a701fc
--- /dev/null
+++ b/challenge-073/jeongoon/.gitignore
@@ -0,0 +1,3 @@
+ch-1
+ch-2
+*~
diff --git a/challenge-073/jeongoon/common-lisp/ch-1.lsp b/challenge-073/jeongoon/common-lisp/ch-1.lsp
new file mode 100644
index 0000000000..bd1c624095
--- /dev/null
+++ b/challenge-073/jeongoon/common-lisp/ch-1.lsp
@@ -0,0 +1,118 @@
+;; Ref:
+;; http://cl-cookbook.sourceforge.net/loop.html
+;; http://clhs.lisp.se/Body/f_mk_ar.htm
+;; https://stackoverflow.com/questions/3950601/swapping-elements-in-a-common-lisp-list
+;; http://clhs.lisp.se/Body/v_rnd_st.htm#STrandom-stateST
+;; https://stackoverflow.com/questions/13359025/adding-to-the-end-of-list-in-lisp
+
+;; I've done with array not list -- which seems wrong choice...
+
+;; tested with
+;; sbcl --script ch-1.lsp <number>
+
+(defun get-command-line () ;; from #072
+ (or
+ #+CLISP *args*
+ #+SBCL *posix-argv*
+ #+LISPWORKS system:*line-arguments-list*
+ #+CMU extensions:*command-line-words*
+ nil))
+
+(defun get-random-pairs (n)
+ (let ((*random-state* (make-random-state t)))
+ (loop for cnt from 1 to n
+ collect (list (random n) (random n)))))
+
+(defun make-range (minv maxv &optional (step 1)) ;; from #072
+ (when (<= minv maxv)
+ (cons minv (make-range (+ minv step) maxv step))))
+
+(defun make-vector-range (min max &optional (step 1))
+ (let* ((range (make-range min max step))
+ (size (length range)))
+ (make-array (list size) :initial-contents range)))
+
+;; not used here
+(defun minimum-in-vector (arr &optional (i 0))
+ (let ((j (+ i 1)))
+ (if (= (length arr) j)
+ (aref arr i)
+ ;; else
+ (when (> (length arr) j)
+ (min (aref arr i) (minimum-in-vector arr j))))))
+
+(defun shuffle-array-by-swapping (arr)
+ (let* ((size (length arr))
+ (shuffle-pairs (get-random-pairs size)))
+ (loop for pair in shuffle-pairs
+ do (let ((le (first pair)) (ri (second pair)))
+ (when (not (and (null le) (null ri)))
+ ;; rotatef: change in place ; I think *f means put in pyhsical memory
+ (rotatef (aref arr le) (aref arr ri)))))))
+
+;; tranlated from groupMinimumList in perl/ch-1.pl
+(defun group-minimum-list (arr group-size)
+ (let* ((total-size (length arr))
+ (min-val nil)
+ (idx-init (- 1 group-size))
+ (idx-max (- total-size group-size))
+ (idx-memo -1)
+ (result ()))
+
+ (loop for b from 0 below total-size ;; b:index for value to be checked
+ ;; or last index in the gorup
+ do (let* ((idx (+ idx-init b)) ;; idx: first index in the group
+ (idx-memo-inboundp (> idx-memo idx))
+ (group-inboundp (and (<= 0 idx) (<= idx idx-max)))
+ (cur-val (aref arr b)))
+
+ (if (and group-inboundp (not idx-memo-inboundp))
+ ;; compare everything in the group
+ (progn
+ (setq idx-memo idx) ;; restart from first index in the grp
+ (setq min-val (aref arr idx))
+ (loop for d from 1 below group-size
+ do(let* ((j (+ idx d))
+ (cur-val (aref arr j)))
+ (when (>= min-val cur-val)
+ (setq idx-memo j)
+ (setq min-val cur-val)))))
+ ;; else
+ (when (or (null min-val) (<= cur-val min-val))
+ (setq min-val cur-val)
+ (setq idx-memo b)) ;; *real index* in the list not idx
+ )
+
+ (when group-inboundp
+ (if (null result)
+ (setq result (list min-val))
+ (nconc result (list min-val))))))
+ result ))
+
+(defparameter *cmdline* (get-command-line))
+
+(defun print-usage ()
+ (format t "Usage: sbcl --script ch-1.lsp <sliding-size>" (car *cmdline*)))
+
+(when (not (= (length *cmdline*) 2))
+ (format t "Wrong Number of arguments: expected 1: but got: ~d~%" (- (length *cmdline*) 1))
+ (print-usage)
+ (quit))
+
+;; *slide-size*
+(defparameter *slide-size* (parse-integer (second *cmdline*)))
+
+(when (< *slide-size* 3)
+ (format t "Too short slide size: ~d: using 3~%" *slide-size*)
+ (setq *slide-size* 3))
+
+;; *frame-size* ; which is 3 times larger than slide at least
+(defparameter *frame-size* (* 10 (round (* 0.3 *slide-size*) 1)))
+
+(format t "Frame Size: ~d~%Slide Size: ~d~%" *frame-size* *slide-size*)
+
+(defparameter *example* (make-vector-range 0 (- *frame-size* 1)))
+(shuffle-array-by-swapping *example*)
+(format t "Input: ~S~%" *example*) ;; used array not list :-/
+(defvar result (group-minimum-list *example* *slide-size*))
+(format t "Output: ~S~%" result)
diff --git a/challenge-073/jeongoon/common-lisp/ch-2.lsp b/challenge-073/jeongoon/common-lisp/ch-2.lsp
new file mode 100644
index 0000000000..d4e0fb06f8
--- /dev/null
+++ b/challenge-073/jeongoon/common-lisp/ch-2.lsp
@@ -0,0 +1,75 @@
+;; Ref:
+
+;; tested with
+;; sbcl --script ch-2.lsp <number>
+
+(defun get-command-line () ;; from #072
+ (or
+ #+CLISP *args*
+ #+SBCL *posix-argv*
+ #+LISPWORKS system:*line-arguments-list*
+ #+CMU extensions:*command-line-words*
+ nil))
+
+(defun get-random-pairs (n)
+ (let ((*random-state* (make-random-state t)))
+ (loop for cnt from 1 to n
+ collect (list (random n) (random n)))))
+
+(defun make-range (minv maxv &optional (step 1)) ;; from #072
+ (when (<= minv maxv)
+ (cons minv (make-range (+ minv step) maxv step))))
+
+(defun make-vector-range (min max &optional (step 1))
+ (let* ((range (make-range min max step))
+ (size (length range)))
+ (make-array (list size) :initial-contents range)))
+
+(defun shuffle-array-by-swapping (arr)
+ (let* ((size (length arr))
+ (shuffle-pairs (get-random-pairs size)))
+ (loop for pair in shuffle-pairs
+ do (let ((le (first pair)) (ri (second pair)))
+ (when (not (and (null le) (null ri)))
+ ;; rotatef: change in place ; I think *f means put in pyhsical memory
+ (rotatef (aref arr le) (aref arr ri)))))))
+
+;; tranlated from groupMinimumList in perl/ch-1.pl
+(defun smallest-or-zero-list (arr)
+ (let* ((size (length arr))
+ (smallest))
+
+ (loop for i from 0 below size
+ collect
+ (let ((cur-val (aref arr i)))
+ (if (null smallest)
+ (progn (setq smallest cur-val) 0)
+ ;; else
+ (if (< cur-val smallest)
+ (progn (setq smallest cur-val) 0) smallest ))))))
+
+(defparameter *cmdline* (get-command-line))
+
+(defun print-usage ()
+ (format t "Usage: sbcl --script ch-1.lsp <list-size>" (car *cmdline*)))
+
+(when (not (= (length *cmdline*) 2))
+ (format t "Wrong Number of arguments: expected 1: but got: ~d~%" (- (length *cmdline*) 1))
+ (print-usage)
+ (quit))
+
+;; *size*
+(defparameter *size* (parse-integer (second *cmdline*)))
+
+(when (< *size* 5)
+ (format t "Too short slide size: ~d: using 5~%" *size*)
+ (setq *size* 5))
+
+(format t "Size: ~d~%" *size*)
+
+(defparameter *example* (make-vector-range *size* (- (* 2 *size*) 1)))
+(shuffle-array-by-swapping *example*)
+(format t "Input: ~S~%" *example*)
+(defvar result (smallest-or-zero-list *example*))
+(format t "Output: ~S~%" result)
+
diff --git a/challenge-073/jeongoon/haskell/JRandomList.hs b/challenge-073/jeongoon/haskell/JRandomList.hs
new file mode 100644
index 0000000000..685e05a840
--- /dev/null
+++ b/challenge-073/jeongoon/haskell/JRandomList.hs
@@ -0,0 +1,49 @@
+module JRandomList
+ ( shuffleByPickingAll,
+ ) where
+
+import Data.List ( unfoldr, splitAt, tails )
+import System.Random ( randomR, Random, StdGen )
+import System.Environment (getArgs)
+
+
+{- Ref:
+https://www.schoolofhaskell.com/school/starting-with-haskell/libraries-and-frameworks/randoms
+https://hackage.haskell.org/package/containers-0.6.3.1/docs/Data-Sequence.html
+https://stackoverflow.com/questions/9834433/convert-data-sequence-to-a-list
+https://hackage.haskell.org/package/base-4.12.0.0/docs/Data-List.html
+https://en.wikibooks.org/wiki/Haskell/Libraries/Random
+https://hackage.haskell.org/package/optparse-generic-1.2.3/docs/Options-Generic.html
+-}
+
+descendingRandomR :: (Integral a, Ord a, Random a) =>
+ ((a, a), StdGen) -> Maybe (a, ((a, a), StdGen))
+descendingRandomR ((lo, hi), g) =
+ let (rv, g') = randomR (lo, hi) g -- rv: random value from seed(g)
+ hi' = hi - 1
+ in if lo > hi then Nothing else Just (rv, ((lo, hi'), g'))
+
+indicesToPick :: (Integral a, Random a) =>
+ a -> StdGen -> [a] -- input: <highest value> <seed>
+indicesToPick = (curry.curry $ unfoldr descendingRandomR) 0 -- 0: first index
+
+popAt :: Int -> [a] -> (Maybe a, [a])
+popAt = curry $ (\(le, ri) ->
+ ( if null ri then Nothing else Just (head ri),
+ le ++ tail ri ) ) . (uncurry splitAt)
+
+poping :: ([a], [Int]) -> Maybe (a, ([a], [Int]))
+poping ([], _) = Nothing
+poping (_, []) = Nothing
+poping (ls, idcs) =
+ let (e, ls') = popAt (head idcs) ls
+ idcs' = tail idcs
+ in case e of
+ Nothing -> poping (ls', idcs') -- skip the index which is out of range
+ Just e' -> Just (e', (ls', idcs'))
+
+shuffleByPickingAll :: [a] -> StdGen -> [a]
+shuffleByPickingAll ls seed = pick (ls, ( indicesToPick maxIdx seed ))
+ where
+ pick = unfoldr poping
+ maxIdx = ( length ls ) - 1
diff --git a/challenge-073/jeongoon/haskell/ch-1.hs b/challenge-073/jeongoon/haskell/ch-1.hs
new file mode 100644
index 0000000000..79ff1f2312
--- /dev/null
+++ b/challenge-073/jeongoon/haskell/ch-1.hs
@@ -0,0 +1,144 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE OverloadedStrings #-}
+import Options.Generic
+import JRandomList
+import System.Random ( StdGen, newStdGen )
+import Data.Maybe
+
+{- Tested with:
+runhaskell -i. ch-1.hs 3
+-}
+
+aSample :: (Integral a, Num a) =>
+ a -> StdGen -> [Int]
+aSample winSize seed =
+ -- size 3 -> frameSize: 10
+ let frameSize = 10 * round( 0.3 * fromIntegral winSize )
+ in shuffleByPickingAll [ 0 .. (pred frameSize {-index-}) ] seed
+
+validateSizeIO :: (Ord a, Show a) => a -> a -> IO a
+validateSizeIO def given = do
+ if given < def then
+ putStrLn ( "Given size is too short: " ++ (show given)
+ ++ ": using default size: " ++ (show def) )
+ >> return def
+ else putStrLn( "Given Size:" ++ (show given) )
+ >> return given
+
+groupMinimumListSimple_ :: (Ord a) => [a] -> [a] -> Int -> [a]
+groupMinimumListSimple_ acc ls s
+ | length sld /= s = acc
+ | otherwise = groupMinimumListSimple_ acc' ls' s where
+ sld = take s ls
+ ls' = tail ls
+ acc' = acc ++ [ minimum sld ]
+
+groupMinimumListSimple = groupMinimumListSimple_ []
+
+someMinValuesWithIndics' :: ( Ord a, Enum a )
+ => a -> Maybe (([a], [Int]), Int) -> Maybe (([a], [Int]), Int)
+-- set default offset value if nothign specified : not used here
+--minValuesWithIndics' x Nothing = minValuesWithIndics' x (Just (([x], [0]), 1))
+someMinValuesWithIndics' x (Just ((min@(m:ms), idx), i))
+ | x < m = Just((x:min, i:idx), pred i)
+ -- prepend the new minimum value
+ | otherwise = Just((min, idx), pred i)
+ -- keep record, change index number only
+
+someMinValuesWithIndics ls offset =
+ let i = (length ls) -1 +offset
+ res = foldr someMinValuesWithIndics' (Just(([last ls], [i]), pred i)) (init ls)
+ in fst( fromJust( res ) )
+
+-- bascially same method which is described in ch-1.pl
+
+groupMinimumList_ :: (Ord a, Enum a) =>
+ ( Maybe( [a], Int, [a], [Int] ), [a] ) -> Int -> [a]
+
+-- first step
+groupMinimumList_ (Nothing, ls) s =
+ let x = head ls
+ a' = 2 - s in -- 2nd number of a (when a == 0 we get full size of group)
+ if 0 <= a'
+ then groupMinimumList_ (Just([x], a', [x], [0]), ls) s
+ else groupMinimumList_ (Just([], a', [x], [0]), ls) s
+-- edge case (no more elements)
+groupMinimumList_ (Just( acc, _, _, _ ), []) _ = acc
+groupMinimumList_ (Just( acc, a, min, mem ), ls) s =
+ let b = a + s -1 -- index for beging checked
+ -- or last index in the group when inbound
+ a' = succ a
+ n = head min; m = head mem
+ ns = tail min; ms = tail mem
+ grp = take s $ drop (if a < 0 then 0 else a) ls
+ x = ls !! b
+ lsize = length ls
+ memInbound = (not (null mem)) && a <= m
+ grpInbound = ( 0 <= a && b < lsize ) in
+
+ if b >= lsize then acc -- edge case
+ else if (not grpInbound) || (grpInbound && memInbound) then
+ let acc' q = if grpInbound then acc ++ [q] else acc
+ min' = if grpInbound then [] else min
+ mem' = if grpInbound then [] else mem
+ in
+ case ( x `compare` n ) of
+ LT -> -- new minimum
+ groupMinimumList_ (Just(acc' x, a', x:min, b:mem), ls) s
+ EQ -> -- better update index only
+ groupMinimumList_ (Just( (acc' n), a', min, b:ms), ls) s
+ GT -> {- just skipping : too complicate recalculate memos
+ better compare evertying in the goup -}
+ groupMinimumList_ (Just( (acc' n), a', min', mem'), ls) s
+
+ else -- grpInbound && not memInbound
+ -- memorised value at leftmost not useful anymore
+ if (not (null mem) ) then -- but maybe we can use next available memo
+ groupMinimumList_ (Just(acc, a, ns, ms), ls) s
+ else -- compare everthing in the group
+ -- meanwhile making memo as well
+ let res = someMinValuesWithIndics grp a -- a: first index in the group
+ min' = fst res
+ mem' = snd res
+ acc' = acc ++ [ head min' ] in
+ groupMinimumList_ (Just(acc', a', min', mem'), ls) s
+
+groupMinimumList :: (Ord a, Enum a) => [a] -> Int -> [a]
+groupMinimumList = curry groupMinimumList_ Nothing
+
+main :: IO ()
+main = do
+ args <- getRecord "Challenge #073 - Task #1"
+ let defS = 3
+ sStr = show ( args :: Int )
+ s = read sStr :: Int
+ getSize = validateSizeIO defS s in
+ do
+ size <- getSize;
+ seed <- newStdGen;
+ let ex = aSample size seed in do
+ putStr "Example\nInput: "
+ print $ ex
+ putStr "Output 1: "
+ print $ groupMinimumListSimple ex size
+ putStr "Output 2: "
+ print $ groupMinimumList ex size
+
+{-
+Task #1 Min Sliding Window
+You are given an array of integers @A and sliding window size $S.
+Write a script to create an array of min from each sliding window.
+
+Example
+Input: @A = (1, 5, 0, 2, 9, 3, 7, 6, 4, 8) and $S = 3
+Output: (0, 0, 0, 2, 3, 3, 4, 4)
+
+[(1 5 0) 2 9 3 7 6 4 8] = Min (0)
+[1 (5 0 2) 9 3 7 6 4 8] = Min (0)
+[1 5 (0 2 9) 3 7 6 4 8] = Min (0)
+[1 5 0 (2 9 3) 7 6 4 8] = Min (2)
+[1 5 0 2 (9 3 7) 6 4 8] = Min (3)
+[1 5 0 2 9 (3 7 6) 4 8] = Min (3)
+[1 5 0 2 9 3 (7 6 4) 8] = Min (4)
+[1 5 0 2 9 3 7 (6 4 8)] = Min (4)
+-}
diff --git a/challenge-073/jeongoon/haskell/ch-2.hs b/challenge-073/jeongoon/haskell/ch-2.hs
new file mode 100644
index 0000000000..2899246fdd
--- /dev/null
+++ b/challenge-073/jeongoon/haskell/ch-2.hs
@@ -0,0 +1,53 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE OverloadedStrings #-}
+import Options.Generic
+import JRandomList
+import System.Random ( StdGen, newStdGen )
+import Data.Maybe
+import Data.List( unfoldr )
+
+{- Tested with:
+runhaskell -i. ch-2.hs 3
+-}
+
+aSample :: (Integral a, Num a, Enum a) =>
+ a -> StdGen -> [Int]
+-- skip small number an making an example: otherwise result is too boring
+aSample size seed =
+ let s' = fromIntegral size in
+ shuffleByPickingAll [ s' .. (pred (2*s') {-index-}) ] seed
+
+validateSizeIO :: (Ord a, Show a) => a -> a -> IO a
+validateSizeIO def given = do
+ if given < def then
+ putStrLn ( "Given size is too short: " ++ (show given)
+ ++ ": using default size: " ++ (show def) )
+ >> return def
+ else putStrLn( "Given Size:" ++ (show given) )
+ >> return given
+
+generateSmallest :: ( Integral a, Ord a )
+ => ( Maybe a, [a] ) -> Maybe ( a, ( Maybe a, [a] ) )
+generateSmallest ( _, [] ) = Nothing
+generateSmallest ( Nothing, ls@(c:ls') ) = Just( 0, ( Just c, ls' ))
+generateSmallest ( Just s, ls@(c:ls') ) =
+ if c <= s then Just( 0, ( Just c, ls' )) -- couldn't find smallest on the left
+ else Just( s, ( Just s, ls' ))
+
+processSmallest = curry (unfoldr generateSmallest) Nothing
+
+main :: IO ()
+main = do
+ args <- getRecord "Challenge #073 - Task #2"
+ let defS = 3
+ sStr = show ( args :: Int )
+ s = read sStr :: Int
+ getSize = validateSizeIO defS s in
+ do
+ size <- getSize;
+ seed <- newStdGen;
+ let ex = aSample size seed in do
+ putStr "Input: "
+ print $ ex
+ putStr "Output: "
+ print $ processSmallest ex
diff --git a/challenge-073/jeongoon/perl/ch-1.pl b/challenge-073/jeongoon/perl/ch-1.pl
new file mode 100644
index 0000000000..b712c07e3e
--- /dev/null
+++ b/challenge-073/jeongoon/perl/ch-1.pl
@@ -0,0 +1,175 @@
+#!/usr/bin/env perl
+# -*- Mode: cperl; cperl-indent-level:4 tab-width: 8; indent-tabs-mode: nil -*-
+# -*- coding: utf-8 -*-
+
+use strict; use warnings;
+
+BEGIN {
+ $::debugging = 0;
+ @ARGV = map {
+ my $d = /^--debug$/;
+ $d && ++$::debugging;
+ $d ? () : $_;
+ } @ARGV;
+
+ our $dprint = sub( @ ) {
+ ++$|;
+ print "[DBG] ",@_;
+ };
+ *::dprint = $::debugging ? $dprint : sub (@) {};
+}
+
+sub unsort ( @ ) { sort { (-1,1)[(rand 1)+0.46] } @_ }
+
+sub groupMinimumList ( @ ) { # $size, @_
+ my $s = shift;
+ # let's memorise the position(index) when we find the mimum value
+ # if previous minimum position is gone,
+ # A compare everything in the group
+ # 1. memo the position, 2. push the value into result
+ # else e.g. if found
+ # B compare only between two values
+ # 1. memo the position, 2. push the value into result
+ my $min = undef;
+ my $i = -$s +1; # index when whole sliding door is ready
+ my $imax = scalar @_ -$s; # same as $#_ -$s +1
+ my $memo = -1;
+
+ map {
+ my $memo_inbound = $memo > $i;
+ my $door_inbound = 0 <= $i && $i <= $imax;
+
+ if ( $door_inbound && ! $memo_inbound ) {
+ # compare everything in sliding door (A)
+ # XXX: no seprate function for debugging purpose
+ $min = $_[ $memo = $i ];
+ ::dprint "(A) $i: min $min at $memo\n";
+ for my $d ( 1 .. $s -1 ) {
+ if ( $min >= $_[$i+$d] ) { $min = $_[ ($memo = $i+$d) ] }
+ ::dprint "(A) $i: min $min at $memo\n";
+ }
+ }
+ else {
+ if ( ! defined $min || $min >= $_ ) {
+ # keep comparing between two .. (B)
+ $min = $_;
+ $memo = $i + ($s -1); # memorise the *real* index in array
+ ::dprint "(B) $i: min $min at $memo\n";
+ }
+ else {
+ ::dprint "(B) $i: min $min at $memo (no need to compare at all)\n";
+ }
+ }
+ ++$i;
+ $door_inbound ? $min : ();
+ } @_;
+}
+
+sub groupMinimumListComplex ( @ ) { # $size, @_
+ my $s = shift;
+
+ my @min = (); # using array
+ my @memo = (); # ditto
+
+ my $i = -$s +1;
+ my $imax = scalar @_ -$s;
+
+ # in this case we are comparing numbrers but. what if comparing
+ # more complex object and comparing process is not very delightful?
+
+ map {
+ isEvil:
+ my $memo_inbound = scalar @memo && $memo[0] > $i;
+ my $door_inbound = 0 <= $i && $i <= $imax;
+
+ if ( $door_inbound && ! $memo_inbound ) {
+ # compare everything in sliding door (A)
+ # Experiment:
+ # but what if we have another minimum value memorised
+ # in bound of the group (because we just disgard one element)
+ if ( scalar @memo ) {
+ shift @memo; shift @min;
+ if ( scalar @memo ) {
+ ::dprint "(B?) Found another minimum value in bound.\n";
+ goto isEvil;
+ }
+ }
+
+ # compare everything in group again
+ @memo = ( $i );
+ @min = ( $_[ $i ] );
+ ::dprint "(A0) $i: min $min[0] at $memo[0]\n";
+
+ for my $d ( 1 .. $s -1 ) {
+ my $k = $i+$d;
+ if ( $min[0] >= $_[$k] ) { # new value is minimum and
+ if ( $memo[0] > $k ) { # located in left hand side
+ unshift @min, $_[$k];
+ unshift @memo, $k;
+ ::dprint "(A+) $i: min $min[0] at $memo[0]\n";
+ }
+ else { # or just forget it. :(
+ @memo = ( $k );
+ @min = ( $_[ $k ] );
+ ::dprint "(A=) $i: min $min[0] at $memo[0]\n";
+ }
+ }
+ }
+ }
+ else {
+ if ( scalar @min == 0 || $min[0] >= $_ ) {
+ # keep comparing between two .. (B)
+ if ( scalar @min && $memo[0] > $i ) {
+ unshift @min, $_;
+ unshift @memo, $i + ($s -1); # memorise the *real* index in array
+ ::dprint "(B+) $i: min $min[0] at $memo[0]\n";
+ }
+ else {
+ @min = ( $_ );
+ @memo = ( $i + ($s -1) );
+ ::dprint "(B=) $i: min $min[0] at $memo[0]\n";
+ }
+ }
+ else {
+ ::dprint "(B) $i: min $min[0] at $memo[0] (no need to compare at all)\n";
+ # XXX: don't change anything
+ # because minimum value was not at leftmost
+ # we can check again in next loop
+ }
+ }
+ ++$i;
+ $door_inbound ? $min[0] : ();
+ } @_;
+}
+
+sub map_ssprintf { map { sprintf "%#$_[0]s", $_ } @_[1..$#_] }
+
+package main;
+
+my $S = shift;
+
+(defined $S and $S > 2) or warn "Invalid sliding door size: USING ",$S = 3," !!";
+my $FS = 10*int( .3* $S +.5 ); # reasonable value for (F)rame(S)ize
+my @A = unsort 0.. $FS-1; # simply using max number from frame size
+
+::dprint "Default My solution: \n";
+my @M = groupMinimumList $S, @A;
+::dprint "Another one: \n";
+my @E = groupMinimumListComplex $S, @A;
+
+$" = ' ';
+my $W = length( $FS-1 ); # for sprintf
+
+print "\$S = $S |-> \$FS = $FS\n";
+print "\@A = (${\"}@{[map_ssprintf($W, @A)]}${\"})\n";
+
+my $diff = scalar @A - scalar @M;
+my @G = ( " " ) x $diff;
+my $gh = int .5 * (scalar @G);
+my @adj = ( $diff % 2 ) ? ( $", '' ) : ( '', $" );
+
+print "\@M = ( $adj[0]".
+ "@{[map_ssprintf($W,@G[0..$gh-1],@M,@G[$gh..$#G])]}$adj[1])\n";
+print "\@E = ( $adj[0]".
+ "@{[map_ssprintf($W,@G[0..$gh-1],@E,@G[$gh..$#G])]}$adj[1])\n";
+print "Complex Method Failed\n" unless "@M" eq "@E";
diff --git a/challenge-073/jeongoon/perl/ch-2.pl b/challenge-073/jeongoon/perl/ch-2.pl
new file mode 100644
index 0000000000..0797cde8ee
--- /dev/null
+++ b/challenge-073/jeongoon/perl/ch-2.pl
@@ -0,0 +1,49 @@
+#!/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 boolean qw(:all);
+
+sub unsort ( @ ) { sort { (-1,1)[(rand 1)+0.46] } @_; }
+sub map_ssprintf { map { sprintf "%#$_[0]d", $_ } @_[1..$#_]; }
+
+sub gen_smallest_( $$ ) {
+ my ( $s, $c ) = @_; # (s)mallest (c)urrent
+ # return true if we couldn't find the smallest
+ # because we found new one
+ # return false if we couldn't find the smallest
+ # return current smallest if we find the one
+ if ( isBoolean( $s ) || $s > $c ) {
+ true # 0 && new smallest
+ }
+ else {
+ ( $s < $c ) ? $s # smallest && keep smallest
+ : false # 0 && keep smallest
+ }
+}
+
+sub processSmallest ( @ ) {
+ my $smallest = boolean( not 'given' );
+ map {
+ my $current_is_smallest_or_just = gen_smallest_ $smallest, $_;
+ isTrue( $current_is_smallest_or_just ) and $smallest = $_;
+ isBoolean( $current_is_smallest_or_just ) ? 0 : $smallest;
+ } @_;
+}
+
+package main;
+
+my $S = shift;
+
+( defined $S and $S > 4 )
+ or warn "Size not given: USING ",$S = 9," !!";
+
+$" = ' ';
+my ( @A, @S );
+my $W = length( 2*$S-1 ); # for sprintf
+
+@S = processSmallest ( @A = unsort $S.. 2*$S-1 );
+
+print "\@A = (${\"}@{[map_ssprintf($W, @A)]}${\"})\n";
+print "\@S = (${\"}@{[map_ssprintf($W, @S)]}${\"})\n";
diff --git a/challenge-073/jeongoon/raku/ch-1.raku b/challenge-073/jeongoon/raku/ch-1.raku
new file mode 100644
index 0000000000..0dde4e1327
--- /dev/null
+++ b/challenge-073/jeongoon/raku/ch-1.raku
@@ -0,0 +1,91 @@
+#!/usr/bin/env raku
+# -*- Mode: Raku; indent-tabs-mode: nil; coding: utf-8 -*-
+# vim: set et ts=4 sw=4:
+
+use v6.d;
+
+class memo { has ( $.idx, $.val ); }
+
+sub caculate-everytime ( :numbers(:@number-list),
+ Int :window-size(:$ssize) where $ssize > 2 ) {
+ @number-list.rotor( $ssize => -($ssize-1) ).map( *.min ).Array;
+}
+
+sub caculate-sometime ( :numbers(:@number-list),
+ Int :window-size(:$ssize) where $ssize > 2 ) {
+
+ my memo @memo = Empty;
+ my $i = -$ssize + 1; # pseudo index: starting from negative value
+
+ @number-list.map(
+ -> $c {
+ my $b = $i + $ssize -1; # last index in the group or to be compared
+ my $mem-inbound = ( @memo.first.?idx andthen * >= $i );
+ my $grp-inbound = 0 <= $i && $b < @number-list.elems;
+
+ if $grp-inbound.not or ( $grp-inbound and $mem-inbound) {
+ given ( @memo.first.?val andthen $c cmp * or Less ) {
+ #say "A:$_";
+ when Less {
+ @memo.unshift( memo.new( :idx($b), :val($c) ) );
+ }
+ when Same { # same but better update index because
+ # if less value located in later,
+ # there less chance to recalculate
+ @memo.first.idx = $b;
+ }
+ when More { # leave memory: maybe too complex to reorder
+ # better recalculate everything again
+ # later
+ }
+ }
+ }
+ else { # grp-inbound && not mem-inbound
+ #say "B:trying memo";
+ # memorised value at leftmost is not useful
+ if @memo.elems { # but maybe we can use next available memo
+ @memo.shift;
+ redo; # without changing map status
+ }
+ else { # no memo: compare evertying in the group
+ #say "B:no memo:compare everything";
+ # first one
+ @memo.push( memo.new( :idx($i), :val( @number-list[$i] )));
+ # and rest
+ for ( $i ^.. $b ) -> $k {
+ if @memo.first.val >= @number-list[$k] { # new value is min.
+ if @memo.first.idx > $k { # and located on the left
+ # save for next next chance
+ @memo.push( memo.new( :idx($k), :val( @number-list[$k] )));
+ }
+ else { # too complicate if we re-arrange memo.
+ # just forget it :-(
+ @memo = memo.new( :idx($k), :val( @number-list[$k ] ));
+ }
+ }
+ }
+ }
+ }
+ #@memo.map( -> $m { print "{$m.val}\@{$m.idx} "; } );
+ #print ": total {@memo.elems}";
+ ++$i;
+ unless $grp-inbound {
+ #say "";
+ next;
+ }
+ #say ">>> {@memo.first.val}";
+ @memo.first.val;
+ } ).Array;
+}
+
+sub MAIN ( Int \S where * > 2 #= sliding window size (>2)
+ ) {
+
+ my \FS = 10 * ( .3 * S + .5 ).floor; # reasonable (F)rame (S)ize
+ my @sample = ( 0 .. FS -1 ).pick( FS );
+ say "Input: {@sample.raku}";
+ say "Correct: " ~ caculate-everytime( :numbers(@sample), :window-size(S) ).raku;
+ say "My Answer: " ~ caculate-sometime( :numbers(@sample), :window-size(S) ).raku;
+
+
+}
diff --git a/challenge-073/jeongoon/raku/ch-2.raku b/challenge-073/jeongoon/raku/ch-2.raku
new file mode 100644
index 0000000000..2e2798a66c
--- /dev/null
+++ b/challenge-073/jeongoon/raku/ch-2.raku
@@ -0,0 +1,32 @@
+#!/usr/bin/env raku
+# -*- Mode: Raku; indent-tabs-mode: nil; coding: utf-8 -*-
+# vim: set et ts=4 sw=4:
+
+use v6.d;
+
+role zero { method raku { "0" } }
+
+sub process-smallest ( @list ) {
+ my $smallest = Nil;
+ @list.map(
+ # always return minimum value (current one inclusive)
+ # but when call with .raku return what Task #2 asks.
+ -> $c {
+ if $smallest.defined.not or $c < $smallest {
+ $smallest = $c;
+ $c but zero
+ } else {
+ $smallest < $c ?? $smallest !! $c but zero
+ }
+ });
+}
+
+sub MAIN ( Int \S where * > 2 #= sliding window size (>2)
+ ) {
+
+ my @sample = ( S .. 2*S -1 ).pick( S );
+ say "Input: {@sample.raku}";
+ my @answer = process-smallest( @sample );
+ say "Output: {@answer.map( *.raku ).map( *.Int ).Array.raku}"
+ #say "Ouput: {@answer.raku}";
+}