diff options
| author | Myoungjin JEON <jeongoon@gmail.com> | 2020-10-15 00:08:40 +1100 |
|---|---|---|
| committer | Myoungjin JEON <jeongoon@gmail.com> | 2020-10-15 00:08:40 +1100 |
| commit | b059dc770f514f3a7f53fc818e36c6f861871d0e (patch) | |
| tree | c72e7c59132b387df8d5f39d641794fc5b26db07 | |
| parent | dd71532a73981ec613c8c61d99fa4bbd3f3fd79c (diff) | |
| download | perlweeklychallenge-club-b059dc770f514f3a7f53fc818e36c6f861871d0e.tar.gz perlweeklychallenge-club-b059dc770f514f3a7f53fc818e36c6f861871d0e.tar.bz2 perlweeklychallenge-club-b059dc770f514f3a7f53fc818e36c6f861871d0e.zip | |
[ch-082/jeongoon] Elm Ch2.elm solution added
| -rw-r--r-- | challenge-082/jeongoon/elm/elm.json | 24 | ||||
| -rw-r--r-- | challenge-082/jeongoon/elm/src/Ch2.elm | 138 | ||||
| -rw-r--r-- | challenge-082/jeongoon/elm/src/Main.elm | 99 |
3 files changed, 261 insertions, 0 deletions
diff --git a/challenge-082/jeongoon/elm/elm.json b/challenge-082/jeongoon/elm/elm.json new file mode 100644 index 0000000000..dea3450db1 --- /dev/null +++ b/challenge-082/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-082/jeongoon/elm/src/Ch2.elm b/challenge-082/jeongoon/elm/src/Ch2.elm new file mode 100644 index 0000000000..fd4a61a14b --- /dev/null +++ b/challenge-082/jeongoon/elm/src/Ch2.elm @@ -0,0 +1,138 @@ +module Ch2 exposing ( .. {- + checkInterleavedString + , allPossiblePartitions + , WhichPart-} ) + +import String as S +import List as L +import Maybe as Mb + +type WhichPart = Odd | Even + +checkInterleavedString : String -> String -> String -> + Result String (List (List String)) +checkInterleavedString sa sb sc = + if L.all (\x -> S.length x == 0 ) [sa, sb, sc] + then Err "" -- probably initial state or equivalent to. + else if L.any(\x -> S.length x == 0) [sa, sb, sc] + then Err "Please input all the strings !!!" + else + let splitRules = allPossiblePartitions sa sb sc in + if L.length splitRules > 0 then + Ok (L.map (\r -> + case interleavePartitions sc r of + (a, b, scls) -> scls ) splitRules) + else + Err "Not interleaved" + +allPossiblePartitions : String -> String -> String -> (List (List Int)) +allPossiblePartitions sa sb sc = + if ( (S.length sa) + (S.length sb) /= S.length sc ) then + [] + else + let taretSum = S.length sc + partls = + sps 1 taretSum + (\ints -> + if ( L.length ints ) <= 1 then + True -- skip as if okay, we will sieve later + else + case checkPartiallyInterleaved sa sb (sc, ints) of + Ok _ -> True + Err _ -> False + ) + [] [] in + case partls of + Nothing -> [] + Just ll -> L.filter (\ls -> L.length ls > 1 + && (L.sum ls) == taretSum + -- filter because I checked them partially + ) ll + +-- find possible summation (permutations with repeatation and filtering) +sps : Int -> Int -> -- sps : some possible sum + (List Int -> Bool) -> -- validator + List Int -> (List (List Int)) -> + Maybe (List (List Int)) +{- there are two terms are used + next case: [[ a case ], [ next case ], ... [ next .. ] ] + lower case: [[ a case :: (with) a lower case ], + [ a case :: (with) another lower case ], .. ], + (and maybe) [ next case ] ] +-} + +sps cn origSum isValid parts siblings = -- cn: current number + if origSum == 0 then Just [] -- edge case for sure (but not Nothing) + else + let restSum = (origSum - cn) + testParts = (parts ++ [cn]) + moreParts = {-same as-}testParts + nextNumber = cn + 1 + lowerCases = sps 1 restSum + isValid moreParts siblings in + if isValid testParts then + if cn == origSum then + -- reach the max: no more next cases + -- concat with the cases in same level + Just (siblings ++ [[cn]]) + else -- note: maybe have next cases + -- push current cases into siblings and continue to + -- next cases + let currentCases = + (Mb.map (\ls -> L.map (\l -> cn :: l) ls) + lowerCases) in + case currentCases of + Nothing -> + -- lower cases has problem so ignore + -- current one, keep going for next + sps nextNumber origSum + isValid parts siblings + Just cases -> + sps nextNumber origSum + isValid parts (siblings ++ cases) + else + -- in this task, we stop here because + -- if smaller pieces cannot make a interleave string, + -- the bigger won't either + if L.length siblings > 0 then + Just siblings + else + Nothing + +checkPartiallyInterleaved : String -> String -> (String, List Int) + -> Result String (List String) +checkPartiallyInterleaved sa sb (sc, splitRules) = + case L.length splitRules of + 0 -> Err "No split rule given" + 1 -> Err "Number of split rules are must be greater than 1" + _ -> case interleavePartitions sc splitRules of + (a, b, scls) -> + -- we are comparing partially here + -- a: "XX" b: "YY" c: "XYXY" with [1,1,1] must be okay + -- because "XYX" -> "XX", "Y" + -- and startWith and `==' will check its validity + if ( (S.startsWith a sa && S.startsWith b sb) + -- or vice versa + ||(S.startsWith b sa && S.startsWith a sb) ) + then + Ok scls + else Err "Not interleaved" + +interleavePartitions : String -> List Int -> (String, String, List String) +interleavePartitions sc splitRules = + it_part__ [""] [""] [] (S.split "" sc) splitRules Odd + +it_part__ : List String -> List String -> List String -> List String -> + List Int -> WhichPart + -> (String, String, List String) +it_part__ os es ls chrs rules whichPart = + case L.head rules of + Nothing -> ( (S.concat os), (S.concat es), ls ) + Just n -> + let rs_ = L.drop 1 rules + cs = L.take n chrs + parts = S.concat cs + chrs_ = L.drop n chrs in + case whichPart of + Odd -> it_part__ (os ++ cs) es (ls ++ [parts]) chrs_ rs_ Even + Even -> it_part__ os (es ++ cs) (ls ++ [parts]) chrs_ rs_ Odd diff --git a/challenge-082/jeongoon/elm/src/Main.elm b/challenge-082/jeongoon/elm/src/Main.elm new file mode 100644 index 0000000000..6d1863fcb1 --- /dev/null +++ b/challenge-082/jeongoon/elm/src/Main.elm @@ -0,0 +1,99 @@ +{- Tested with: +elm make src/Main.elm +# and access elm/index.html in a web browser(firefox in my case) +-} + +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 + +-- Solutions ... +import Ch2 exposing (..) + +-- Main + +main = + Browser.sandbox { init = init, update = update, view = view } + +-- Model + +type alias Model = + { ch2StringA : String + , ch2StringB : String + , ch2StringC : String + , ch2Result : Result String (List (List String)) + } + +init : Model +init = Model "" "" "" (Err "") + +-- Update + +type Task = Task1 | Task2 + +type Msg = {-CommonFactors String | -} + InterleavedStringFirst String + | InterleavedStringSecond String + | InterleavedStringInterleaved String + +update : Msg -> Model -> Model +update msg m = + case msg of + InterleavedStringFirst nv -> -- new value + let res = Ch2.checkInterleavedString nv m.ch2StringB m.ch2StringC + in { m | ch2StringA = nv, ch2Result = res } + InterleavedStringSecond nv -> + let res = Ch2.checkInterleavedString m.ch2StringA nv m.ch2StringC + in { m | ch2StringB = nv , ch2Result = res } + InterleavedStringInterleaved nv -> + let res = Ch2.checkInterleavedString m.ch2StringA m.ch2StringB nv + in { m | ch2StringC = nv , ch2Result = res } +-- View + +view : Model -> Html Msg +view m = + div [ style "padding" "20px", style "width" "90%" ] + [ h1 [] [ text "Task2: Interleave String" ] + , viewInput "text" "String A" + m.ch2StringA InterleavedStringFirst + , viewInput "text" "String B" + m.ch2StringB InterleavedStringSecond + , viewInput "text" "String C (maybe interleaved)" + m.ch2StringC InterleavedStringInterleaved + , displayAnswerCh2 m.ch2StringC m.ch2Result + ] + +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 ] []] + +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 " + (L.map + (\sl -> + "[" ++ (S.join ", " sl) ++ "]" ) + listOfStringList ))) + Err e -> Err e) + +displayAnswer : String -> Result String String -> Html msg +displayAnswer entryString result = + case result of + Ok str -> div [ style "color" "green" ] + [ text (entryString ++ str) ] + Err e -> + if e == "" + then div [ style "color" "blue" ] + [ text (entryString ++ "please input all the entries") ] + else div [ style "color" "red" ] [ text e ] |
