import math import csv def max_n_log(time_seconds): # f(n) = log2(n) # czyli log2(n) <= microseconds -> n <= 2^microseconds microseconds = time_seconds * 1_000_000 log10_n = microseconds * math.log10(2) # zeby nie wybuchlo, zapis jako 10^x return f"≈ 10^{log10_n:,.0f}".replace(",", " ") def max_n_linear(time_seconds): # f(n) = n, easy, n <= microseconds microseconds = time_seconds * 1_000_000 return f"{int(microseconds):,}".replace(",", " ") def max_n_nlogn(time_seconds): # f(n) = n * log2(n) # tego nie rozwiazesz recznie, trzeba przyblizenie microseconds = time_seconds * 1_000_000 left, right = 1, 10**18 # na pewno wystarczy lol while left < right: mid = (left + right) // 2 f = mid * math.log2(mid) if f <= microseconds: left = mid + 1 else: right = mid - 1 return f"{left:,}".replace(",", " ") def max_n_quadratic(time_seconds): # f(n) = n^2 -> n <= sqrt(microseconds) microseconds = time_seconds * 1_000_000 n = int(math.sqrt(microseconds)) return f"{n:,}".replace(",", " ") def max_n_cubic(time_seconds): # f(n) = n^3 -> n <= microseconds^(1/3) microseconds = time_seconds * 1_000_000 n = int(round(microseconds ** (1/3))) return f"{n:,}".replace(",", " ") def max_n_exponential(time_seconds): # f(n) = 2^n -> 2^n <= microseconds -> n <= log2(microseconds) microseconds = time_seconds * 1_000_000 n = int(math.log2(microseconds)) return f"{n:,}".replace(",", " ") def max_n_factorial(time_seconds): # f(n) = n! -> n! <= microseconds -> trzeba jechac petla bo inaczej nie policzysz microseconds = time_seconds * 1_000_000 n = 1 fact = 1 while fact <= microseconds: n += 1 fact *= n return f"{n-1:,}".replace(",", " ") # dobra tu ustawiamy czasy czasy = [ ("1 sekunda", 1), ("1 minuta", 60), ("1 godzina", 3600), ("1 dzień", 86400), ("1 miesiąc", 30 * 86400), ("1 rok", 365 * 86400) ] # export to csv using primewriter with open("czasy_transposed.csv", "w", newline="", encoding="utf-8") as f: writer = csv.writer(f) # kolumny: nagłówek z etykietami czasu header = ["label"] + [label for label, _ in czasy] writer.writerow(header) # helper do pisania wiersza def write_row(name, func): row = [name] + [func(seconds) for _, seconds in czasy] writer.writerow(row) # teraz każdy wiersz odpowiada jednej funkcji złożoności writer.writerow(["seconds"] + [seconds for _, seconds in czasy]) write_row("lg(n)", max_n_log) write_row("n", max_n_linear) write_row("n·lg(n)", max_n_nlogn) write_row("n²", max_n_quadratic) write_row("n³", max_n_cubic) write_row("2ⁿ", max_n_exponential) write_row("n!", max_n_factorial) # i lecimy z tabela for label, seconds in czasy: print("================================") print(f"{label.upper()}") # no ładnie niech wygląda print("================================") print(f"lg(n): n ≤ {max_n_log(seconds)}") print(f"n: n ≤ {max_n_linear(seconds)}") print(f"n·lg(n): n ≤ {max_n_nlogn(seconds)}") print(f"n²: n ≤ {max_n_quadratic(seconds)}") print(f"n³: n ≤ {max_n_cubic(seconds)}") print(f"2ⁿ: n ≤ {max_n_exponential(seconds)}") print(f"n!: n ≤ {max_n_factorial(seconds)}") print() # pusta linia zeby nie bolało w oczy # porownaj na wykresie zlozonosci dla osi n / czas import matplotlib.pyplot as plt import numpy as np # dobra, tu robimy dane testowe, bo tych ogromnych liczb i tak nie narysujesz sensownie # weźmy np. n od 1 do 100 (dla 2^n i n!) i do 1e6 (dla n, n^2, n log n) n_linear = np.linspace(1, 1e6, 500) # 500 punktow, wystarczy n_small = np.arange(1, 30) # do wykładniczych # przeliczamy "czas" w mikrosekundach (nie ma znaczenia jednostka, chodzi o kształt) y_log = np.log2(n_linear) y_n = n_linear y_nlogn = n_linear * np.log2(n_linear) y_n2 = n_linear**2 y_n3 = n_linear**3 y_2n = 2**n_small y_fact = [math.factorial(i) for i in n_small] plt.figure(figsize=(10,6)) # rysujemy wykresy — używamy skali log bo inaczej wszystko zniknie xd plt.plot(n_linear, y_log, label='lg(n)') plt.plot(n_linear, y_n, label='n') plt.plot(n_linear, y_nlogn, label='n·lg(n)') plt.plot(n_linear, y_n2, label='n²') plt.plot(n_linear, y_n3, label='n³') plt.plot(n_small, y_2n, label='2ⁿ') plt.plot(n_small, y_fact, label='n!') plt.yscale("log") plt.xscale("log") plt.title("Porównanie złożoności czasowych algorytmów") plt.xlabel("Rozmiar problemu n (skala log)") plt.ylabel("Czas wykonania f(n) (skala log)") plt.legend() plt.grid(True, which="both", linestyle="--", alpha=0.4) # troche marginesu bo n! szybko idzie w kosmos plt.tight_layout() plt.show()