Проверка_чисел_такси.py 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. import tkinter as tk
  2. from tkinter import messagebox
  3. import sqlite3
  4. import math
  5. class TaxicabFinder:
  6. def __init__(self, window):
  7. self.window = window
  8. self.window.title("Проверка чисел Такси")
  9. self.window.geometry("500x300")
  10. # Создание элементов интерфейса
  11. self.info_label = tk.Label(
  12. window,
  13. text="Проверить, можно ли представить число как сумму кубов двумя разными способами",
  14. wraplength=400,
  15. justify="center"
  16. )
  17. self.info_label.pack(pady=10)
  18. # Поле для ввода числа
  19. self.input_frame = tk.Frame(window)
  20. self.input_frame.pack(pady=10)
  21. self.input_label = tk.Label(self.input_frame, text="Введите число для проверки:")
  22. self.input_label.pack(side=tk.LEFT, padx=5)
  23. self.number_entry = tk.Entry(self.input_frame, width=15)
  24. self.number_entry.pack(side=tk.LEFT, padx=5)
  25. self.number_entry.bind('<Return>', lambda event: self.check_number()) # Поиск по Enter
  26. # Кнопки
  27. self.button_frame = tk.Frame(window)
  28. self.button_frame.pack(pady=10)
  29. self.check_button = tk.Button(
  30. self.button_frame,
  31. text="Проверить число",
  32. command=self.check_number,
  33. bg="lightblue"
  34. )
  35. self.check_button.pack(side=tk.LEFT, padx=5)
  36. self.find_button = tk.Button(
  37. self.button_frame,
  38. text="Найти следующее число Такси",
  39. command=self.find_next_taxicab,
  40. bg="lightgreen"
  41. )
  42. self.find_button.pack(side=tk.LEFT, padx=5)
  43. # Область вывода результатов
  44. self.output_label = tk.Label(window, text="Результат: ", wraplength=450, justify="left")
  45. self.output_label.pack(pady=10)
  46. # История поиска
  47. self.history_label = tk.Label(window, text="История найденных чисел:", font=("Arial", 10, "bold"))
  48. self.history_label.pack(pady=(20, 5))
  49. self.history_text = tk.Text(window, height=6, width=60)
  50. self.history_text.pack(pady=5)
  51. # Подготовка базы данных
  52. self.setup_database()
  53. # Загрузка истории
  54. self.load_history()
  55. def setup_database(self):
  56. """Настройка базы данных для хранения результатов"""
  57. self.db_connection = sqlite3.connect('taxicab_results.db')
  58. self.db_cursor = self.db_connection.cursor()
  59. self.db_cursor.execute('''
  60. CREATE TABLE IF NOT EXISTS found_numbers (
  61. id INTEGER PRIMARY KEY AUTOINCREMENT,
  62. taxicab_number INTEGER,
  63. first_num1 INTEGER, first_num2 INTEGER,
  64. second_num1 INTEGER, second_num2 INTEGER
  65. )
  66. ''')
  67. self.db_connection.commit()
  68. def check_number(self):
  69. """Проверка введенного числа"""
  70. try:
  71. number = int(self.number_entry.get())
  72. if number <= 0:
  73. messagebox.showerror("Ошибка", "Пожалуйста, введите положительное число")
  74. return
  75. except ValueError:
  76. messagebox.showerror("Ошибка", "Пожалуйста, введите целое число")
  77. return
  78. # Поиск представлений числа как суммы двух кубов
  79. representations = self.find_cube_representations(number)
  80. if len(representations) >= 2:
  81. # Нашли число Такси
  82. result_text = f" Число {number} ЯВЛЯЕТСЯ числом Такси!\n\n"
  83. for i, (a, b) in enumerate(representations[:2], 1):
  84. result_text += f" Способ {i}: {a}³ + {b}³ = {a**3} + {b**3} = {a**3 + b**3}\n"
  85. # Сохраняем в базу данных
  86. self.save_result(number, representations[0], representations[1])
  87. self.output_label.config(text=result_text, fg="green")
  88. else:
  89. # Не нашли достаточно представлений
  90. if len(representations) == 1:
  91. result_text = f" Число {number} можно представить как сумму кубов только одним способом:\n"
  92. a, b = representations[0]
  93. result_text += f"{a}³ + {b}³ = {a**3} + {b**3} = {number}"
  94. else:
  95. result_text = f" Число {number} НЕЛЬЗЯ представить как сумму двух кубов"
  96. self.output_label.config(text=result_text, fg="red")
  97. # Обновляем историю
  98. self.load_history()
  99. def find_cube_representations(self, number):
  100. """Найти все представления числа как суммы двух кубов"""
  101. representations = []
  102. max_cube = int(round(number ** (1/3))) + 1
  103. for a in range(1, max_cube + 1):
  104. a_cube = a ** 3
  105. if a_cube > number:
  106. continue
  107. remaining = number - a_cube
  108. b = round(remaining ** (1/3))
  109. if b >= a and b ** 3 == remaining: # b >= a, чтобы избежать дубликатов
  110. representations.append((a, b))
  111. return representations
  112. def find_next_taxicab(self):
  113. """Найти следующее число Такси (автоматический поиск)"""
  114. self.output_label.config(text="Поиск следующего числа Такси...", fg="blue")
  115. self.window.update()
  116. found_numbers = self.get_existing_numbers()
  117. current_number = max(found_numbers) + 1 if found_numbers else 1
  118. while True:
  119. representations = self.find_cube_representations(current_number)
  120. if len(representations) >= 2:
  121. # Нашли число Такси
  122. result_text = f" Найдено число Такси: {current_number}\n\n"
  123. for i, (a, b) in enumerate(representations[:2], 1):
  124. result_text += f" Способ {i}: {a}³ + {b}³ = {a**3} + {b**3} = {a**3 + b**3}\n"
  125. # Сохраняем в базу данных
  126. self.save_result(current_number, representations[0], representations[1])
  127. self.output_label.config(text=result_text, fg="green")
  128. self.number_entry.delete(0, tk.END)
  129. self.number_entry.insert(0, str(current_number))
  130. # Обновляем историю
  131. self.load_history()
  132. break
  133. current_number += 1
  134. # Защита от бесконечного цикла (на всякий случай)
  135. if current_number > 10**7:
  136. messagebox.showwarning("Прервано", "Поиск прерван на большом числе")
  137. self.output_label.config(text="Поиск прерван", fg="orange")
  138. break
  139. def get_existing_numbers(self):
  140. """Получить список уже найденных чисел из базы данных"""
  141. self.db_cursor.execute("SELECT taxicab_number FROM found_numbers")
  142. return [row[0] for row in self.db_cursor.fetchall()]
  143. def save_result(self, number, first_pair, second_pair):
  144. """Сохранение найденного числа в базу данных"""
  145. # Проверяем, нет ли уже этого числа в базе
  146. self.db_cursor.execute("SELECT id FROM found_numbers WHERE taxicab_number = ?", (number,))
  147. if not self.db_cursor.fetchone():
  148. self.db_cursor.execute('''
  149. INSERT INTO found_numbers (taxicab_number, first_num1, first_num2, second_num1, second_num2)
  150. VALUES (?, ?, ?, ?, ?)
  151. ''', (number, first_pair[0], first_pair[1], second_pair[0], second_pair[1]))
  152. self.db_connection.commit()
  153. def load_history(self):
  154. """Загрузка истории найденных чисел"""
  155. self.db_cursor.execute('''
  156. SELECT taxicab_number, first_num1, first_num2, second_num1, second_num2
  157. FROM found_numbers
  158. ORDER BY taxicab_number
  159. ''')
  160. results = self.db_cursor.fetchall()
  161. self.history_text.delete(1.0, tk.END)
  162. if not results:
  163. self.history_text.insert(tk.END, "История пуста")
  164. return
  165. for row in results:
  166. number, a1, b1, a2, b2 = row
  167. history_line = f"{number} = {a1}³ + {b1}³ = {a2}³ + {b2}³\n"
  168. self.history_text.insert(tk.END, history_line)
  169. def close_connection(self):
  170. """Закрытие соединения с базой данных"""
  171. if hasattr(self, 'db_connection'):
  172. self.db_connection.close()
  173. if __name__ == "__main__":
  174. main_window = tk.Tk()
  175. app = TaxicabFinder(main_window)
  176. main_window.mainloop()
  177. app.close_connection()