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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
{- 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 =
{ ch1IntStr : String
, ch1ReversedStr : String
, ch1Result : Result String String
, ch2MatString : String
, ch2Squares : Result String (List Ch2.Square)
}
init : Model
init = Model "" "" (Err "") "" (Err "")
-- Update
type Task = Task1 | Task2
type Msg = ReverseIntegerValueChanged String
| FindSquareMatrixChanged String
update : Msg -> Model -> Model
update msg m =
case msg of -- nv: new value
ReverseIntegerValueChanged nv ->
let resReversed = Ch1.reverseIntStr nv in
case resReversed of
Err e -> { m | ch1IntStr = nv
, ch1ReversedStr = ""
, ch1Result = (Err e) }
Ok reversed ->
{ m | ch1IntStr = nv
, ch1ReversedStr = reversed
, ch1Result = Ch1.filter32Bit reversed }
FindSquareMatrixChanged nv ->
-- ref: https://package.elm-lang.org/packages/elm/core/latest/Basics#(|%3E)
-- https://package.elm-lang.org/packages/elm/core/latest/Result#andThen
{ m | ch2MatString = nv
, ch2Squares =
( nv
|> Ch2.pointsAtRowsFromString
|> R.andThen Ch2.getHorizLines
|> R.andThen Ch2.findSquares ) }
-- View
view : Model -> Html Msg
view m =
div [ style "padding" "20px", style "width" "90%" ]
[ h1 [] [ text "Task1: Reverse Integer" ]
, viewInput "text" "Input" m.ch1IntStr ReverseIntegerValueChanged
, displayAnswerCh1 m
, h1 [] [ text "Task2: Find Squares" ]
, viewInputTextArea "Input a matrix data"
m.ch2MatString FindSquareMatrixChanged
, displayAnswerCh2 m.ch2Squares
]
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 ] []]
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 : Model -> Html msg
displayAnswerCh1 m =
displayAnswer "Result"
(case m.ch1Result of
Ok filteredReversed ->
Ok filteredReversed
Err e ->
if e == "" then
Ok ""
else
Err (m.ch1IntStr ++ " was reversed as\n"
++ m.ch1ReversedStr
++ "\nHowever filtred because\n" ++ e))
displayAnswerCh2 : Result String (List Ch2.Square) -> Html msg
displayAnswerCh2 result =
displayAnswer "Result: "
(case result of
Ok squaresList ->
Ok (S.concat
(("Found " ++ (S.fromInt (L.length squaresList))
++ " squares.\n")
:: (L.indexedMap
(\idx sq ->
let sz = (S.fromInt (sq.hline.end
- sq.hline.start)) in
(S.fromInt (idx + 1))
++ ": (" ++ sz ++ " X " ++ sz ++ ")"
++ " from (r:" ++ (S.fromInt sq.hline.row)
++ ", c:" ++ (S.fromInt sq.hline.start)
++ ") to (r:" ++ (S.fromInt sq.alsoAtRow)
++ ", c: " ++ (S.fromInt sq.hline.end)
++ ")\n")
squaresList)))
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 msg -> div []
[ viewReadOnlyTextArea "green" msg ]
Err e ->
if e == ""
then div []
[ viewReadOnlyTextArea "blue"
(entryString ++ "please input all the entries") ]
else div []
[ viewReadOnlyTextArea "red" e ]
|