aboutsummaryrefslogtreecommitdiff
path: root/challenge-082
diff options
context:
space:
mode:
authorJan Krňávek <Jan.Krnavek@gmail.com>2020-10-18 13:13:27 +0200
committerJan Krňávek <Jan.Krnavek@gmail.com>2020-10-18 13:13:27 +0200
commitf5f5530b5c5e9e70a3059a811f85d03450b5f793 (patch)
tree06c23b708c461be025b825caab54e7798603389a /challenge-082
parentc2d5208ded891b4b9a21753021d96bdde0f90e6b (diff)
parente8d83a10c2044eba1be500684d2caa4577400c85 (diff)
downloadperlweeklychallenge-club-f5f5530b5c5e9e70a3059a811f85d03450b5f793.tar.gz
perlweeklychallenge-club-f5f5530b5c5e9e70a3059a811f85d03450b5f793.tar.bz2
perlweeklychallenge-club-f5f5530b5c5e9e70a3059a811f85d03450b5f793.zip
Merge remote-tracking branch 'upstream/master' into challenge-week-082
Diffstat (limited to 'challenge-082')
-rw-r--r--challenge-082/abigail/blog.txt1
-rw-r--r--challenge-082/abigail/blog1.txt1
-rw-r--r--challenge-082/abigail/perl/ch-2.pl79
-rw-r--r--challenge-082/colin-crain/blog.txt1
-rwxr-xr-xchallenge-082/e-choroba/perl5/ch-1.pl12
-rw-r--r--challenge-082/jeongoon/elm/src/Ch1.elm39
-rw-r--r--challenge-082/jeongoon/elm/src/Ch2.elm5
-rw-r--r--challenge-082/jeongoon/elm/src/Main.elm71
-rw-r--r--challenge-082/jeongoon/go/ch-1.go112
-rw-r--r--challenge-082/jeongoon/go/ch-2.go99
-rw-r--r--challenge-082/jeongoon/haskell/ch-1.hs23
-rw-r--r--challenge-082/jeongoon/haskell/ch-2.hs6
-rw-r--r--challenge-082/jeongoon/perl/ch-1.pl47
-rw-r--r--challenge-082/jeongoon/perl/ch-2.pl169
-rw-r--r--challenge-082/jeongoon/raku/ch-1.raku11
-rw-r--r--challenge-082/jeongoon/raku/ch-2.raku142
-rwxr-xr-xchallenge-082/jluis/perl/ch-1.pl65
-rwxr-xr-xchallenge-082/jluis/perl/ch-2.pl42
-rw-r--r--challenge-082/juliodcs/perl/ch-2.pl37
-rw-r--r--challenge-082/juliodcs/raku/ch-2.raku52
-rw-r--r--challenge-082/lubos-kolouch/perl/ch-2.pl57
-rw-r--r--challenge-082/lubos-kolouch/python/ch-1.py45
-rw-r--r--challenge-082/lubos-kolouch/python/ch-2.py47
-rw-r--r--challenge-082/nunovieira220/js/ch-1.js13
-rw-r--r--challenge-082/nunovieira220/js/ch-2.js38
-rw-r--r--challenge-082/nunovieira220/perl/ch-1.pl18
-rw-r--r--challenge-082/nunovieira220/perl/ch-2.pl39
-rw-r--r--challenge-082/pete-houston/perl/ch-1.pl38
-rw-r--r--challenge-082/pete-houston/perl/ch-2.pl50
-rw-r--r--challenge-082/vinod-k/perl/ch-1.pl32
30 files changed, 1328 insertions, 63 deletions
diff --git a/challenge-082/abigail/blog.txt b/challenge-082/abigail/blog.txt
new file mode 100644
index 0000000000..55b2db8670
--- /dev/null
+++ b/challenge-082/abigail/blog.txt
@@ -0,0 +1 @@
+https://wp.me/pcsEjt-1t
diff --git a/challenge-082/abigail/blog1.txt b/challenge-082/abigail/blog1.txt
new file mode 100644
index 0000000000..5a9e7458c3
--- /dev/null
+++ b/challenge-082/abigail/blog1.txt
@@ -0,0 +1 @@
+https://wp.me/pcsEjt-K
diff --git a/challenge-082/abigail/perl/ch-2.pl b/challenge-082/abigail/perl/ch-2.pl
index 8a176e1e79..821b05b26e 100644
--- a/challenge-082/abigail/perl/ch-2.pl
+++ b/challenge-082/abigail/perl/ch-2.pl
@@ -23,41 +23,56 @@ chomp (my $A = <>);
chomp (my $B = <>);
chomp (my $C = <>);
+#
+# $A, $B, $C are arrays, containing the single characters of
+# the input strings. $ai, $bi, $ci are indices into the arrays
+# (and can be seen as pointers into the strings).
+#
+# Invariants: - $ai + $bi == $ci
+# - @$C [0 .. $ci - 1] is an interleaving of
+# @$A [0 .. $ai - 1] and @$B [0 .. $bi - 1]
+#
sub is_interleaved;
-sub is_interleaved ($A, $B, $C) {
- #
- # If $A or $B is empty, the other should equal $C.
- # This also takes care of the situation where all strings
- # are empty (which means, they are interleaved).
- #
- return $A eq $C if !length $B;
- return $B eq $C if !length $A;
-
- #
- # The length of $C must equal the length of $A plus the
- # length of $B, else $C cannot be an interleaving of $A and $B.
- #
- return unless length ($A) + length ($B) == length ($C);
-
- #
- # Now, let $A = a . A', $B = b . B', $C = c . C', where
- # a, b, and c are the first characters of the strings
- # $A, $B, $C, and A', B', C' the rest of the strings.
- # $C is an interleaving of $A and $B if one of the following
- # statements is true:
- # * a eq c, and C' is an interleaving of A' and $B.
- # * b eq c, and C' is an interleaving of $A and B'.
- #
- # Note that at this point, none of the strings $A, $B or $C are empty.
- #
- my ($a, $A_prime) = $A =~ /^(.)(.*)$/;
- my ($b, $B_prime) = $B =~ /^(.)(.*)$/;
- my ($c, $C_prime) = $C =~ /^(.)(.*)$/;
- return $a eq $c && is_interleaved ($A_prime, $B, $C_prime) ||
- $b eq $c && is_interleaved ($A, $B_prime, $C_prime);
+sub is_interleaved ($A, $B, $C, $ai = 0, $bi = 0, $ci = 0) {
+ state $cache;
+ local $" = "";
+ $$cache [$ai] [$bi] //= do {
+ #
+ # If we have reached the end of either $A or $B,
+ # what is remaining in the other string, must
+ # match the unmatched part in $C.
+ #
+ return "@$A[$ai..$#$A]" eq "@$C[$ci..$#$C]" if $bi == @$B;
+ return "@$B[$bi..$#$B]" eq "@$C[$ci..$#$C]" if $ai == @$A;
+
+ #
+ # Now we can recurse; if the first character of unmatched
+ # part of C matches the first character of the unmatched
+ # part of either A or B, we match the first character of C
+ # and the first character of either A or B, and recurse.
+ # If the first character of the unmatched part of C matches
+ # the first character of unmatched parts of both A and B,
+ # we first recurse first by matching against A, and if this
+ # doesn't provide a match, we recurse by matching against B.
+ #
+
+ return $$A [$ai] eq $$C [$ci] &&
+ is_interleaved ($A, $B, $C, $ai + 1, $bi, $ci + 1) ||
+ $$B [$bi] eq $$C [$ci] &&
+ is_interleaved ($A, $B, $C, $ai, $bi + 1, $ci + 1);
+ }
}
-say is_interleaved ($A, $B, $C) ? 1 : 0;
+#
+# Check lengths; if the length of C isn't equal to the length of A
+# plus the length of B, we cannot have a match. If the lengths check
+# out, recursively check whether the strings are interleafed.
+#
+
+say length ($A) + length ($B) == length ($C) &&
+ is_interleaved ([split // => $A],
+ [split // => $B],
+ [split // => $C]) ? 1 : 0;
__END__
diff --git a/challenge-082/colin-crain/blog.txt b/challenge-082/colin-crain/blog.txt
new file mode 100644
index 0000000000..ac8be5d356
--- /dev/null
+++ b/challenge-082/colin-crain/blog.txt
@@ -0,0 +1 @@
+https://colincrain.wordpress.com/2020/10/16/factor-i-hardly-knew-ye-interwoven-aphorisms-ftw/
diff --git a/challenge-082/e-choroba/perl5/ch-1.pl b/challenge-082/e-choroba/perl5/ch-1.pl
index bac0ff5500..aeea793065 100755
--- a/challenge-082/e-choroba/perl5/ch-1.pl
+++ b/challenge-082/e-choroba/perl5/ch-1.pl
@@ -5,12 +5,14 @@ use strict;
sub common_factors {
my ($m, $n) = @_;
($m, $n) = ($n, $m) if $n < $m;
- my @r;
- for my $i (1 .. $m) {
- push @r, $i if 0 == $m % $i
- && 0 == $n % $i;
+ my (@r, @rev_r);
+ for my $i (1 .. sqrt $m) {
+ if (0 == $m % $i) {
+ push @r, $i if 0 == $n % $i;
+ unshift @rev_r, $m / $i if 0 == $n % ($m / $i);
+ }
}
- return \@r
+ return [@r, @rev_r]
}
use Test::More;
diff --git a/challenge-082/jeongoon/elm/src/Ch1.elm b/challenge-082/jeongoon/elm/src/Ch1.elm
new file mode 100644
index 0000000000..84b6dfdf0f
--- /dev/null
+++ b/challenge-082/jeongoon/elm/src/Ch1.elm
@@ -0,0 +1,39 @@
+module Ch1 exposing ( getCommonFactors )
+
+import String as S
+import List as L
+import Maybe as Mb
+
+getCommonFactors : Int -> Int -> Result String (List Int)
+getCommonFactors m n =
+ if L.all (\x -> x < 0 ) [m, n]
+ then Err "" -- probably initial state or equivalent to.
+ else if L.any(\x -> x < 1) [m, n]
+ then Err "Please input all the strings !!!"
+ else
+ case commonFactors [m, n] of
+ [] -> Err "invalid input"
+ ls -> Ok ls
+
+commonFactors : List Int -> List Int
+commonFactors ils =
+ case ils of
+ [] -> []
+ ls ->
+ let l = L.minimum ls
+ g = L.maximum ls in
+ case Mb.map2 (\a b -> a == b) l g of
+ Nothing -> []
+ Just same ->
+ case l of
+ Nothing -> [] -- impossible but have to
+ Just jl ->
+ if same then
+ -- note: modBy has opposite order of arguments
+ -- when compared to most of other language
+ L.filter (\dv -> modBy dv jl ==0) (L.range 1 jl)
+ else
+ L.filter (\dv ->
+ L.all (\i ->
+ modBy dv i == 0) ls)
+ (L.range 1 jl)
diff --git a/challenge-082/jeongoon/elm/src/Ch2.elm b/challenge-082/jeongoon/elm/src/Ch2.elm
index 85d1cb2de3..5d2f7d7422 100644
--- a/challenge-082/jeongoon/elm/src/Ch2.elm
+++ b/challenge-082/jeongoon/elm/src/Ch2.elm
@@ -1,7 +1,6 @@
-module Ch2 exposing ( .. {-
- checkInterleavedString
+module Ch2 exposing ( checkInterleavedString
, allPossiblePartitions
- , WhichPart-} )
+ , WhichPart )
import String as S
import List as L
diff --git a/challenge-082/jeongoon/elm/src/Main.elm b/challenge-082/jeongoon/elm/src/Main.elm
index 6d1863fcb1..a128fc6e08 100644
--- a/challenge-082/jeongoon/elm/src/Main.elm
+++ b/challenge-082/jeongoon/elm/src/Main.elm
@@ -1,6 +1,7 @@
{- 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
-}
module Main exposing (..)
@@ -14,6 +15,7 @@ import String as S
import List as L
-- Solutions ...
+import Ch1 exposing (..)
import Ch2 exposing (..)
-- Main
@@ -24,28 +26,44 @@ main =
-- Model
type alias Model =
- { ch2StringA : String
+ { ch1IntM : Int
+ , ch1IntN : Int
+ , ch1Result : Result String (List Int)
+ , ch2StringA : String
, ch2StringB : String
, ch2StringC : String
, ch2Result : Result String (List (List String))
}
init : Model
-init = Model "" "" "" (Err "")
+init = Model 0 0 (Err "") "" "" "" (Err "")
-- Update
type Task = Task1 | Task2
-type Msg = {-CommonFactors String | -}
- InterleavedStringFirst String
+type Msg = CommonFactorsM String
+ | CommonFactorsN String
+ | InterleavedStringFirst String
| InterleavedStringSecond String
| InterleavedStringInterleaved String
update : Msg -> Model -> Model
update msg m =
- case msg of
- InterleavedStringFirst nv -> -- new value
+ case msg of -- nv: new value
+ CommonFactorsM nv ->
+ case S.toInt nv of
+ Nothing -> { m | ch1IntM = 0 }
+ Just ni ->
+ let res = Ch1.getCommonFactors ni m.ch1IntN
+ in { m | ch1IntM = ni, ch1Result = res }
+ CommonFactorsN nv ->
+ case S.toInt nv of
+ Nothing -> { m | ch1IntN = 0 }
+ Just ni ->
+ let res = Ch1.getCommonFactors m.ch1IntM ni
+ in { m | ch1IntN = ni, ch1Result = res }
+ InterleavedStringFirst nv ->
let res = Ch2.checkInterleavedString nv m.ch2StringB m.ch2StringC
in { m | ch2StringA = nv, ch2Result = res }
InterleavedStringSecond nv ->
@@ -59,7 +77,11 @@ update msg m =
view : Model -> Html Msg
view m =
div [ style "padding" "20px", style "width" "90%" ]
- [ h1 [] [ text "Task2: Interleave String" ]
+ [ h1 [] [ text "Task1: Common Factors" ]
+ , viewInputInt "text" "$M" m.ch1IntM CommonFactorsM
+ , viewInputInt "text" "$N" m.ch1IntN CommonFactorsN
+ , displayAnswerCh1 m.ch1Result
+ , h1 [] [ text "Task2: Interleave String" ]
, viewInput "text" "String A"
m.ch2StringA InterleavedStringFirst
, viewInput "text" "String B"
@@ -69,31 +91,52 @@ view m =
, displayAnswerCh2 m.ch2StringC m.ch2Result
]
+viewInputInt : String -> String -> Int -> (String -> msg) -> Html msg
+viewInputInt t p i toMsg =
+ viewInput t p (if i < 0 then ""
+ else S.fromInt i ) toMsg
+
viewInput : String -> String -> String -> (String -> msg) -> Html msg
viewInput t p v toMsg =
div [ style "display" "inline-block" ]
[ input [ size 150, type_ t, 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 : String -> Result String (List (List String)) -> Html msg
displayAnswerCh2 stringC result =
displayAnswer "Result: "
(case result of
Ok listOfStringList ->
- Ok ("Interleaved as `" ++ stringC ++ "' can be divided into\n"
- ++ (S.join " or "
+ Ok ("1 (Interleaved) as `" ++ stringC ++ "' can be divided into\n"
+ ++ (S.join "\n"
(L.map
(\sl ->
"[" ++ (S.join ", " sl) ++ "]" )
listOfStringList )))
Err e -> Err e)
+viewReadOnlyTextArea : String -> String -> Html msg
+viewReadOnlyTextArea color str =
+ textarea [ readonly True, style "color" color
+ , rows 15, cols 150, value str ] []
+
displayAnswer : String -> Result String String -> Html msg
displayAnswer entryString result =
case result of
- Ok str -> div [ style "color" "green" ]
- [ text (entryString ++ str) ]
+ Ok msg -> div []
+ [ viewReadOnlyTextArea "green" msg ]
Err e ->
if e == ""
- then div [ style "color" "blue" ]
- [ text (entryString ++ "please input all the entries") ]
- else div [ style "color" "red" ] [ text e ]
+ then div []
+ [ viewReadOnlyTextArea "blue"
+ (entryString ++ "please input all the entries") ]
+ else div []
+ [ viewReadOnlyTextArea "red" e ]
diff --git a/challenge-082/jeongoon/go/ch-1.go b/challenge-082/jeongoon/go/ch-1.go
new file mode 100644
index 0000000000..1205ad51df
--- /dev/null
+++ b/challenge-082/jeongoon/go/ch-1.go
@@ -0,0 +1,112 @@
+/*
+ * test with : go run ch-1.go 12 8
+ * Ref: https://www.admfactory.com/convert-string-to-int-golang/
+ * https://stackoverflow.com/questions/13247644/tostring-function-in-go
+ */
+
+/* Comment:
+ * I cannot see why go is popular... T.T
+ */
+
+package main
+
+import (
+ "os"
+ "fmt"
+ "strings"
+ "strconv"
+)
+
+func usage() {
+ fmt.Println( "Usage: go run ch-1.go <natural num> <natural num>" )
+}
+
+
+type MaybeNat string
+
+func (str MaybeNat) Nat() Nat {
+ n, err := strconv.Atoi(string(str))
+ if err == nil {
+ return(Nat(n))
+ } else {
+ return(Nat(0))
+ }
+}
+
+func (str MaybeNat) isNatural() bool {
+ return(str.Nat() > 0)
+}
+
+type Nat int
+func (n Nat) String() string {
+ return fmt.Sprintf("%d", n)
+}
+
+func gcd(m int, n int) int { // a not bad gcd implementation
+ var sm, bg int
+
+ if m == n {
+ return(m)
+ } else if m < n {
+ sm, bg = m, n
+ } else {
+ sm, bg = n, m
+ }
+
+ if bg % sm == 0 {
+ return(sm)
+ }
+
+ for i := sm-1; i > 0; i-- {
+ if bg % i == 0 && sm % i == 0 {
+ return(i)
+ }
+ }
+ // cannot reach here but have to mention
+ return(1)
+}
+
+func commonDivisors (a int, b int) []int {
+ var result []int
+ gcd := gcd(a,b)
+
+ for i := 1; i <= gcd; i++ {
+ if gcd % i == 0 {
+ result = append(result, i);
+ }
+ }
+ return result
+}
+
+func main() {
+ if len(os.Args[1:]) != 2 {
+ usage();
+ os.Exit(1);
+ }
+
+ var N []Nat
+ all_good := true
+
+ for _, str := range os.Args[1:3] {
+ if MaybeNat(str).isNatural() {
+ N = append(N, MaybeNat(str).Nat())
+ } else {
+ all_good = false
+ break
+ }
+ }
+
+ if ! all_good {
+ usage();
+ os.Exit(2);
+ }
+
+ cvs := commonDivisors(int(N[0]), int(N[1]))
+
+ var S []string
+ for _, n := range(cvs) {
+ S = append(S, Nat(n).String())
+ }
+
+ fmt.Println( "(" + strings.Join(S, ", ") + ")" )
+}
diff --git a/challenge-082/jeongoon/go/ch-2.go b/challenge-082/jeongoon/go/ch-2.go
new file mode 100644
index 0000000000..10b66cf142
--- /dev/null
+++ b/challenge-082/jeongoon/go/ch-2.go
@@ -0,0 +1,99 @@
+/*
+ * note: this is different approach when compared to my other solutions
+ *
+ * checking just interleaving or not (non-recursive version)
+ *
+ * Tested with:
+
+ * go run ch-2.go ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCABCDDEFGHIJEFKLGHIJKLMNMNOOPPQRQRSTUVSTWXYUVWXYZZ # -> 1
+ * go run ch-2.go XY XX XYXX # -> 1
+ * go run ch-2.go YX X XXY # -> 0
+ */
+
+package main
+
+import (
+ "os"
+ "fmt"
+)
+
+func isInterleaving (A string, B string, C string) bool {
+ Alen, Blen, Clen := len(A), len(B), len(C)
+ if Alen + Blen != Clen {
+ return false
+ }
+
+ Apin, Bpin := -1, -1
+ checkpingPlanB := false
+
+ for Ai, Bi, Ci := 0, 0, 0 ;; Ci = Ai + Bi {
+ if checkpingPlanB {
+ if Bpin > 0 {
+ // note: it was A[Ai] == B[Bi] == C[Ci]
+ // and tried A already.
+ Bi = Bpin + 1
+ Ai = Apin
+ Apin, Bpin = -1, -1
+ checkpingPlanB = false
+ } else {
+ // there is no plan B ...
+ return false
+ }
+ continue
+ } else {
+ if Ci == Clen {
+ return true
+ }
+ if Ai == Alen {
+ if B[Bi:] == C[Ci:] {
+ return true
+ } else {
+ checkpingPlanB = true
+ continue
+ }
+ } else if Bi == Blen {
+ return A[Ai:] == C[Ci:]
+ }
+
+ if A[Ai] == B[Bi] {
+
+ if A[Ai] != C[Ci] {
+ checkpingPlanB = true
+ } else {
+ // remember this node
+ Apin, Bpin = Ai, Bi
+ // try plan A first
+ Ai++
+ }
+ } else {
+
+ if A[Ai] == C[Ci] {
+ Ai++
+ } else if B[Bi] == C[Ci] {
+ Bi++
+ } else {
+ checkpingPlanB = true
+ }
+ }
+ }
+ }
+}
+
+func usage() {
+ fmt.Println( "Usage: go run ch-2.go " +
+ "<string> <string> <may be interleaved string>\n" )
+}
+
+func main() {
+ if len(os.Args[1:]) != 3 {
+ usage();
+ os.Exit(1);
+ }
+ A, B, C := os.Args[1], os.Args[2], os.Args[3]
+
+ if isInterleaving(A, B, C) {
+ fmt.Println( "1" )
+ } else {
+ fmt.Println( "0" )
+ }
+}
diff --git a/challenge-082/jeongoon/haskell/ch-1.hs b/challenge-082/jeongoon/haskell/ch-1.hs
new file mode 100644
index 0000000000..fda6cf8772
--- /dev/null
+++ b/challenge-082/jeongoon/haskell/ch-1.hs
@@ -0,0 +1,23 @@
+import System.Environment
+import System.Exit
+import Data.Char (isNumber)
+import Data.Maybe (isJust, catMaybes)
+
+{- test with:
+runhaskell ch-1.hs 12 18
+-}
+
+-- from ch-081/ch-1.hs :-]
+--commonDivisors :: (Integral a) => [a] -> [a]
+commonDivisors [] = []
+commonDivisors xs = filter ((==0).(rem gcd')) ([1..(gcd' `div` 2)] ++ [gcd'])
+ where gcd' = foldr1 (\acc x -> gcd acc x) xs
+
+main = do
+ (catMaybes.map (\nStr ->
+ if (all isNumber nStr) then Just(read nStr :: Int)
+ else Nothing )) `fmap` getArgs
+ >>= (\nums ->
+ if length nums /= 2 then
+ die "Usage: runhaskell ch-1.hs <natural num> <natural num>"
+ else (putStrLn.show.commonDivisors.take 2) nums )
diff --git a/challenge-082/jeongoon/haskell/ch-2.hs b/challenge-082/jeongoon/haskell/ch-2.hs
index a3fc204f5a..5dd2eff3fd 100644
--- a/challenge-082/jeongoon/haskell/ch-2.hs
+++ b/challenge-082/jeongoon/haskell/ch-2.hs
@@ -3,6 +3,10 @@ import System.Exit
import Data.Maybe (catMaybes)
import Data.List (intersect, intercalate)
+{- test with:
+runhaskell ch-2.hs XXY XXZ XXXXZY
+-}
+
data WhichPart = Odd | Even deriving (Show, Eq)
decomposeAsEachOddsEvensWith :: String -> [Int] -> ([String], String, String)
@@ -86,7 +90,7 @@ main = do
args <- getArgs;
let sa = args !! 0; sb = args !! 1; sc = args !! 2 in
if length args /= 3
- then die "Usage: runhaskell ch-1.hs <string A> <string B> <string C>"
+ then die "Usage: runhaskell ch-2.hs <string A> <string B> <string C>"
else
case allInterleavedCases sa sb sc of
Left err -> putStrLn $ "0 as " ++ err
diff --git a/challenge-082/jeongoon/perl/ch-1.pl b/challenge-082/jeongoon/perl/ch-1.pl
new file mode 100644
index 0000000000..3af39cafce
--- /dev/null
+++ b/challenge-082/jeongoon/perl/ch-1.pl
@@ -0,0 +1,47 @@
+#!/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(all);
+
+sub usage {
+ say 'Usage: perl ch-1.pl <natural num> <natural num>', "\n",
+ 'ex) perl ch-1.pl 12 18';
+}
+
+sub common_divisors_($$) {
+ # note: do not check they are natural numbers.
+ my ( $l, $r ) = @_;
+
+ my @gcdFinders;
+
+ @gcdFinders = (
+ # for 0 ( == )
+ sub { $l },
+ # for 1 ( < )
+ sub { # left hand side is smaller but trust user input if given
+ my ( $sm, $bg ) = @_ ? @_ : ($l, $r);
+ if ( $bg % $sm == 0 ) { $sm }
+ else {
+ my $i = $sm;
+ --$i while ( $sm % $i || $bg % $i );
+ $i;
+ }
+ },
+ # for -1 ( > )
+ sub { $gcdFinders[1]->( $r, $l ); }
+ );
+
+ my $gcd = $gcdFinders[ $l <=> $r ]->();
+ map { ( $gcd % $_ ) ? () : $_ } 1 .. $gcd;
+}
+
+my ( $M, $N ) = @ARGV;
+
+( @ARGV == 2
+ and
+ all { int($_) eq $_ and $_ > 0 } $M, $N ) or usage, exit 0;
+
+say "(".join(", ", common_divisors_( $M, $N )).")";
diff --git a/challenge-082/jeongoon/perl/ch-2.pl b/challenge-082/jeongoon/perl/ch-2.pl
new file mode 100644
index 0000000000..e5eba1d0f0
--- /dev/null
+++ b/challenge-082/jeongoon/perl/ch-2.pl
@@ -0,0 +1,169 @@
+#!/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(all any min);
+
+# this will find the all the possilbe way to make interleave string
+
+# tested with:
+# perl ch-2.pl ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCABCDDEFGHIJEFKLGHIJKLMNMNOOPPQRQRSTUVSTWXYUVWXYZZ # 1: 256 cases
+# perl ch-2.pl XY XX XYXX # 1: 1 cases
+# perl ch-2.pl 1X XX XXX1 # 0
+
+sub usage {
+ say $/,'Usage: perl ch-2.pl <string> <string> <may be interleaved string>',
+ $/,'ex) perl ch-1.pl AY AA AYAA # only 1 case.',$/;
+}
+
+# real entry point
+sub allPossiblePartitions ($$$) {
+ my ( $A, $B, $C ) = @_;
+ my $sum = length $C;
+ my @sps = somePossilbeSum( 1, $sum, [], [],
+ sub ($) { # check if we can continue to make a permutation sequences
+ my $parts = shift;
+ @$parts <= 1 and return 1; # 1 block is too short
+ # because we need to compare both A,B
+
+ my ( $splited, $o, $e ) # o: odd indexed chars(string)
+ # e: even indexed chars(string)
+ = uninterleave( $C, $parts );
+ # check if *maybe* interleaved
+ # we will confirm later
+ return any { # any case of A, B vs B, A
+ my ($l, $r) = @$_; # left, right
+
+ my $omin = (min (map {length} $l, $o));
+ my $emin = (min (map {length} $r, $e));
+
+ all {
+ # minimum compare left vs odds
+ # or right vs evens
+ my ($m, $n, $len) = @$_;
+ substr( $m, 0, $len ) eq substr( $n, 0, $len )
+ } [$l, $o, $omin], [$r, $e, $emin];
+ } [$A,$B], [$B,$A];
+ }
+ );
+
+ map { # confirm the cases if actually interleaved
+ if ( @$_ > 1 ) {
+ my @resultRow = uninterleave( $C, $_ );
+ my ( $splited, $o, $e ) = @resultRow;
+
+ if ( any {
+ my ( $a, $b ) = @$_;
+ $a eq $o and $b eq $e
+ } [$A, $B], [$B, $A] ) {
+ \@resultRow
+ }
+ else {
+ () # not interleaved
+ }
+ } else {
+ # skip if only one block, becuase it doesn't make a interleave str.
+ # it is okay only if A or B is empty.
+ # but it doesn't make sense for me
+ # because interleaving has no meaning if one of them is empty
+ ()
+ }
+ } @sps;
+}
+
+# limited permutations with repeatition and filtering ...
+# find any possible cases of group of natural numbers can make $sum
+
+sub somePossilbeSum ( $$$$$ );
+sub somePossilbeSum ( $$$$$ ) {
+ my ( $n, $sum,
+ $parentPartitions, # store numbers into ArrayRef
+ # to remember current depth and totoal summation
+ $siblings, # possible other cases at the same level
+ $isValid # validator for current case
+ ) = @_;
+ return () if $sum == 0;
+
+ my $maybeNewPartitions = [ @$parentPartitions, $n ];
+
+ if ( $isValid->( $maybeNewPartitions ) ) {
+
+ if ( $n == $sum ) { # last (edge case) for parent case
+ # no more *next* cases in other word
+ # due to $n starts from 1 until meet $sum
+ @$siblings, [ $n ]
+ }
+ else {
+ # *maybe* have lower cases
+ my @childrenCases = somePossilbeSum( 1, # starts from 1
+ ($sum - $n ), # with rest
+ $maybeNewPartitions,
+ [], # without siblings
+ $isValid );
+
+ my @expandedCurrentCases = map { [ $n, @$_ ] } @childrenCases;
+
+ # go for next case with siblings which includes current one.
+ somePossilbeSum( ++$n, # next case
+ $sum, # with same number
+ $parentPartitions, # with the same parent
+ [ @$siblings, @expandedCurrentCases ],
+ $isValid )
+ }
+ } else {
+ @$siblings
+ }
+}