aboutsummaryrefslogtreecommitdiff
path: root/challenge-094/paulo-custodio/basic/ch-1.bas
blob: dba3fb7e3ed5b1fdc6fce93302c666b8dee7ac53 (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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
' Challenge 094
'
' TASK #1 � Group Anagrams
' Submitted by: Mohammad S Anwar
' You are given an array of strings @S.
'
' Write a script to group Anagrams together in any random order.
'
' An Anagram is a word or phrase formed by rearranging the letters of a
' different word or phrase, typically using all the original letters exactly
' once.
'
' Example 1:
'     Input: ("opt", "bat", "saw", "tab", "pot", "top", "was")
'     Output: [ ("bat", "tab"),
'               ("saw", "was"),
'               ("top", "pot", "opt") ]
' Example 2:
'     Input: ("x")
'     Output: [ ("x") ]

' List of strings
Type ListNodeType
    value as String
    nxt as ListNodeType Ptr
End Type

Type ListType
    head as ListNodeType Ptr
    tail as ListNodeType Ptr
End Type


' Map of keys to lists of strings
Type MapNodeType
    key as String
    values as ListType
    nxt as MapNodeType Ptr
End Type

Type MapType
    head as MapNodeType Ptr
    tail as MapNodeType Ptr
End Type


Sub list_push(Byref list as ListType, value as String)
    Dim node as ListNodeType Ptr
    node = Callocate(1, Sizeof(ListNodeType))
    node->value = value
    if list.head = 0 Then
        list.head = node
        list.tail = node
    Else
        list.tail->nxt = node
        list.tail = node
    End If
End Sub

Sub list_delete(Byref list as ListType)
    Dim node as ListNodeType Ptr, nxt as ListNodeType Ptr
    node = list.head
    Do While node <> 0
        nxt = node->nxt
        Deallocate(node)
        node = nxt
    Loop
End Sub

Sub list_print(Byref list as ListType)
    Dim node as ListNodeType Ptr
    Print "(";
    node = list.head
    Do While node <> 0
        If node <> list.head Then Print ", ";
        Print """"; node->value; """";
        node = node->nxt
    Loop
    Print ")";
End Sub


' add/find a key
Function map_add_key(Byref map as MapType, key as String) as ListType Ptr
    Dim node as MapNodeType Ptr
    If map.head = 0 Then                ' map empty
        node = Callocate(1, Sizeof(MapNodeType))
        map.head = node
        map.tail = node
        node->key = key
        map_add_key = @node->values
    Else
        node = map.head
        Do While node <> 0
            If node->key = key Then     ' found key
                map_add_key = @node->values
                Exit Function
            End If
            node = node->nxt
        Loop

        ' not found
        node = Callocate(1, Sizeof(MapNodeType))
        node->key = key
        map.tail->nxt = node
        map.tail = node
        map_add_key = @node->values
    End If
End Function

' add key/value
Sub map_add_key_value(Byref map as MapType, key as String, value as String)
    Dim list as ListType Ptr
    list = map_add_key(map, key)
    list_push(*list, value)
End Sub

Sub map_print(Byref map as MapType)
    Dim node as MapNodeType Ptr
    print "[ ";
    node = map.head
    Do While node <> 0
        If node <> map.head Then Print ",":Print "  ";
        list_print(node->values)
        node = node->nxt
    Loop
    Print " ]"
End Sub

Sub map_delete(Byref map as MapType)
    Dim node as MapNodeType Ptr, nxt as MapNodeType Ptr
    node = map.head
    Do While node <> 0
        nxt = node->nxt
        list_delete(node->values)
        Deallocate(node)
        node = nxt
    Loop
End Sub


' sort a string - selection sort
Function sort_string(Byval s as String) as String
    dim i as Integer, j as Integer, min_i as Integer
    dim c as String

    for i=0 to len(s)-1
        min_i=i
        for j=i+1 to len(s)
            if Asc(Mid(s,j,1)) < Asc(Mid(s,min_i,1)) Then
                min_i=j
            End If
        Next j

        ' swap
        c=Mid(s,i,1)
        Mid(s,i,1)=Mid(s,min_i,1)
        Mid(s,min_i,1)=c
    next i
    sort_string = s
End Function


' read strings from command line, build map
Sub read_strings(Byref map as MapType)
    Dim key as String, value as String
    Dim i as Integer
    i = 1
    Do While Command(i) <> ""
        value = Command(i)
        key = sort_string(value)
        map_add_key_value(map, key, value)
        i = i+1
    Loop
End Sub

' main
Dim map as MapType
read_strings(map)
map_print(map)
map_delete(map)