-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpython.py
More file actions
313 lines (292 loc) · 11.7 KB
/
Copy pathpython.py
File metadata and controls
313 lines (292 loc) · 11.7 KB
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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
# Author ---> Aryaman Khandelwal
# UID -----> U20210018
# Importing the packages
import re
from collections import defaultdict
# This function adds '1' in the beginning if the coefficient is missing for that term
def add_dig_start(word):
if(word[0] == '-'):
if(word[1].isdigit() == True):
return word # It already has a coefficient
else:
word = "1" + word # Adding "1" as the leading coefficient
return word
else:
if(word[0].isdigit() == True):
return word # It already has a coefficient
else:
word = "1" + word # Adding "1" as the leading coefficient
return word
# This function parses the string until it gets the alphabet | Output ---> length of the substring and substring
def parse_string_until_alphabet(string):
for i in range(len(string)):
if string[i].isalpha():
return i, string[:i]
return len(string), string
# This function stores the sign of each term. This is calld while assigning the sign to the coefficients
def assign_sign(word):
sign_list = []
current_sign = '+'
if word[0] == '-':
current_sign = '-'
if word[0].isdigit() == True or word[0].isalpha():
sign_list.append(current_sign)
for char in word:
if char in ['+','-']:
current_sign = char
sign_list.append(current_sign)
return sign_list
# This function is used to simplify the terms containing variables | Concatenates the variable with its power
def simplify_expression(char_list):
j = 0
total_list = []
while(j<len(char_list)):
if(char_list[j].isalpha()==True):
if(j+1<len(char_list) and char_list[j+1].isdigit()==True):
output = char_list[j]+char_list[j+1]
total_list.append(output)
j+=1
else:
total_list.append(char_list[j])
j+=1
else:
j+=1
return total_list
# This function splits the each term
def split_expression(word):
if word[0].isdigit() == False:
word = "1"+word
# Now we will start iterating through the word
index, coeff = parse_string_until_alphabet(word)
text = word[index:]
i = 0
list_char = []
while(i<len(text)):
list_char.append(text[i])
# Now checking whether the next character is an alphabet or '^'
if (i+1<len(text) and text[i+1]=='^'):
j = i+2
remaining_word = text[j:]
parsed_string = ""
for character in remaining_word:
if character.isalpha():
break
else:
parsed_string+= character
j+=1
i = j
list_char.append(parsed_string)
else:
i+=1
output = simplify_expression(list_char)
output.insert(0,coeff)
return output
# This function is used to create dictionary of the resultant expression. Keys are all the unique terms that appear in the expression, and the value
# of the keys are the coefficients of the terms
def convert_string(string):
result = ''
i = 0
while i < len(string):
if string[i].isalpha():
result += string[i]
i += 1
else:
num_start = i
while i < len(string) and string[i].isdigit():
i += 1
num = int(string[num_start:i])
num = num - 1
result += string[num_start - 1] * num
return result
# This function updates the keys of the dictionary. Like it converts the key 'x2y3' to 'xxyyy' and so on. For the case,
# where the key is 'xy' remains'xy' only. This function is called by create_dictionary function
def update_dict(dict1):
new_dict = {}
for index in dict1:
var = convert_string(index)
var = ''.join(sorted(var))
if index == 'constant': var = 'constant'
if var not in new_dict:
new_dict[var] = dict1[index]
else: # It is already present
new_dict[var] = int(new_dict[var]) + int(dict1[index])
return new_dict
# This function is used to create dictionary of the resultant expression. Keys are all the unique terms that appear in the expression, and the value
# of the keys are the coefficients of the terms
def create_dictionary(lst):
dict1 = {}
for elem in lst: # Extracts each element of the list
if(len(elem) == 1): # This means that it is a constant
var = 'constant' # Defining the variable as constant
if var not in dict1: # No constant term in the dictionary
dict1[var] = [elem[0]]
else: # There exists a constant term already
dict1['constant'].append(elem[0])
else: # Any term except constant
var = ""
value = elem[0]
for j in range(len(elem)):
if(j>0):
var = var + elem[j]
if var not in dict1: # If that term does not exist in the dictionary
dict1[var] = [value]
else:
dict1[var].append(value) # If that term already exists in the dictionary
# For terms which appear more than once in the expression, computing the resultant sum of them
for index in dict1:
if len(dict1[index])==1:
dict1[index] = (dict1[index])[0]
else:
sum = 0
for value in dict1[index]:sum = sum + int(value)
dict1[index] = sum
dic_out = {}
dict1 = update_dict(dict1)
for x, y in dict1.items():
if y != 0:
dic_out[x] = y
return dic_out
# This function takes sum of two expressions
def perform_operations(dict1,dict2):
master_dict = {}
# Iterate over dict1 and check if the keys exist in dict2
for key, val in dict1.items():
if key in dict2:
value = dict2[key]
if (type(value)==str):
if value[0] == '+':
value = int(value[1:])
else:
value = int(value[1:])
value = - (value)
if (type(val)== str):
if val[0] == '+':
val = int(val[1:])
else:
val = int(val[1:])
val = -(val)
master_dict[key] = val + value
# Iterate over dict2 and add the keys that are not present in dict1
for key, val in dict2.items():
if key not in dict1:
master_dict[key] = val
# Iterate over dict1 and add the keys that are not present in master_dict
for key, val in dict1.items():
if key not in master_dict:
master_dict[key] = val
return master_dict
# This function is used to call all the functions that are defined above
def call_function(text):
sign_list = assign_sign(text)
# Splits the string whenever it encounters a (+) or (-) sign, without including the sign in the split
result = re.split('(?<![eE])[+-]', text)
# Removes any leading or trailing whitespace from each term
result = [term.strip() for term in result]
if result[0] == '':
result = result[1:]
for i in range(len(result)):
word = result[i]
output = add_dig_start(word)
result[i] = output
if any(c.isalpha() for c in result[i]):
result[i] = split_expression(result[i])
else:
result[i] = [result[i]]
# Adding the respective signs to each term
for i in range(len(result)):
expression = result[i]
expression[0] = sign_list[i] + expression[0]
return result
# This function is used to call call_function and create_dictionary for a term
def row_operations(term):
result = call_function(term)
dict1 = create_dictionary(result)
return dict1
# This function performs operations for a row. Here the variable row can be a single row, column, left diagonal, right diagonal
def calculate_row(row):
resultant_dict = defaultdict(int)
for i in range(len(row)-1):
if i == 0:
dict1 = row_operations(row[i])
dict2 = row_operations(row[i+1])
resultant_dict = perform_operations(dict1,dict2)
else:
dict1 = row_operations(row[i+1])
resultant_dict = perform_operations(resultant_dict,dict1)
return resultant_dict
# This function is used to check whether the matrix is a magic square matrix or not
def is_magic_square(matrix):
# Checks for all the rows
master_dict = defaultdict(int)
for i in range(len(matrix)):
if i == 0:
master_dict = calculate_row(matrix[i])
else:
check_dict = calculate_row(matrix[i])
if (master_dict!=check_dict):
return False
# Checks for all the columns
num_cols = len(matrix[0])
for col_idx in range(num_cols):
column = [matrix[row_idx][col_idx] for row_idx in range(len(matrix))]
check_dict = calculate_row(column)
if (master_dict!=check_dict):
return False
check_dict.clear()
# Checks for the left diagonal
left_diag = [matrix[i][i] for i in range(len(matrix))]
check_dict = calculate_row(left_diag)
if (master_dict!=check_dict):
return False
check_dict.clear()
# Checks for the right diagonal
size = len(matrix)
right_diag = [matrix[i][-1-i] for i in range(size)]
check_dict = calculate_row(left_diag)
if (master_dict!=check_dict):
return False
return True
# This function is used to parse text from the matrix.txt file, and generates the matrix that needs to be check whether they are magic square
# or not.
def parse_text():
with open("./matrix.txt","r") as file:
matrix = []
for line in file:
if line.strip(): # Not an empty line
lst = line.rstrip().split(' ')
lst = [value.lstrip() for value in lst]
matrix.append(lst)
else:
print("The output is:",is_magic_square(matrix))
matrix = []
print("The output is:",is_magic_square(matrix))
########################################### ALL THE FUNCTIONS FOR EXPRESSIONS END HERE ####################################################
def main():
parse_text()
return 0
if __name__== "__main__" :
main()
########################################### SOME OF THE TEST CASES THAT I HAVE USED ###########################################################
# print(is_magic_square(matrix))
# matrix = [["8", "1", "6"],["3", "5", "7"],["4", "9", "2"]]
# print("The output is: ",is_magic_square(matrix))
# matrix = [ ["16", "2", "3", "13"],["5", "11", "10", "8"],["9", "7", "6", "12"],["4", "14", "15", "1"] ]
# print("The output is: ",is_magic_square(matrix))
# matrix = [ ["1", "2", "3"],["4", "5", "6"],["7", "8", "9"]]
# output = is_magic_square(matrix)
# print("The output is: ",output)
# matrix = [["x^2+2","x^2+5x+7","x^2+4x+6"], ['x^2+7x+9','x^2+3x+5','x^2-x+1'] , ['x^2+2x+4','x^2+x+3','x^2+6x+8']]
# output = is_magic_square(matrix)
# print("The output is: ",output)
# matrix = [["y^2x+xy-1+xz-xz","yx+1-2+xy^2"],["xy+y^2x-1" ,'yx-1+z^2+xy^2-z^2']]
# output = is_magic_square(matrix)
# print("The output is: ",output)
# matrix = [["-x^2y^2+2xy+1" ,"-x^2y^2+7yx-5yx+1"],["2x^2y^2-3x^2y^2+2xy+1","2xy-y^2x^2+1"]]
# output = is_magic_square(matrix)
# print("The output is: ",output)
# matrix = [['-x^2y^2 + 2xy + 1','-x^2y^2 + 7yx - 5yx + 1'],['2x^2y^2 - 3x^2y^2 + 2xy + 1', '2xy - y^2x^2 + 1']]
# output = is_magic_square(matrix)
# print("The output is: ",output)
# matrix = [['1+1', '1+1'], ['1+1', '1+1']]
# output = is_magic_square(matrix)
# print("The output is: ",output)