aboutsummaryrefslogtreecommitdiff
path: root/challenge-088/jeongoon/elm/src/Main.elm
blob: 7a051aca5fbac662f9256e56ec7c62e84c9cb654 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
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 ] []