type Decrease<N extends number, U extends any[] = []> = [...U, any]['length'] extends N ? U['length'] : Decrease<N, [...U, any]>
type Hanoi<N extends number, From = 'A', To = 'B', Intermediate = 'C'> = N extends 0 ? [] : [...Hanoi<Decrease<N>, From, Intermediate, To>, [From, To], ...Hanoi<Decrease<N>, Intermediate, To, From>]
Solution by 2083335157 #34990
type MinusOne<N, Result extends 0[] = []> =
[...Result, 0]['length'] extends N
? Result['length']
: MinusOne<N, [...Result, 0]>
type Hanoi<N extends number, From = 'A', To = 'B', Intermediate = 'C'> =
N extends 0
? []
: N extends 1
? [[From, To]]
: [
...Hanoi<MinusOne<N>, From, Intermediate, To>,
[From, To],
...Hanoi<MinusOne<N>, Intermediate, To, From>
]
Solution by drylint #34195
type Hanoi<N extends number, From = 'A', To = 'B', Temp = 'C', CurIdx extends 0[] = []> =CurIdx['length'] extends N ? [] : [
...Hanoi<N, From, Temp, To, [...CurIdx, 0]>, [From, To], ...Hanoi<N, Temp, To, From, [...CurIdx, 0]>
]
Solution by ouzexi #34174
// Type to simulate the steps required to solve the Tower of Hanoi puzzle for N disks.
// `From`, `To`, and `Intermediate` represent the three rods involved.
type Hanoi<N extends number, From = 'A', To = 'B', Intermediate = 'C'>
= N extends 0 ? [] // Base case: no moves needed for zero disks.
: [
...Hanoi<MinusOne<N>, From, Intermediate, To>,
[From, To],
...Hanoi<MinusOne<N>, Intermediate, To, From>,
]
type MinusOne<N extends number | string, S extends string = `${N}`>
=(S extends `${infer L}0` ? L extends '1' ? '9' : `${MinusOne<L>}9`
: S extends `${infer L}1` ? `${L}0`
: S extends `${infer L}2` ? `${L}1`
: S extends `${infer L}3` ? `${L}2`
: S extends `${infer L}4` ? `${L}3`
: S extends `${infer L}5` ? `${L}4`
: S extends `${infer L}6` ? `${L}5`
: S extends `${infer L}7` ? `${L}6`
: S extends `${infer L}8` ? `${L}7`
: S extends `${infer L}9` ? `${L}8`
: '-1') extends `${infer N extends number}` ? N : never
Solution by teamchong #32993
type Hanoi<
N extends number,
From = "A",
To = "B",
Intermediate = "C"
> = HanoiByArr<NumToArr<N>, From, To, Intermediate>;
type HanoiByArr<
Count extends any[],
From = "A",
To = "B",
Intermediate = "C"
> = Count extends [infer _, ...infer R]
? [
...HanoiByArr<R, From, Intermediate, To>,
[From, To],
...HanoiByArr<R, Intermediate, To, From>
]
: [];
type NumToArr<N extends number, Count extends any[] = []> = number extends N
? []
: N extends Count["length"]
? Count
: NumToArr<N, [...Count, 1]>;
Solution by Vampirelee #32596
type Hanoi<
N extends number,
From = "A",
To = "B",
Intermediate = "C",
C extends 0[] = [0]
> = N extends 0
? []
: C["length"] extends N
? [[From, To]]
: [
...Hanoi<N, From, Intermediate, To, [...C, 0]>,
[From, To],
...Hanoi<N, Intermediate, To, From, [...C, 0]>
];
Solution by vangie #32212
type MakeNumberToArray<T extends number, U extends unknown[] = []> = U['length'] extends T
? U
: MakeNumberToArray<T, [...U, unknown]>;
type Hanoi<
N extends number,
From = 'A',
To = 'B',
Intermediate = 'C',
U extends unknown[] = MakeNumberToArray<N>,
> = U['length'] extends 1
? [[From, To]]
: U extends [unknown, ...infer Rest]
? [...Hanoi<Rest['length'], From, Intermediate, To>, [From, To], ...Hanoi<Rest['length'], Intermediate, To, From>]
: [];
Solution by leejaehyup #30993
type Hanoi<Rings extends number, FromRod extends string = 'A', ToRod extends string = 'B', IntermediateRod extends string = 'C', Acc extends 'πΊπ¦'[] = []> = Acc['length'] extends Rings ? [] : [ ...Hanoi<Rings, FromRod, IntermediateRod, ToRod, [...Acc, 'πΊπ¦']>, [FromRod, ToRod], ...Hanoi<Rings, IntermediateRod, ToRod, FromRod, [...Acc, 'πΊπ¦']> ]
/* We should move disk from rod-A to rod-B using rod-C as a intemediate helper rod. Only one disk at a time. So, I explain on Hanoi<1> example. By default Acc is empty array and it's length 0, so we skip true branch of our comparison and go to false branch.
Solution by ArtDorfman #30769
type Hanoi<N extends number, From = 'A', To = 'B', Intermediate = 'C'> = Helper<N, [], From, To, Intermediate>
type Helper<N extends number, C extends 1[], From extends unknown, To extends unknown, Intermediate extends unknown> = C['length'] extends N
? []
: [...Helper<N, [...C, 1], From, Intermediate, To>, [From, To], ...Helper<N, [...C, 1], Intermediate, To, From>]
Solution by Sun79 #30479