Ga naar hoofdinhoud

Cheatsheet — Torens van Hanoi

Snelle referentie. Klap open wat je nodig hebt.

De drie regels

Wat mag wel en niet?
  1. Eén schijf per keer verplaatsen.
  2. Alleen de bovenste schijf van een paal.
  3. Nooit een grotere schijf op een kleinere.

Doel: verplaats de hele stapel van de bron-paal naar de doel-paal.

De oplossing

De functie die de zetten teruggeeft
def hanoi(n, bron, doel, hulp):
if n == 0:
return []
zetten = []
zetten += hanoi(n - 1, bron, hulp, doel) # n-1 naar de hulp-paal
zetten.append((bron, doel)) # grootste schijf naar doel
zetten += hanoi(n - 1, hulp, doel, bron) # n-1 op hun plek
return zetten
Alleen het aantal zetten
def tel_zetten(n):
if n == 0:
return 0
return 2 * tel_zetten(n - 1) + 1

Het recursieve recept

Drie stappen + basisgeval

Om n schijven van bron naar doel te verplaatsen:

  1. verplaats n − 1 schijven van bron naar hulp;
  2. verplaats de grootste schijf van bron naar doel;
  3. verplaats n − 1 schijven van hulp naar doel.

Basisgeval: bij n == 0 is er niets te doen. Zonder basisgeval stopt de recursie nooit (RecursionError).

In stap 1 en 3 wisselen hulp en doel van plek in de recursieve aanroep.

Aantal zetten

Waarom 2ⁿ − 1?

Elke oplossing doet twee keer een kleiner probleem plus één losse zet:

T(n) = 2 · T(n − 1) + 1 met T(0) = 0

Uitgerold tot het basisgeval:

T(n) = 2·T(n−1) + 1
= 4·T(n−2) + 3
= 8·T(n−3) + 7
= …
= 2ⁿ·T(0) + (2ⁿ − 1) = 2ⁿ − 1

Voor 1, 2, 3, 4, ... schijven dus 1, 3, 7, 15, ... Elke schijf erbij verdubbelt het werk, ongeveer. Dit is het minimum; met drie palen kan het niet sneller.

Veelgemaakte fouten

Top-3 fouten
  1. Basisgeval vergeten → RecursionError.
  2. hulp en doel verwisseld in de recursieve call → de test voor 2 schijven faalt, de grootste schijf komt bovenop de kleinste.
  3. append in plaats van += bij de recursieve aanroep → een lijst ín de lijst.

Begrippen

Recursie, basisgeval, recurrence
  • Recursie: een functie die zichzelf aanroept op een kleiner stuk van het probleem.
  • Basisgeval: het kleinste geval, dat je direct beantwoordt zonder nieuwe aanroep. Het zorgt dat de recursie stopt.
  • Recurrence: een formule die de kosten van n uitdrukt in de kosten van een kleiner probleem, hier T(n) = 2·T(n−1)+1.