0853 - Cadouri

De la Universitas MediaWiki

Cerinţa

Elevii clasei a X-a s-au implicat în strângerea de cadouri pentru Crăciun. Fiecare elev a adus mai multe cadouri, și a trimis prin email șefului clasei o urare, însoțită de lista cadourilor. Fiecare email are forma: urare lista_cadouri urare este un text care nu conţine cifre. Lista cadourilor constă într-o enumerare a cadourilor: numar_cadouri denumire_cadou (numar_cadouri este un număr natural, iar denumire_cadou este un cuvânt scris cu litere mici ale alfabetului englez; numar_cadouri şi denumire_cadou sunt separate prin cel puţin un spaţiu), cadourile din listă fiind separate prin spaţii şi/sau diverse semne de punctuaţie

Şeful clasei trebuie să centralizeze listele primite. Ajutaţi-l să construiască o listă a care să conţină denumirea fiecărui cadou şi numărul total de cadouri de acel tip (cantitatea). Lista va fi ordonată descrescător după cantitate.


Date de intrare

Fișierul de intrare cadouriin.txt conține pe prima linie numărul n de elevi din clasa a X-a; fiecare dintre următoarele n linii, conţine câte un email.

Date de ieșire

Fișierul de ieșire cadouriout.txt va conține pe prima linie numărul de cadouri diferite C; următoarele C linii vor conţine câte un cadou şi cantitatea totală, separate prin exact un spaţiu. Lista cadouri va fi ordonată descrescător după cantitate. Dacă există mai multe cadouri cu aceeaşi cantitate, se va afişa mai întâi cadoul cu denumirea mai mică din punct de vedere lexicografic.

Restricţii şi precizări

  • 1 ⩽ n ⩽ 100
  • fiecare linie a fişierului de intrare conţine cel mult 255 caractere
  • sunt cel mult 500 de cadouri diferite cu denumirea de cel mult 20 de litere ale afabetului englez
  • cantitatea din fiecare cadou este cel mult 100.000

Exemplu 1

cadouriin.txt
3
La multi ani! 4 papusi, 15 ciocolate , 20 sosete.
Sarbatori fericite :) ! 3 ciocolate , 10 biscuiti, 5 papusi
Salut. 2 ciocolate , 1 papusi. 1 ciocolate!
cadouriout.txt
Datele de intrare corespund restrictiilor impuse
4
ciocolate 21
sosete 20
biscuiti 10
papusi 10


Exemplu 2

cadouriin.txt
1000
La multi ani! 40 ab, 15 ciocolate , 20 sosete.
Sarbatori fericite :) ! 3 ciocolateciocolateciocolate , 10 biscuiti, 5 papusi
Salut. 2 ciocolate , 1 papusi. 1 ciocolate!
cadouriout.txt
Datele de intrare nu corespund restrictiilor impuse


Rezolvare

import re
from collections import Counter


def process_emails(emails):
    # Funcția procesează emailurile și returnează un dicționar
    # cu denumirea fiecărui cadou și numărul total de cadouri de acel tip.

    gifts = Counter()
    for email in emails:
        # Extragem lista de cadouri din email
        gift_list = re.findall(r'(\d+) (\w+)', email)
        for count, gift in gift_list:
            gifts[gift] += int(count)
    return gifts


def main():
    with open('cadouriin.txt', 'r') as fin, open('cadouriout.txt', 'w') as fout:
        n = int(fin.readline().strip())
        emails = [fin.readline().strip() for _ in range(n)]

        # Verificăm dacă emailurile respectă restricțiile
        if len(emails) > 100 or any(len(email) > 255 for email in emails):
            fout.write("Datele de intrare nu corespund restrictiilor impuse\n")
            return

        fout.write("Datele de intrare corespund restrictiilor impuse\n")

        # Procesăm emailurile și obținem numărul total de cadouri de fiecare tip
        gifts = process_emails(emails)

        # Sortăm cadourile în ordine descrescătoare a numărului de cadouri și lexicografică
        sorted_gifts = sorted(gifts.items(), key=lambda x: (-x[1], x[0]))

        # Scriem numărul de cadouri diferite și lista de cadouri în fișierul de ieșire
        fout.write(str(len(sorted_gifts)) + '\n')
        for gift, count in sorted_gifts:
            fout.write(f'{gift} {count}\n')


if __name__ == "__main__":
    main()