C# :: Aufgabe #95

2 Lösungen Lösungen öffentlich

Das Damenproblem (Teil I)

Fortgeschrittener - C# von ElPapito - 07.05.2015 um 11:42 Uhr
Das klassische Damenproblem besteht aus einem 8x8 Schachfeld und 8 Damen.
Die Aufgabe besteht darin die 8 Damen so zu positionieren, dass sie sich gegenseitig nicht bedrohen, d.h. es dürfen keine zwei Damen in der gleichen Zeile/Spalte/Diagonale stehen.

Schreibe ein kleines Programm, welches ausgibt wie viele Lösungen existieren.

Lösungen:

5 Kommentare
vote_ok
von eulerscheZhl (5230 Punkte) - 08.05.2015 um 16:10 Uhr
Quellcode ausblenden C#-Code
using System;

namespace trainYourProgrammer
{
	class MainClass
	{
		static long PlaceQueens(int n, bool[,] blocked, int line) {
			if (line == n)
				return 1;
			long result = 0;
			for (int i = 0; i < n; i++) {
				if (blocked [i, line])
					continue;
				result += PlaceQueens (n, PlaceQueenAt (i, line, n, blocked), line + 1);
			}
			return result;
		}

		static long PlaceQueens(int n) {
			bool[,] blocked = new bool[n, n];
			long result = 0;
			for (int i = 0; i < n/2; i++) { //Ausnutzen der Symmetrie
				result += 2 * PlaceQueens (n, PlaceQueenAt (i, 0, n, blocked), 1);
			}
			if (n % 2 == 1)
				result += PlaceQueens (n, PlaceQueenAt (n / 2, 0, n, blocked), 1);
			return result;
		}

		static bool[,] PlaceQueenAt(int x, int y, int n, bool[,] blocked) {
			int[,] offset = {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
			bool[,] result = (bool[,]) blocked.Clone();
			for(int dir = 0; dir < 8; dir++) {
				int x_ = x + offset[dir, 0];
				int y_ = y + offset[dir, 1];
				while (x_ >= 0 && x_ < n && y_ >= 0 && y_ < n) {
					result[x_, y_] = true;
					x_ += offset[dir, 0];
					y_ += offset[dir, 1];
				}
			}
			return result;
		}

		static void Main(string[] args) {
			for (int i = 8; i < 9; i++) {
				Console.WriteLine ("n = " + i.ToString().PadLeft(2) + ": " + PlaceQueens(i).ToString().PadLeft(6) + " Möglichkeiten");
			}
		}
	}
}
vote_ok
von alezyn (100 Punkte) - 05.11.2015 um 15:16 Uhr
Sicherlich nicht der "cleanste" Code, aber er funktioniert.

Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Damenproblem
{
    class Program
    {
        /// <summary>
        /// Programmablauf
        /// </summary>
        static void Main(string[] args)
        {
            //Setup
            SchachbrettClass schachbrett = new SchachbrettClass();
            Loesung loesung = new Loesung();
            Dame[] damen = new Dame[8];
            for (int i = 0; i < 8; i++)
            {
                damen[i] = new Dame(schachbrett);
            }

            //Möglichkeiten durchgehen
            Check(damen, 0, schachbrett, loesung);
            Console.WriteLine("Es gibt {0} Lösungen.", loesung.Moeglichkeiten);
            Console.ReadLine();
        }

        private static void Check(Dame[] damen, int spalte, SchachbrettClass schachbrett, Loesung loesung)
        {
            int zaehler = 0;

            do
            {
                if (damen[spalte].Spalte < 7)
                {
                    Check(damen, (spalte + 1), schachbrett, loesung);
                }
                if (damen[spalte].Reihe < 7)
                {
                    damen[spalte].Bewegen(schachbrett, damen[spalte].Reihe + 1, spalte);
                    loesung.Ueberpruefe(schachbrett);
                }
                zaehler++;
            } while (zaehler < 8);
            damen[spalte].Bewegen(schachbrett, 0, spalte);
        }
    }
}


Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Damenproblem
{
    public class SchachbrettClass
    {
        private int[,] schachbrett = new int[8,8];

        public SchachbrettClass()
        {
            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    schachbrett[i, j] = 0;
                }
            }
        }
        
        public int[,] Schachbrett
        {
            get
            {
                return schachbrett;
            }
            set
            {
                schachbrett = value;
            }
        }

        public void SetzeDameBei(int reihe, int spalte)
        {
            if (IstEineDameBei(reihe, spalte))
            {
                throw new Exception("Feld bereits besetzt!");
            }
            else
            {
                schachbrett[reihe, spalte] = 1;
            }
        }

