-- tower of hanoi 00010060
-- 00020060
-- 1 1 00030060
-- 222 =====> 222 00040060
-- 33333 33333 00050060
-- *links* *mitte* *rechts* *links* *mitte* *rechts* 00060060
-- 00070060
-- Regeln: immer nur ein Scheibe bewegen, immer auf grössere legen 00080060
-- 00090060
-- Lösung wir benutzen Rekursion mit From, To und Help Stapel 00100061
-- 1: rekursiv die n-1 obersten Scheiben von From auf Help Stapel 00110064
-- 2: die jetzt oberste (ursprünglich n.) Scheibe vom From auf To 00120064
-- 3: (rekursiv) die n-1 obersten Scheiben von Help auf To Stapel 00130064
-- erst am Schluss schauen wir, was Links Mitte und Rechts war 00140064
-- (Trick: zuunterst in jedem Stapel fixe Scheibe l, m, bzw. r) 00141065
-- 00150064
with h (f, t, h, anz, seq, lev) as 00160064
( -- start: 00170064
select cast('123456l' as varchar(9)), 00180064
cast('m' as varchar(9)), 00190064
cast('r' as varchar(9)), 00200064
5, cast('' as varchar(9)), 0 00210064
from sysibm.sysDummy1 00220064
-- Schritt 1 : 00230064
-- rekursiv anz-1 Scheiben von f auf h00240064
union all select f, h, t, anz-1, seq || 'x', lev+1 00250064
from h 00260064
where anz > 1 and lev < 9 00270064
-- Schritt 2+3 : 00280064
-- anz-te Scheibe von f nach t 00290064
-- rekursiv anz-1 Scheiben von h auf t00300064
union all select left(f, anz-1) || h, 00310064
substr(f, anz, 1) || t, 00320064
substr(f, anz+1), 00330064
anz-1, seq || 'y', lev+1 00340064
from h 00350064
where anz > 0 and lev < 9 00360060
) --- f,t,h auf Links Mitte Rechts legen 00370060
, lmr as 00380054
( select case when right(f, 1) = 'l' then f 00390054
when right(t, 1) = 'l' then t 00400054
when right(h, 1) = 'l' then h else '?' end l, 00410054
case when right(f, 1) = 'm' then f 00420054
when right(t, 1) = 'm' then t 00430054
when right(h, 1) = 'm' then h else '?' end m, 00440054
case when right(f, 1) = 'r' then f 00450054
when right(t, 1) = 'r' then t 00460054
when right(h, 1) = 'r' then h else '?' end r, 00470054
h.* 00480037
from h 00490037
) --- l,m,r rechtsbündig anzeigen 00500061
select substr(' ' || l, length(l), 9) l, 00510059
substr(' ' || m, length(m), 9) m, 00520059
substr(' ' || r, length(r), 9) r, 00530059
anz, seq, lev, f, t, h 00540058
from lmr 00550055
where right(seq, 1) <> 'x' 00560053
order by seq 00570037
; 00580062
-- 00590062
-- tower of hanoi 00600061
-- muehsamere Lösung: wir arbeiten mit Links Mitte und Rechts 00610061
-- und müssen in der Rekursion alle Permutationen ausprogrammieren 00620061
-- 00630061
with h (l, m, r, fth, anz, seq, lev) as 00640061
( -- start bewege Turm von links -> Mitte 00650063
select cast('123456' as varchar(9)), 00660037
cast('' as varchar(9)), 00670037
cast('' as varchar(9)), 00680037
'lmr', 4, 00690061
cast('' as varchar(9)), 0 00700037
from sysibm.sysDummy1 00710037
union all select l, m, r , -- Schritt 1 anz-1 Scheiben von f auf h 00720063
translate('132', fth, '123'), 00730037
anz-1, seq || 'x', lev+1 00740037
from h 00750037
where anz > 1 and lev < 9 00760037
-- Schritt f -> t und h -> t für lmr 00770063
union all select substr(l, anz+1), 00780061
substr(l, anz, 1) || m, 00790061
left(l, anz-1) || r, 00800061
00810037
'rml', anz-1, seq || 'y', lev+1 00820061
from h 00830037
where anz > 0 and lev < 9 and fth = 'lmr' 00840061
-- Schritt f -> t und h -> t für lrm 00850063
union all select substr(l, anz+1), 00860061
left(l, anz-1) || m, 00870061
substr(l, anz, 1) || r, 00880061
'mrl', anz-1, seq || 'y', lev+1 00890061
from h 00900037
where anz > 0 and lev < 9 and fth = 'lrm' 00910061
-- Schritt f -> t und h -> t für mlr 00920063
union all select substr(m, anz, 1) || l, 00930061
substr(m, anz+1), 00940061
left(m, anz-1) || r, 00950061
'rlm', anz-1, seq || 'y', lev+1 00960061
from h 00970037
where anz > 0 and lev < 9 and fth = 'mlr' 00980061
-- Schritt f -> t und h -> t für mrl 00990063
union all select left(m, anz-1) || l, 01000061
substr(m, anz+1), 01010061
substr(m, anz, 1) || r, 01020061
'lrm', anz-1, seq || 'y', lev+1 01030061
from h 01040037
where anz > 0 and lev < 9 and fth = 'mrl' 01050061
-- Schritt f -> t und h -> t für rlm 01060063
union all select substr(r, anz, 1) || l, 01070061
left(r, anz-1) || m, 01080061
substr(r, anz+1), 01090061
'mlr', anz-1, seq || 'y', lev+1 01100061
from h 01110037
where anz > 0 and lev < 9 and fth = 'rlm' 01120061
-- Schritt f -> t und h -> t für rml 01130063
union all select left(r, anz-1) || l, 01140061
substr(r, anz, 1) || m, 01150061
substr(r, anz+1), 01160061
'lmr', anz-1, seq || 'y', lev+1 01170061
from h 01180037
where anz > 0 and lev < 9 and fth = 'rml' 01190061
) 01200037
select substr(' ' || l, 1+length(l), 9) l, 01210061
substr(' ' || m, 1+length(m), 9) m, 01220061
substr(' ' || r, 1+length(r), 9) r, 01230061
fth, anz, seq, lev 01240037
from h 01250037
-- where right(seq, 1) <> 'x' 01260041
order by seq 01270037