1126 - Betisoare

From Bitnami MediaWiki

Enunţ[edit | edit source]

Se presupune că unele dintre primele instrumente de calcul au fost beţişoarele de socotit. În problema noastră vom considera un număr ca fiind o succesiune de unul sau mai multe beţişoare, un beţişor fiind reprezentat de litera I. Într-o expresie, între oricare două numere există semnul + sau semnul *.

Exemple:

Numere
   I
   III
   IIIIIIIIIII
Expresii
   III
   II*III
   I+I*III+IIIIIII

Cerinţă[edit | edit source]

Scrieţi un program care evaluează astfel de expresii.

Date de intrare[edit | edit source]

Fișierul de intrare betisoare.in conține pe prima linie o valoare naturală n, care indică numărul de expresii care trebuie evaluate. Fiecare dintre următoarele n linii conţine un şir de maximum 1.000.000 caractere care reprezintă expresia ce trebuie evaluată.

Date de ieșire[edit | edit source]

Fișierul de ieșire betisoare.out va conține pe fiecare linie i dintre primele n linii câte un număr întreg care reprezintă rezultatul evaluării expresiei de pe linia i+1 din fişierul de intrare.

Restricții și precizări[edit | edit source]

  • 1 ≤ n ≤ 10
  • O expresie poate avea cel puţin 1 caracter şi cel mult 1.000.010 de caractere.
  • Valorile calculate pe parcurs şi valoarea finală au maximum 18 cifre.
  • Dintre teste, 26% conţin numai operaţii de adunare, 22% numai operaţii de înmulţire, iar restul de 52% conţin ambele operaţii.

Exemplul 1[edit | edit source]

betisoare.in
1
I+I*III+IIIIIII
betisoare.out
11

Exemplul 2[edit | edit source]

betisoare.in
1
I+I*III+IIIIIII
betisoare.out
4
2

Exemplul 3[edit | edit source]

betisoare.in
II2+3*II
betisoare.out
Date de intrare invalide!

Rezolvare[edit | edit source]

<syntaxhighlight lang="python" line>

  1. 1126 Betisoare

def verificare_date_intrare(expresie):

 caractere_permise = {'I', '+', '*'}
 for caracter in expresie:
   if caracter not in caractere_permise and not caracter.isdigit():
     return False
 return True

def evaluare_expresie(expresie):

 stiva = []
 numar = 0
 for caracter in expresie:
   if caracter == 'I':
     numar += 1
   elif caracter == '+':
     stiva.append(numar)
     stiva.append('+')
     numar = 0
   elif caracter == '*':
     stiva.append(numar)
     stiva.append('*')
     numar = 0
   elif caracter.isdigit():
     numar = numar * 10 + int(caracter)
 # Adăugăm ultimul număr la stivă
 stiva.append(numar)
 rezultat = 0
 operatie = '+'
 while stiva:
   element = stiva.pop()
   if isinstance(element, int):
     if operatie == '+':
       rezultat += element
     elif operatie == '*':
       rezultat *= element
   else:
     operatie = element
 return rezultat

def main():

 with open("betisoare.in", "r") as f:
   n = f.readline().strip()
   try:
     n = int(n)
   except ValueError:
     with open("betisoare.out", "w") as fout:
       fout.write("Date de intrare invalide!\n")
     return
   expresii = [f.readline().strip() for _ in range(n)]
 rezultate = []
 for expresie in expresii:
   if not verificare_date_intrare(expresie):
     rezultate.append("Date invalide")
     continue
   rezultat = evaluare_expresie(expresie)
   rezultate.append(rezultat)
 with open("betisoare.out", "w") as f:
   for rezultat in rezultate:
     f.write(str(rezultat) + "\n")

if __name__ == "__main__":

 main()

</syntaxhighlight>