1608 - Sortare Divizori

De la Universitas MediaWiki

Cerinţa

Se dau n numere naturale nenule. Ordonați descrescător cele n numere după numărul lor de divizori.

Date de intrare

Fișierul de intrare sortare_divizoriin.txt conține pe prima linie numărul n, iar pe a doua linie n numere naturale nenule separate prin câte un spațiu.

Date de ieșire

Fișierul de ieșire sortare_divizoriout.txt va conține cele n numere aflate pe a doua linie a fișierului de intrare ordonate descrescător după numărul de divizori.

Restricţii şi precizări

  • 1 ≤ n ⩽ 1.000
  • numerele de pe a doua linie a fișierului de intrare vor fi mai mici decât 1.000.000.000
  • dacă există mai multe numere care au același număr de divizori, acestea vor fi ordonate crescător


Exemplul 1

sortare_divizoriin.txt
5
12 20 4 100 13
sortare_divizoriout.txt
Datele de intrare respectă cerințele impuse.
100 12 20 4 13

Explicație

12 are 6 divizori, 20 are 6 divizori, 4 are 3 divizori, 100 are 9 divizori, 13 are 2 divizori, 12 și 20 au același număr de divizori. Așadar ordinea va fi 100 12 20 4 13.

Exemplul2

sortare_divizoriin.txt
5
12 20 4 100 1000000001
sortare_divizoriout.txt
Datele de intrare nu respectă cerințele impuse.


Rezolvare

 def numar_divizori(numar):
    divizori = 0
    for i in range(1, numar + 1):
        if numar % i == 0:
            divizori += 1
    return divizori

def sortare_divizori(n, numere):
    # Calculează numărul de divizori pentru fiecare număr și creează o listă de tupluri (număr, număr_divizori)
    numere_divizori = [(nr, numar_divizori(nr)) for nr in numere]

    # Sortează lista de tupluri în funcție de numărul de divizori descrescător și apoi după valoarea numărului crescător
    numere_divizori.sort(key=lambda x: (-x[1], x[0]))

    return [nr for nr, _ in numere_divizori]

def main():
    try:
        with open("sortare_divizoriin.txt", "r", encoding="utf-8") as f:
            n = int(f.readline())
            if not 1 <= n <= 1000:
                raise ValueError
            numere = list(map(int, f.readline().split()))
            if not all(1 <= nr < 1000000000 for nr in numere):
                raise ValueError

        with open("sortare_divizoriout.txt", "w", encoding="utf-8") as f_out:
            f_out.write("Datele de intrare respectă cerințele impuse.\n")

            rezultat = sortare_divizori(n, numere)
            f_out.write(" ".join(map(str, rezultat)))
    except Exception as e:
        with open("sortare_divizoriout.txt", "w", encoding="utf-8") as f_out:
            f_out.write(f"Datele de intrare nu respectă cerințele impuse.")

if __name__ == "__main__":
    main()