◂ 21 décembre 2022 ▸
Monkey Math : Calculer une expression mathématique, puis en résoudre une autre
vbjj: fcml * mwwn
mbmw: 2
gstw: cldd / rvtn
brsc: 5
bpjn: 11
⋮
- moncode.py
- codeReductionEquation.py
- calcul.py
class calcul:
def __init__(self, t):
if type(t) == calcul:
self.type = t.type
if t.type in ['i', 'x']:
self.v = t.v
else:
self.m1 = t.m1
self.m2 = t.m2
return
if (type(t) == list or type(t) == tuple) and len(t) == 1:
t = t[0]
if type(t) == int:
self.type = 'i'
self.v = t
elif type(t) == str:
self.type = 'x'
self.v = t
else:
m1 = calcul(t[0])
m2 = calcul(t[2])
if m1.type == 'i' and m2.type == 'i' and (t[1] != '/' or m1.v % m2.v == 0):
self.type = 'i'
if t[1] == '+':
self.v = m1.v + m2.v
elif t[1] == '-':
self.v = m1.v - m2.v
elif t[1] == '*':
self.v = m1.v * m2.v
elif t[1] == '/':
self.v = m1.v // m2.v
else:
print("Aargh 2", t)
exit(1)
if(self.v == 0):
print("Hum...", t, t[0], t[1], t[2])
else:
self.m1 = m1
if t[1] not in ['+', '-', '*', '/']:
print("Aaargh 3", t, t[0], t[2])
exit(1)
self.type = t[1]
self.m2 = m2
def isNum(self):
return self.type == 'i' or set(str(self)).issubset(set('()+-*/ 0123456789')) # pas de x ou autre variable
def reduire(self):
if self.type in ['i', 'x']:
return self
m1 = self.m1.reduire()
m2 = self.m2.reduire()
if m1.type == 'i' and m2.type == 'i':
if self.type != '/' or m1.v % m2.v == 0:
return calcul([m1, self.type, m2]).reduire()
elif self.type == '/':
v1 = m1.v
v2 = m2.v
if v2 < 0:
v1 *= -1
v2 *= -1
for f in [2,3,5,7,11,13,17,19]:
while v1 % f == 0 and v2 % f == 0:
v1 //= f
v2 //= f
m1.v = v1
m2.v = v2
if m2.type == 'i' and self.type in ['-']:
return calcul([-m2.v, '+', m1]).reduire()
if m2.isNum() and not m1.isNum() and self.type in ['+', '*']:
return calcul([m2, self.type, m1]).reduire()
if m2.type == 'i' and m1.type != 'i' and self.type in ['+', '*']:
return calcul([m2, self.type, m1]).reduire()
if self.type == '+':
if m1.isNum() and m2.type in ['+', '-'] and m2.m1.isNum():
return calcul([ [m1, '+', m2.m1], m2.type, m2.m2 ]).reduire()
if m1.isNum() and m2.isNum():
if m1.type == '/' and m2.type == '/':
return calcul([ [[m1.m1, '*', m2.m2], '+', [m2.m1, '*', m1.m2]], '/', [m1.m2, '*', m2.m2] ]).reduire()
elif m1.type == 'i':
return calcul([ [[m1.v, '*', m2.m2], '+', m2.m1], '/', m2.m2 ]).reduire()
if self.type == '-':
if m1.isNum() and m2.type in ['+'] and m2.m1.isNum():
return calcul([ [m1, '-', m2.m1], '-', m2.m2 ]).reduire()
if m1.isNum() and m2.type in ['-'] and m2.m1.isNum():
return calcul([ [m1, '-', m2.m1], '+', m2.m2 ]).reduire()
if m1.isNum() and m2.isNum():
if m1.type == '/' and m2.type == '/':
return calcul([ [[m1.m1, '*', m2.m2], '-', [m2.m1, '*', m1.m2]], '/', [m1.m2, '*', m2.m2] ]).reduire()
elif m1.type == 'i':
return calcul([ [[m1.v, '*', m2.m2], '-', m2.m1], '/', m2.m2 ]).reduire()
if self.type == '*':
if m1.type == 'i' and m2.type in ['*', '/'] and m2.m1.type == 'i':
return calcul([m1.v * m2.m1.v, m2.type, m2.m2]).reduire()
if m1.type == 'i' and m2.type in ['/'] and m2.m2.type == 'i':
return calcul([[m1, '/', m2.m2] , '*', m2.m1]).reduire()
if m1.type == '*' and m2.type == '*':
return calcul([ [m1.m1, '*', m2.m1], '*', [m1.m2, '*', m2.m2] ]).reduire()
if m1.type == '/' and m2.type == '*':
return calcul([ [m1.m1, '*', m2.m1], '*', [m2.m2, '/', m1.m2] ]).reduire()
if m1.type == '*' and m2.type == '/':
return calcul([ [m1.m1, '*', m2.m1], '*', [m1.m2, '/', m2.m2] ]).reduire()
if m1.type == '/' and m2.type == '/':
return calcul([ [m1.m1, '*', m2.m1], '/', [m1.m2, '*', m2.m2] ]).reduire()
if self.type == '/':
if m2.type == '/':
return calcul( [m1, '*', [m2.m2, '/', m2.m1]] ).reduire()
if m1.type == 'i' and m2.type == '*':
if m2.m1.type == 'i' and m1.v % m2.m1.v == 0:
return calcul([m1.v // m2.m1.v, '/', m2.m2]).reduire()
if m2.m1.isNum():
return calcul([[m1, '/', m2.m1], '/', m2.m2]).reduire()
elif m1.type == 'i' and m2.type == '/':
if m2.m1.type == 'i' and m1.v % m2.m1.v == 0:
return calcul([m1.v // m2.m1.v, '*', m2.m2]).reduire()
if m2.m2.type == 'i':
return calcul([m1.v * m2.m2.v, '/', m2.m1]).reduire()
elif m2.type == 'i' and m1.type in ['/']:
return calcul([m1.m1, '/', [m2, '*', m1.m2] ]).reduire()
if m1.type == '/' and m2.type == '*':
return calcul([m1.m1, '/', [m1.m2, '*', m2]]).reduire()
if m1.type == '*' and m2.type == '/':
return calcul([[m2.m2, '*', m1], '/', m2.m1]).reduire()
if m1.type == '/' and m2.type == '/':
return calcul([ [m1.m1, '*', m2.m2], '/', [m1.m2, '*', m2.m1] ]).reduire()
if m1.type in ['*','/'] and m2.type == '*' and m1.m1.type == 'i' and m2.m1.type == 'i' and m1.m1.v % m2.m1.v == 0: # (a#f) / (b%g) = (a/b)
return calcul([ [m1.m1.v // m2.m1.v, m1.type, m1.m2], '/', m2.m2 ]).reduire()
if self.type == '*' and m2.type in ['+', '-']:
return calcul([calcul([m1, '*', m2.m1]).reduire(), m2.type, calcul([m1, '*', m2.m2]).reduire()])
if self.type == '/' and m1.type in ['+', '-']:
return calcul([calcul([m1.m1, '/', m2]).reduire(), m1.type, calcul([m1.m2, '/', m2]).reduire()])
c = calcul([m1, self.type, m2])
if str(m1) == str(self.m1) and str(m2) == str(self.m2):
return calcul([m1, self.type, m2])
else:
return calcul([m1, self.type, m2]).reduire()
def __str__(self):
if self.type == 'i':
return str(self.v)
if self.type == 'x':
return self.v
if self.type == '*':
a = str(self.m1)
b = str(self.m2)
if self.m1.type not in ['*', '/', 'i', 'x']:
a = '(' + a + ')'
if self.m2.type not in ['*', '/', 'i', 'x']:
b = '(' + b + ')'
return a + '*' + b
if self.type == '/':
a = str(self.m1)
b = str(self.m2)
if self.m1.type not in ['*', '/', 'i', 'x']:
a = '(' + a + ')'
if self.m2.type not in ['i', 'x']:
b = '(' + b + ')'
return a + '/' + b
if self.type == '+':
return str(self.m1) + '+' + str(self.m2)
if self.type == '-':
a = str(self.m1)
b = str(self.m2)
if self.m2.type not in ['*', '/', 'i', 'x']:
b = '(' + b + ')'
return a + '-' + b