namespace su.divan2000.PLandDS_HanoiTowers { class HanoiTowers { private int[][] towers; private int size; public enum TowerName { A, B, C } public int Size { get { return size; } } public HanoiTowers(int size) { this.size = size; towers = new int[3][]; towers[0] = new int[size]; towers[1] = new int[size]; towers[2] = new int[size]; for (int i = 0; i < size; i++) { towers[0][i] = size - i; } } public override string ToString() { int charsPerTower = size.ToString().Length; string result = ""; for (int i = size - 1; i >= 0; i--) { result += towers[0][i].ToString().PadLeft(charsPerTower).Replace("0", "|") + " "; result += towers[1][i].ToString().PadLeft(charsPerTower).Replace("0", "|") + " "; result += towers[2][i].ToString().PadLeft(charsPerTower).Replace("0", "|") + "\n"; } return result; } public void move(TowerName from, TowerName to) { if (from == to) return; int[] sourceTower = towers[(int)from]; int[] targetTower = towers[(int)to]; int sourceTopIndex = getTopIndex(sourceTower); int targetTopIndex = getTopIndex(targetTower); if (sourceTopIndex < 0) throw new InvalidOperationException("Source tower is empty"); if (targetTopIndex >= size) throw new InvalidOperationException("Target tower is full"); if (targetTopIndex > 0 && sourceTower[sourceTopIndex] > targetTower[targetTopIndex]) throw new InvalidOperationException("Cannot place larger disk on smaller one"); targetTower[targetTopIndex + 1] = sourceTower[sourceTopIndex]; sourceTower[sourceTopIndex] = 0; } public int getTopIndex(int[] tower) { for (int i = size-1; i >= 0; i--) { if (tower[i] != 0) { return i; } } return -1; // Tower is empty } } static class HanoiUtils { public struct Move { public HanoiTowers.TowerName From; public HanoiTowers.TowerName To; public Move(HanoiTowers.TowerName from, HanoiTowers.TowerName to) { From = from; To = to; } } public static List MoveN(HanoiTowers towers, int n, HanoiTowers.TowerName from, HanoiTowers.TowerName to, HanoiTowers.TowerName aux) { List moves = new List(); if (n == 1) { moves.Add(new Move(from, to)); } else { moves.AddRange(MoveN(towers, n - 1, from, aux, to)); moves.Add(new Move(from, to)); moves.AddRange(MoveN(towers, n - 1, aux, to, from)); } return moves; } public static void ExecuteMoves(HanoiTowers towers, List moves) { foreach (Move move in moves) { towers.move(move.From, move.To); Console.Clear(); Console.WriteLine($"Move from {move.From} to {move.To}"); Console.WriteLine(towers); System.Threading.Thread.Sleep(1000); } } } }