-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathInsertionSort.elm
141 lines (110 loc) · 4.14 KB
/
InsertionSort.elm
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
module InsertionSort
exposing
( InsertionList
, insertionSort
, init
, update
, animate
, view
, subscribe
)
import Html exposing (Html)
import Point exposing (Point, updatePosition, updateStyles, animateElement, renderPoints)
import Animation
type alias InsertionList =
{ sorted : CurrentList, unsorted : List Point }
type CurrentList
= SortBuffer (List Point) Point (List Point)
| SortedList (List Point)
init : List Point -> InsertionList
init unsorted =
{ unsorted = unsorted, sorted = SortedList [] }
update : InsertionList -> InsertionList
update oldList =
let
newModel =
insertionSort oldList.sorted oldList.unsorted
in
case newModel.sorted of
SortedList list ->
{ newModel | sorted = SortedList (List.map updateStyles (list)) }
SortBuffer head element unsorted ->
{ newModel
| sorted =
SortBuffer
(List.map updateStyles head)
(updateStyles element)
(List.map updateStyles unsorted)
}
animate : Animation.Msg -> InsertionList -> InsertionList
animate time newList =
case newList.sorted of
SortedList list ->
{ sorted = SortedList (List.map (animateElement time) list)
, unsorted = newList.unsorted
}
SortBuffer head element unsorted ->
{ sorted =
SortBuffer
(List.map (animateElement time) head)
((animateElement time) element)
(List.map (animateElement time) unsorted)
, unsorted = newList.unsorted
}
view : InsertionList -> List (Html msg)
view list =
renderPoints "Insertion Sort" ((currentListToList list.sorted) ++ list.unsorted)
subscribe : (Animation.Msg -> msg) -> InsertionList -> Sub msg
subscribe msg list =
Animation.subscription msg (List.map .style ((currentListToList list.sorted) ++ list.unsorted))
currentListToList : CurrentList -> List Point
currentListToList currentList =
case currentList of
SortBuffer sorted element unsorted ->
sorted ++ (element :: unsorted)
SortedList list ->
list
insertionSort : CurrentList -> List Point -> InsertionList
insertionSort sorted list =
case sorted of
SortBuffer head element sorted ->
{ sorted = insertHelper head element sorted, unsorted = list }
SortedList sortedList ->
case list of
[] ->
{ sorted = sorted, unsorted = [] }
[ x ] ->
{ sorted = insert x sortedList, unsorted = [] }
x :: xs ->
{ sorted = insert x sortedList, unsorted = xs }
insert : Point -> List Point -> CurrentList
insert =
insertHelper []
insertHelper : List Point -> Point -> List Point -> CurrentList
insertHelper head element sorted =
case sorted of
[] ->
SortedList [ element ]
[ x ] ->
if x.value < element.value then
SortedList
(head
++ [ updatePosition (List.length head) x
, updatePosition (List.length head + 1) element
]
)
else
SortedList
(head
++ [ updatePosition (List.length head) element
, updatePosition (List.length head + 1) x
]
)
x :: xs ->
if x.value < element.value then
SortBuffer
(head ++ [ updatePosition (List.length head) x ])
(updatePosition (List.length head + 1) element)
(List.indexedMap (\i x -> updatePosition (List.length head + 2 + i) x) xs)
else
SortedList (head ++ ((updatePosition (List.length head) element) :: (List.indexedMap (\i x -> updatePosition (List.length head + 1 + i) x) sorted)))