I'm facing the Towers of Hanoi problem, I read the concept and the recursive way of solving it from wikipedia, but I can not see what I'm missing in the implementation of the steps mentioned in wikipedia.
I have seen many examples here but I don't want my program to print the steps, I want the program solves the problem moving the "discs" between 3 collections, in my code I'm using 3 Stacks to simulate the pegs.
Here is my current code:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main(string[] args)
{
var hs = new HanoiSolver(discs: 3);
hs.Solve();
Console.ReadKey();
}
}
class HanoiSolver
{
private int TotalDiscs { get; set; } = 0;
private Stack<int> FirstPeg { get; set; } = new Stack<int>();
private Stack<int> SecondPeg { get; set; } = new Stack<int>();
private Stack<int> ThirdPeg { get; set; } = new Stack<int>();
public HanoiSolver(int discs = 3)
{
TotalDiscs = discs;
//Create list of items (discs)
var discList = Enumerable.Range(1, TotalDiscs).Reverse();
//Add items (discs) to first peg
foreach (var d in discList)
{
FirstPeg.Push(d);
}
}
public void Solve()
{
if (ThirdPeg.Count != TotalDiscs)
{
PrintPegs();
//Move first item from firstpeg to secondpeg
if (FirstPeg.Any())
{
var fp_f = FirstPeg.Pop();
SecondPeg.Push(fp_f);
}
PrintPegs();
//Move second item from firstpeg to thirdpeg
if (FirstPeg.Any())
{
var fp_s = FirstPeg.Pop();
ThirdPeg.Push(fp_s);
}
PrintPegs();
//Move first item from secondpeg to thirdpeg
if (SecondPeg.Any())
{
var sp_f = SecondPeg.Pop();
ThirdPeg.Push(sp_f);
}
PrintPegs();
Solve();
}
}
private void PrintPegs()
{
var fp = FirstPeg.Select(x => x.ToString()).ToList();
if (fp.Count < TotalDiscs)
{
fp.AddRange(Enumerable.Repeat(string.Empty, (TotalDiscs - fp.Count)));
}
var sp = SecondPeg.Select(x => x.ToString()).ToList();
if (sp.Count < TotalDiscs)
{
sp.AddRange(Enumerable.Repeat(string.Empty, (TotalDiscs - sp.Count)));
}
var tp = ThirdPeg.Select(x => x.ToString()).ToList();
if (tp.Count < TotalDiscs)
{
tp.AddRange(Enumerable.Repeat(string.Empty, (TotalDiscs - tp.Count)));
}
Console.WriteLine($"{"[First Peg]",10}" + $"{"[Second Peg]",10}" + $"{"[Third Peg]",10}");
for (var i = 0; i < TotalDiscs; i++)
{
Console.WriteLine($"{fp[i],10}" +
$"{sp[i],10}" +
$"{tp[i],10}");
}
}
}
In order to make a recursive method you need one or more base cases where the recursion will end and then one or more recursive calls that break the problem down closer to one of the base cases. For Towers of Hanoi the idea is that moving n discs from Peg A to Peg C is just moving n-1 from Peg A to Peg B, then moving the nth from A to C and finally moving the n-1 discs from C to B. That will eventually get you down to moving no discs which is your base case. That can be done in a recursive method very simply like this.
private static void Move(
int discs,
Stack<int> fromPeg,
Stack<int> toPeg,
Stack<int> otherPeg)
{
if (discs == 0)
{
return;
}
Move(discs - 1, fromPeg, otherPeg, toPeg);
toPeg.Push(fromPeg.Pop());
Move(discs -1, otherPeg, toPeg, fromPeg);
}