Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование.Python.8-10.docx
Скачиваний:
2
Добавлен:
01.07.2025
Размер:
1.2 Mб
Скачать

Ханойские башни

Другой классической задачей, решаемой при помощи рекурсии, является задача о Ханойских башнях. Головоломка “Ханойские башни” состоит из трех стержней, пронумерованных числами 1, 2, 3. На стержень 1 надета пирамидка из n дисков различного диаметра в порядке возрастания диаметра. Диски можно перекладывать с одного стержня на другой строго по одному, при этом диск нельзя класть на диск меньшего диаметра. Необходимо переложить всю пирамидку со стержня 1 на стержень 3 <b>за минимальное число перекладываний</b>.

Необходимо написать программу, которая для данного числа дисков n печатает последовательность перекладываний, необходимую для решения головоломки.

Сначала нужно подумать, как переложить пирамидку из n дисков с одного стержня на другой. Для этого нужно прежде всего перенести самый большой диск. Но чтобы перенести этот диск нужно всю пирамидку без этого диска, то есть пирамидку из n−1 диска перенести на третий стержень, затем перенести один самый большой диск, затем перенести пирамидку из n−1 диска на тот стержень, на который переместили самый большой диск.

Напишем рекурсивную функцию move(n, start, finish), которая печатает последовательность перекладываний, необходимых для перемещения пирамидки из n дисков со стержня номер start на стержень номер finish. Простой случай — n==1, в этом случае рекурсия не нужна и нужно просто переместить один диск.

def move(n, start, finish):     if n == 1:         print("Перенести диск 1 со стержня", start, "на стержень", finish)     else:         temp = 6 — start — finish # Вспомогательный колышек         move(n — 1, start, temp)         print("Перенести диск", n, "со стержня", start, "на стержень", finish)         move(n — 1, temp, finish) # Для решения головоломки из 10 дисков вызываем так: move(10, 1, 3)

Решение можно сделать проще, если понять, что крайний случай — это случай n==0, в этом случае для перемещения пирамидки из 0 дисков… просто ничего не нужно делать!

def move(n, start, finish):     if n > 0:         temp = 6 — start — finish # Вспомогательный колышек         move(n — 1, start, temp)         print("Перенести диск", n, "со стержня", start, "на стержень", finish)         move(n — 1, temp, finish)

Ограничение на глубину рекурсии

По умолчанию глубина рекурсии в языке Питон ограничена 1000 вызовов. Это ограничение можно поднять при помощи функции  setrecursionlimit из модуля system. Например, чтобы увеличить возможную глубину рекурсии до 10000 нужно в начале программы выполнить две инструкции:

import sys sys.setrecursionlimit(10000)

Следует учитывать, что глубину рекурсии нельзя увеличивать до очень большого значения, помимо ограничения, который устанавливается при помощи setrecursionlimit есть и ограничения операционной системы.

Объект map в Python

Если необходимо обработать каждый элемент списка, это можно сделать в цикле, например:

for i in s:     t[i] = int(s[i])

А можно воспользоваться специальной функцией map, которой передается два параметра — функция, которая будет применена к каждому элементу, и список (или другой итерируемый объект), к элементам которого будет применяться эта функция. На самом деле map — это объект, который можно в дальнейшем преобразовать в список, или использовать непосредственно как итератор (например, в цикле for).

s = map(int, t) 

Вот несколько типичных примеров использования map:

s = list(map(int, input().split()))

a, b = map(float, input().split())

map часто использую с lambda-функциями:

t = list(map(lambda x: x[0], s)) # взять первый символ каждой строки

lambda-функции в Python

lambda-выражения используются для создания однострочных функций, как правило с целью их моментального и единоразового использования, например, как аргумента функций  sort, map и т.п.

Синтаксис:  lambda параметр 1, параметр 2, … : выражение

ПРИМЕРЫ

f = lambda x, y: x * x + y * y f(2, 3) s.sort(key=lambda x: x[-1]) # сортировка по последней букве s = list(map(lambda x: x - 1, s)) # уменьшить все числа на 1

Передача функции как аргумента в Python

В Python функции являются такими же объектами, как строки, числа, списки: их можно присваивать переменным, хранить в списках и даже передавать как параметр функции.

ПРИМЕР

def apply(func, number1, number2):     return func(number1, number2)

print(apply(max, 1, 2), apply(lambda x, y: x - 2 * y, 100, 10))

Типичный пример использование такой возможности —  функция sort, принимающая функцию в качестве параметра key, и функция map, принимающая в качестве первого параметра функцию, которую нужно применить к каждому элементу второго аргумента map:

s.sort(key=abs) # отсортировать числа по абсолютному значению

s = list(map(int, input().split()))