рефактор HanoyTowers, добавление решателя

This commit is contained in:
2026-03-05 22:07:29 +04:00
parent dbc3b3359e
commit 3d57b2a574
2 changed files with 77 additions and 64 deletions

View File

@@ -1,82 +1,113 @@
namespace su.divan2000.PLandDS_hanoi namespace su.divan2000.PLandDS_HanoiTowers
{ {
class HanoiTowers class HanoiTowers
{ {
private int[] tower_A; private int[][] towers;
private int[] tower_B;
private int[] tower_C;
private int size; private int size;
public enum TowerName { A, B, C }
public int Size { get { return size; } }
public HanoiTowers(int size) public HanoiTowers(int size)
{ {
this.size = size; this.size = size;
tower_A = new int[size]; towers = new int[3][];
tower_B = new int[size]; towers[0] = new int[size];
tower_C = new int[size]; towers[1] = new int[size];
towers[2] = new int[size];
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
{ {
tower_A[i] = size - i; towers[0][i] = size - i;
} }
} }
public string toString() public override string ToString()
{ {
int charsPerTower = size.ToString().Length; int charsPerTower = size.ToString().Length;
string result = ""; string result = "";
for (int i = size - 1; i >= 0; i--) for (int i = size - 1; i >= 0; i--)
{ {
result += tower_A[i].ToString().PadLeft(charsPerTower).Replace("0", "|") + " "; result += towers[0][i].ToString().PadLeft(charsPerTower).Replace("0", "|") + " ";
result += tower_B[i].ToString().PadLeft(charsPerTower).Replace("0", "|") + " "; result += towers[1][i].ToString().PadLeft(charsPerTower).Replace("0", "|") + " ";
result += tower_C[i].ToString().PadLeft(charsPerTower).Replace("0", "|") + "\n"; result += towers[2][i].ToString().PadLeft(charsPerTower).Replace("0", "|") + "\n";
} }
return result; return result;
} }
public void move(int from, int to) public void move(TowerName from, TowerName to)
{ {
int[] sourceTower = getTower(from); if (from == to) return;
int[] targetTower = getTower(to);
int[] sourceTower = towers[(int)from];
int[] targetTower = towers[(int)to];
int sourceTopIndex = getTopIndex(sourceTower); int sourceTopIndex = getTopIndex(sourceTower);
int targetTopIndex = getTopIndex(targetTower); int targetTopIndex = getTopIndex(targetTower);
if (sourceTopIndex == -1) if (sourceTopIndex < 0)
{ throw new InvalidOperationException("Source tower is empty");
throw new InvalidOperationException("No disk to move"); if (targetTopIndex >= size)
} throw new InvalidOperationException("Target tower is full");
if (targetTopIndex > 0 && sourceTower[sourceTopIndex] > targetTower[targetTopIndex])
if (targetTopIndex != -1 && sourceTower[sourceTopIndex] > targetTower[targetTopIndex])
{
throw new InvalidOperationException("Cannot place larger disk on smaller one"); throw new InvalidOperationException("Cannot place larger disk on smaller one");
}
targetTower[targetTopIndex + 1] = sourceTower[sourceTopIndex]; targetTower[targetTopIndex + 1] = sourceTower[sourceTopIndex];
sourceTower[sourceTopIndex] = 0; sourceTower[sourceTopIndex] = 0;
} }
private int[] getTower(int index) public int getTopIndex(int[] tower)
{ {
switch (index) for (int i = size-1; i >= 0; i--)
{
case 0: return tower_A;
case 1: return tower_B;
case 2: return tower_C;
default: throw new ArgumentException("Invalid tower index");
}
}
private int getTopIndex(int[] tower)
{
for (int i = size - 1; i >= 0; i--)
{ {
if (tower[i] != 0) if (tower[i] != 0)
{ {
return i; return i;
} }
} }
return -1; // Tower is full 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<Move> MoveN(HanoiTowers towers, int n, HanoiTowers.TowerName from, HanoiTowers.TowerName to, HanoiTowers.TowerName aux)
{
List<Move> moves = new List<Move>();
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<Move> 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);
}
} }
} }
} }

View File

@@ -1,36 +1,18 @@
using System; using System;
namespace su.divan2000.PLandDS_hanoi namespace su.divan2000.PLandDS_HanoiTowers
{ {
class Program class Program
{ {
static void Main() static void Main()
{ {
HanoiTowers towers = new HanoiTowers(4); HanoiTowers towers = new HanoiTowers(8);
Console.WriteLine(towers.toString()); Console.WriteLine(towers);
try List<HanoiUtils.Move> moves = HanoiUtils.MoveN(towers, towers.Size, HanoiTowers.TowerName.A, HanoiTowers.TowerName.C, HanoiTowers.TowerName.B);
{ HanoiUtils.ExecuteMoves(towers, moves);
towers.move(0, 1);
Console.WriteLine(towers.toString()); Environment.Exit(0);
towers.move(0, 2);
Console.WriteLine(towers.toString());
towers.move(1, 2);
Console.WriteLine(towers.toString());
towers.move(0, 1);
Console.WriteLine(towers.toString());
towers.move(2, 0);
Console.WriteLine(towers.toString());
towers.move(2, 1);
Console.WriteLine(towers.toString());
towers.move(0, 1);
}
catch (InvalidOperationException ex)
{
Console.WriteLine("Error: " + ex.Message);
}
Console.WriteLine(towers.toString());
} }
} }
} }