        public void EntferneDameBei(int reihe, int spalte)
        {
            if (IstEineDameBei(reihe, spalte))
            {
                schachbrett[reihe, spalte] = 0;
            }
            else
            {
                throw new Exception("Keine Dame auf Feld!");
            }
        }

        public bool IstEineDameBei(int reihe, int spalte)
        {
            if (schachbrett[reihe, spalte] == 1)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}


Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Damenproblem
{
    public class Loesung
    {
        private int moeglichkeiten = 0;

        public int Moeglichkeiten
        {
            get
            {
                return moeglichkeiten;
            }
            set
            {
                moeglichkeiten = value;
            }
        }

        /// <summary>
        /// Überprüfe ob das übergebene Schachbrett Lösungskonform ist.
        /// </summary>
        public void Ueberpruefe(SchachbrettClass schachbrett)
        {
            bool checkr = true;
            bool checks = true;
            bool checkd = true;
            int checksGesamt = 0;
            
            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    if (schachbrett.IstEineDameBei(i, j))
                    {
                        checkr = CheckReihe(schachbrett, i);
                        if (!checkr)
                        {
                            checks = CheckSpalte(schachbrett, j);
                            if (!checks)
                            {
                                checkd = CheckDiagonale(schachbrett, i, j);
                            }
                        }
                        if (!checkd && !checkr && !checks)
                        {
                            checksGesamt++;
                        }
                    }
                }
            }
            if (checksGesamt == 8)
            {
                this.moeglichkeiten++;
            }
        }

        public bool CheckReihe(SchachbrettClass schachbrett, int reihe)
        {
            int zaehler = 0;

            for (int j = 0; j < 8; j++)
            {
                if (schachbrett.IstEineDameBei(reihe, j))
                {
                    zaehler++;
                    if (zaehler > 1)
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        public bool CheckSpalte(SchachbrettClass schachbrett, int spalte)
        {
            int zaehler = 0;

            for (int i = 0; i < 8; i++)
            {
                if (schachbrett.IstEineDameBei(i, spalte))
                {
                    zaehler++;
                    if (zaehler > 1)
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        public bool CheckDiagonale(SchachbrettClass schachbrett, int reihe, int spalte)
        {
            int i = reihe;
            int j = spalte;

            while (i > 0 && j > 0)
            {
                i--;
                j--;
                if (schachbrett.IstEineDameBei(i, j))
                {
                    return true;
                }
            }

            i = reihe;
            j = spalte;
            while (i < 7 && j > 0)
            {
                i++;
                j--;
                if (schachbrett.IstEineDameBei(i, j))
                {
                    return true;
                }
            }

            i = reihe;
            j = spalte;
            while (i < 7 && j < 7)
            {
                i++;
                j++;
                if (schachbrett.IstEineDameBei(i, j))
                {
                    return true;
                }
            }

            i = reihe;
            j = spalte;
            while (i > 0 && j < 7)
            {
                i--;
                j++;
                if (schachbrett.IstEineDameBei(i, j))
                {
                    return true;
                }
            }
            return false;
        }
    }
}


Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Damenproblem
{
    public class Dame
    {
        private int reihe = -1;
        private int spalte = -1;

        /// <summary>
        /// Setze neue Dame auf das Schachbrett. Wenn die Standardposition schon belegt ist wird nach einer neuen Position gesucht.
        /// </summary>
        public Dame(SchachbrettClass schachbrett)
        {
            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    if (!schachbrett.IstEineDameBei(i, j))
                    {
                        reihe = i;
                        spalte = j;
                        schachbrett.SetzeDameBei(i, j);
                        return;
                    }
                }
            }
        }

        public int Reihe
        {
            get
            {
                return reihe;
            }
            set
            {
                reihe = value;
            }
        }

        public int Spalte
        {
            get
            {
                return spalte;
            }
            set
            {
                spalte = value;
            }
        }

        public bool Bewegen(SchachbrettClass schachbrett, int reihe, int spalte)
        {
            if (schachbrett.IstEineDameBei(reihe, spalte))
            {
                return false;
            }
            else
            {
                schachbrett.SetzeDameBei(reihe, spalte);
                schachbrett.EntferneDameBei(this.reihe, this.spalte);
                this.reihe = reihe;
                this.spalte = spalte;
                return true;
            }
        }
    }
}


Ausgabe:

Konsolenausgabe:

Es gibt 92 Lösungen.
2103679

Du scheinst einen AdBlocker zu nutzen. Ich würde mich freuen, wenn du ihn auf dieser Seite deaktivierst und dich davon überzeugst, dass die Werbung hier nicht störend ist.