avp26/u8/program.py
2026-11-03 14:54:10 +00:00

140 lines
4.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import sys
from dataclasses import dataclass
# dátová struktúra pre uzol stromu / датова структура для вузла дерева
@dataclass
class Node:
text: str
left: "Node | None" = None # Vetva 'a' (áno) / Гілка 'a' (так)
right: "Node | None" = None # Vetva 'n' (nie) / Гілка 'n' (ні)
# rekurzívne načítanie bázy znalostí (preorder)
# рекурсивне читання бази знаноь (преордер)
def read_node(lines_iterator):
# Rekurzívne načíta uzol a jeho podstromy vo formáte preorder.
# Рекурсивно зчитує вузол та його піддерева у форматі preorder.
try:
line = next(lines_iterator)
except StopIteration:
raise ValueError("Chýba očakávaný uzol")
# Odstránime iba znaky konca riadka (\n, \r)
# Видаляємо лише символи кінця рядка (\n, \r)
text = line.rstrip("\r\n")
# Kontrola prázdneho riadka na konci bázy
# Перевірка порожнього рядка в кінці бази
if text == "":
raise ValueError("Chýba očakávaný uzol")
node = Node(text=text)
# Ak sa text končí na '?', ide o otázku s dvoma potomkami (ľavý = áno, pravý = nie)
# Якщо текст закінчується на '?', це питання з двома потомками (лівий = так, правий = ні)
if node.text.endswith("?"):
node.left = read_node(lines_iterator)
node.right = read_node(lines_iterator)
return node
# rekurzívne počítanie prvkov bázy
# рекурсивний підрахунок елементів бази
def count_questions(node):
# Spočíta všetky vnútorné uzly (otázky končiace znakom '?').
# Підраховує всі внутрішні вузли (питання, що закінчуються на '?').
if node is None:
return 0
is_question = 1 if node.text.endswith("?") else 0
return is_question + count_questions(node.left) + count_questions(node.right)
def count_answers(node):
# Spočíta všetky listové uzly (konečné odpovede / zvieratá).
# Підраховує всі листові вузли (кінцеві відповіді / звірів).
if node is None:
return 0
if node.left is None and node.right is None:
return 1
return count_answers(node.left) + count_answers(node.right)
# prehľadávanie stromu a dialóg s používateľom
# пошук у дереві та діалог з користувачем
def search(node):
# Prechádza stromom podľa volieb používateľa až po konečnú odpoveď.
# Проходить по дереву відповідно до вибору користувача до кінцевої відповіді.
# Vypíšeme text aktuálneho uzla (otázku alebo zviera)
# Виводимо текст поточного вузла (питання або звіра)
print(node.text)
# Ak sme v liste, našli sme zviera - vypíšeme Koniec a skončíme
# Якщо ми в листі, ми знайшли звіра - виводимо Koniec і завершуємо
if node.left is None and node.right is None:
print("Koniec")
return
# Načítanie voľby používateľa ('a' alebo 'n')
# Зчитування вибору користувача ('a' або 'n')
choice_line = sys.stdin.readline()
if choice_line == "":
return # Neočakávaný koniec vstupu / Несподіваний кінець входу
choice = choice_line.rstrip("\r\n")
# Spracovanie voľby: 'a' ideme vľavo, 'n' ideme vpravo
# Обробка вибору: 'a' перехід ліворуч, 'n' перехід праворуч
if choice == 'a':
search(node.left)
elif choice == 'n':
search(node.right)
else:
# Neplatná voľba ukončí program
# Некоректний вибір завершує програму
return
def main():
# Požadovaný úvodný výpis
# Обов'язковий стартовий вивід
print("Expert zo zoo to vie.")
# Načítanie celého vstupu do iterátora
# Зчитування всього входу в ітератор
lines_iterator = iter(sys.stdin.read().splitlines(keepends=True))
try:
root = read_node(lines_iterator)
except (ValueError, StopIteration):
return
# Výpočet a výpis celkových štatistík bázy
# Підрахунок та вивід загальної статистики бази
q_count = count_questions(root)
a_count = count_answers(root)
print(f"Pocet otazok: {q_count}")
print(f"Pocet odpovedi: {a_count}")
print("Odpovedajte 'a' pre prvu moznost alebo 'n' pre druhu moznost.")
# Spustenie dialógu od koreňa
# Запуск діалогу від кореня
search(root)
if __name__ == "__main__":
main()