Форум программистов, компьютерный форум, киберфорум
Python: Tkinter
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
2 / 1 / 1
Регистрация: 20.01.2023
Сообщений: 63

Модифицированная задача о Ханойских башнях

19.12.2024, 03:53. Показов 1244. Ответов 0

Студворк — интернет-сервис помощи студентам
Не получается реализовать визуальное перемещение дисков, как сделать так, чтобы при нажатии на кнопки итераций они передвигались. И правильно ли считается общее количество проделанных итераций для перемещения всех дисков на шпиндель один. Помогите пожалуйста, месяц уже голову ломаю. Дайте ответ пожалуйста кодом

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import tkinter as tk
import random
 
 
class HanoiTowerApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Hanoi Tower Visualization")
 
        # Инициализация состояний для каждой итерации
        self.iteration_states = {
            0: {8: [89, 79, 69, 59, 49, 39, 29], 7: [], 6: [69], 5: [89, 79, 69, 59, 49, 39, 29, 19, 9],
                4: [79, 69, 59, 49, 39, 29, 19, 9], 3: [69], 2: [79, 69], 1: []},
            25: {8: [89, 79, 69, 59], 7: [49, 39, 29], 6: [69], 5: [89, 79, 69, 59, 49, 39, 29, 19, 9],
                 4: [79, 69, 59, 49, 39, 29, 19, 9], 3: [69], 2: [79, 69], 1: []},
            50: {8: [89, 79], 7: [69, 59], 6: [49, 39], 5: [89, 79, 69, 59, 49, 39, 29, 19, 9],
                 4: [79, 69, 59, 49, 39, 29, 19, 9], 3: [69], 2: [79, 69], 1: []},
            75: {8: [89], 7: [79], 6: [69], 5: [59], 4: [49], 3: [39], 2: [79, 69], 1: []},
            100: {1: [89, 79, 69, 59, 49, 39, 29], 2: [], 3: [], 4: [], 5: [], 6: [], 7: [], 8: []}
        }
 
        # Изначально отображаем состояние на первой итерации
        self.spindles = self.iteration_states[0]
 
        # Создание холста для отображения башен
        self.canvas = tk.Canvas(self.root, width=1280, height=480, bg="white")
        self.canvas.grid(row=0, column=0, padx=20, pady=10)
 
        # Отображение начальной конфигурации
        self.display_towers()
 
        # Для отображения текста итерации
        self.iteration_text = None
 
        # Добавление переменной для отслеживания сделанных итераций
        self.iteration_count = 0  # Количество итераций
 
        # Создание контейнера для ввода процентов и кнопок
        self.percent_frame = tk.Frame(self.root)
        self.percent_frame.grid(row=1, column=0, pady=10)
 
        # Ввод для промежуточных процентов
        self.percent_labels = []
        default_percentages = [70, 19, 81, 20]
        for i in range(4):
            label = tk.Label(self.percent_frame, text=f"Процент {i + 1}:")
            label.grid(row=0, column=i * 2)
            entry = tk.Entry(self.percent_frame)
            entry.insert(tk.END, str(default_percentages[i]))  # Установка дефолтных значений
            entry.grid(row=0, column=i * 2 + 1)
            self.percent_labels.append(entry)
 
        # Кнопки для отображения начальной и конечной итерации
        self.buttons_frame = tk.Frame(self.root)
        self.buttons_frame.grid(row=2, column=0, pady=10)
 
        self.buttons = [
            tk.Button(self.buttons_frame, text="Начало", command=self.show_start),
            tk.Button(self.buttons_frame, text="Окончание", command=self.show_end),
        ]
        for btn in self.buttons:
            btn.grid(row=0, column=self.buttons.index(btn), padx=10)
 
        # Кнопки для отображения промежуточных итераций
        self.iteration_buttons = []
        for i in range(4):
            button = tk.Button(self.percent_frame, text=f"П. {i + 1}", command=lambda i=i: self.show_iteration(i))
            button.grid(row=1, column=i * 2 + 1, padx=10)
            self.iteration_buttons.append(button)
 
    def display_towers(self):
        self.canvas.delete("all")  # Очистить холст
        spindle_positions = [100, 200, 300, 400, 500, 600, 700, 800]
 
        # Рисуем все шпиндели (с 8 до 1)
        for i in range(8, 0, -1):
            self.draw_spindle(spindle_positions[8 - i], i)
            self.draw_disks(spindle_positions[8 - i], self.spindles[i])
 
    def draw_spindle(self, x, number):
        # Рисуем сам шпиндель
        self.canvas.create_line(x, 50, x, 400, width=4)
        self.canvas.create_text(x, 30, text=f"Шпиндель {number}")
 
    def draw_disks(self, x, disks):
        if not disks:  # Если на шпинделе нет дисков
            return
        # Рисуем диски на шпинделе
        num_disks = len(disks)
        for i, disk in enumerate(disks):
            # Номер диска сверху вниз: сверху диск будет номером 1
            disk_number = num_disks - i  # Номер диска сверху вниз
            spindle_number = 8 - (x // 100) + 1  # Номер шпинделя (от 8 до 1)
 
            # Правильное вычисление диаметра: M * 10 + N
            diameter = spindle_number * 10 + disk_number  # Формула для диаметра
 
            color = f"#{random.randint(0, 0xFFFFFF):06x}"  # Случайный цвет
            # Рисуем диск
            self.canvas.create_rectangle(x - diameter / 2, 350 - i * 30, x + diameter / 2, 370 - i * 30, fill=color)
            self.canvas.create_text(x, 360 - i * 30, text=str(diameter), fill="white")
            # Добавляем номер диска слева
            self.canvas.create_text(x - diameter / 2 - 10, 360 - i * 30, text=str(disk_number), fill="black")
 
    def show_start(self):
        # Начальная конфигурация
        self.spindles = self.iteration_states[0]
        self.display_towers()
        self.update_iteration_text("Итерация 0")  # Обновляем текст на "Итерация 0"
 
    def show_end(self):
        # Конечная конфигурация
        self.spindles = self.iteration_states[100]
        self.display_towers()
        self.show_iterations_count()
 
    def show_iteration(self, iteration_index):
        # Получаем процент выполнения для итерации
        try:
            percentage = int(self.percent_labels[iteration_index].get())
        except ValueError:
            return
 
        # Вычисляем номер итерации на основе процента
        total_iterations = 100  # Общее количество итераций
        iteration_number = (percentage * total_iterations) // 100
 
        # Используем заранее подготовленное состояние для итерации
        self.spindles = self.iteration_states.get(iteration_number, self.iteration_states[0])
        self.display_towers()
        self.update_iteration_text(f"Итерация {iteration_number}")  # Обновляем текст
 
    def update_iteration_text(self, text):
        # Удаляем старую надпись и рисуем новую
        if self.iteration_text:
            self.canvas.delete(self.iteration_text)
        self.iteration_text = self.canvas.create_text(640, 420, text=text, font=("Arial", 14, "bold"))
 
    def show_iterations_count(self):
        # Общее количество шагов для задачи Ханои с 8 дисками
        total_steps = (2 ** 8) - 1  # Для 8 дисков общее количество шагов = 255
 
        # Получаем проценты для каждой итерации и вычисляем количество шагов
        total_iterations = 0
        for entry in self.percent_labels:
            try:
                percent = int(entry.get())  # Читаем процент из поля ввода
                iteration_steps = (percent * total_steps) // 100  # Преобразуем процент в шаги
                total_iterations += iteration_steps  # Добавляем шаги для текущего процента
            except ValueError:
                continue  # Если введено некорректное значение, пропускаем
 
        # Отображаем количество итераций на экране
        self.canvas.create_text(640, 450, text=f"Общее количество итераций: {total_iterations}",
                                font=("Arial", 14, "bold"))
 
 
root = tk.Tk()
app = HanoiTowerApp(root)
root.mainloop()

Сама задача:
Существует 8 шпинделей, пронумерованных от 8 до 1 справа налево. На каждом шпинделе надеты диски, в количестве, равном соответствующей цифре 70198120. Все диски имеют разные диаметры. Диаметр диска равен M * 10 + N, где М – номер шпинделя, на котором надет диск, а N – это номер диска на шпинделе, считая сверху вниз.
Необходимо визуально изобразить предложенную задачу.
Диски на шпинделях сделать случайных цветов. На каждом диске отображать цифру, равную его диаметру. Диаметр диска также показывать его фактическим размером в пикселях.
Необходимо вычислить, за какое минимальное количество итераций переместятся все диски на шпиндель номер 1 по следующим правилам:

• За одну итерацию можно переместить один диск;
• диски можно класть только с большего на меньший;
• cо шпинделя номер 8 можно перекладывать диски только на шпиндели 7 и 6;
• cо шпинделя 1 можно перекладывать диски только на шпиндели номер 2 и 3;
• cо шпинделей от 2 по 7 можно перекладывать диски только на два соседних шпинделя.

Необходимо отобразить начальное и конечное расположение дисков на шпинделях, для этого под изображением Ханойских башен предусмотреть две кнопки «Начало» и «Окончание». При нажатии на нее, в надписи под схемой должен выводится текст «Итерация ХХ», где ХХ – номер итерации (либо 0, либо номер итоговой итерации, соответственно).
Необходимо графически отобразить четыре промежуточные итерации перекладывания дисков. Для этого:
a. общее количество итераций признаётся равным 100%;
b. 70198120 делится на 4 двузначных числа, каждое из которых обозначает итерацию, соответствующую этому проценту выполнения общей задачи.

Под изображением Ханойских башень предусмотреть четыре поля для ввода цифр с процентами выполнения. По-умолчанию добавить туда числа 70198120
Под каждым полем для ввода предусмотреть кнопку, при нажатии на которую схема Ханойской башни отображает расположение дисков на соответствующей итерации. Также в надписи под схемой должен выводится текст «Итерация ХХ», где ХХ – номер итерации.
Дать возможность пользователю изменять проценты в полях для ввода цифр, и по нажатию соответствующей кнопки просматривать расположение дисков на данной итерации.

Основная часть работы над задачей сводится к правильной визуализации полученных результатов, а также оптимальному поиску промежуточных результатов.

Так как размер диска должен соответствовать его номеру на шпинделе и номеру самого шпинделя, умноженного на 10, то максимальный диаметр диска может быть 89. Поэтому для правильной визуализации без наложения дисков рекомендуется выдерживать расстояние между шпинделями примерно в 100-120 пикселей (для окна формата 1280х1024).

Поскольку диски близких размеров будут отличаться всего на один пиксель, то для контроля на каждом диске необходимо проставить его диаметр в виде цифры. Так как в конце задачи все диски будут находиться на первом шпинделе, а общее количество дисков теоретически может быть равно 72, то рекомендуется сделать толщину одного диска примерно равной 10-12 пикселям, для указанного окна.

Остальные элементы управления под схемой Ханойской башни рекомендуется выстраивать при нажатии на кнопки, нужно показать итерации, соответствующие 70%, 19%, 81% и 20% выполнения задачи.


Если по какому-либо проценту получается дробная итерация, то необходимо её визуализировать как промежуточный этап переноса диска. При этом диск изобразить в воздухе, между тем шпинделем, с которого он снят, и тем, на который он переносится. Номер итерации в таком случае отображать как дробный, с округлением до 3 цифр после нуля.


Входные данные:
Номер из 8 цифр, промежуточные проценты, вводимые в соответствующие поля над кнопками.

Выходные данные:
На цифровом дисплее должно отображаться окно с начальным расположением дисков на шпинделях Ханойских башень. Шпиндели пронумерованы, на дисках также обозначены соответствующие диаметры. Под ней отображается шесть кнопок и четыре поля для ввода цифр. В нижней части экрана демонстрируется надпись «Итерация 0».
При нажатии на любую из шести имеющихся кнопок, либо при заполнении поля ввода другими данными и нажатии на кнопку, схема ханойских башень меняется, для отображения соответствующей итерации.
Надпись в нижней части экрана также меняется.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
19.12.2024, 03:53
Ответы с готовыми решениями:

Модифицированная задача о Ханойских башнях
Здравствуйте, прошу помочь в данном вопросе сижу уже неделю так и не могу понять Существует 8 шпинделей, пронумерованых от 8 до 1...

Задача о Ханойских башнях
#include <iostream> #include <iomanip> using namespace std; //------------------------ void tower(int, int, int, int); //...

Задача о Ханойских башнях
Доброго времени суток! Мне нужно решить задачу о "Ханойских башнях" с помощью рекурсии. Одно из заданий прошу помочь реализовать:...

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
19.12.2024, 03:53
Помогаю со студенческими работами здесь

задача о Ханойских башнях
Составьте функцию, решающую задачу о Ханойских башнях.

Модифицированния задача о ханойских башнях
Здравствуйте, уже часа два бьюсь над решением этой задачи: Существует 8 шпинделей, пронумерованных от 8 до 1 слева направо. На каждом...

Задача о ханойских башнях на си через стек
Написать нерекурсивное решение задачи о ханойских башнях через стек отложенных заданий, элементами которого будут тройки (i,m,n). (...

Задача о "Ханойских башнях" на Haskell
Добрый день! Помогите, пожалуйста, реализовать алгоритм решения задачи "Ханойские башни" на языке Haskell. Смысл задачи заключается...

Нерекурсивное решение в Ханойских башнях
помогите решить задачу.... Разработать нерекурсивный алгоритм решения задачи о ханойских башнях. На языке программирования Pascal...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru