Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Das Programmier-Spiel: nette Übungsaufgaben für zwischendurch
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3430
Herkunft: Trier -> München

beantworten | zitieren | melden

Hallo,

bleiben wir mit der nächsten Aufgabe mal beim Thema char[ , ]

Gegeben sei folgende Methodensignatur:

int FindRoute(char[,])
Implementiert die Methode so, daß ein Weg aus einem übergebenen Labyrinth gefunden wird. Dabei gilt:
'#': Wand
' ': möglicher Weg

Füllt den gefundenen Weg im übergebenen Array mit '+'-Zeichen aus.
Edit: Rückgabewert soll die Länge des gefundenen Weges sein.

Ihr könnt außerdem von folgenden Startbedingungen ausgehen:
Das Labyrinth ist immer vollständig mit einer Wand umrahmt, die eine Startöffnung in der ersten Zeile und einer Zielöffnung in der letzten Zeile aufweist. Dabei existiert mindestens ein Weg vom Start zum Ziel.

Es muss nicht der kürzeste Weg gefunden werden, bei mehreren Möglichkeiten reicht es, eine davon zu finden.

Eine Ausgabe auf der Konsole ist auch in dieser Aufgabe optional.

Beispiel:
################+#############
# # # ###      #+# #         #
# # #     ######+# # ####### #
# #   #####++++++# # #     # #
#   # #    +###### # ##### # #
# # # # # #+#      #       # #
# # # # # #+###### ##### # # #
# # # # # #++++++# #+++# # # #
# # # # # ######+# #+#+##### #
# # # # ###  # #+# #+#+      #
# # # #      # #+++++#+## ####
# ### ######## #######+#     #
# #                   +# # ###
# # ##################+# # # #
# # #++++++++++++++++++# # # #
# # #+################## # # #
# # #+#                      #
#####+########################

Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
private Nachricht | Beiträge des Benutzers
edsplash
myCSharp.de - Member

Avatar #avatar-3111.jpg


Dabei seit:
Beiträge: 411

beantworten | zitieren | melden

Hallo..


    private static int FindRoute(char[,] map)
    {
      for (int column = 0; column < map.GetLength(1); column++)
      {
        int wayLenght = GetWayLength(map, 0, column, 1);
        if (wayLenght > 0)
          return wayLenght;
      }
      return 0;
    }

    private static int GetWayLength(char[,] map, int line, int column, int wayLength)
    {
      //Oberer Rand überschritten
      if (line == -1)
        return -1;
      //Linker Rand überschritten
      if (column == -1)
        return -1;
      //Rechter Rand überschritten
      if (column ≥ map.GetLength(1))
        return -1;

      if (map[line, column] == ' ')
      {
        map[line, column] = '+';

        if (line + 1 == map.GetLength(0))
          //Auf der letzten Zeile angelangt
          return wayLength;
        else
        {
          int rightNeighbor = GetWayLength(map, line, column + 1, wayLength + 1);
          int bottomNeighbor = GetWayLength(map, line + 1, column, wayLength + 1);
          int leftNeighbor = GetWayLength(map, line, column - 1, wayLength + 1);
          int topNeighbor = GetWayLength(map, line - 1, column, wayLength + 1);

          if (rightNeighbor > 0)
            return rightNeighbor;
          if (bottomNeighbor > 0)
            return bottomNeighbor;
          if (leftNeighbor > 0)
            return leftNeighbor;
          if (topNeighbor > 0)
            return topNeighbor;
          else
          {
            //Sackgasse
            //Bisher gegangener Weg löschen bzw. aktuelle Position wieder löschen
            map[line, column] = ' ';
            return -1;
          }
        }
      }
      else
      {
        return -1;
      }
    }

Wenn es zwei Wege gibt, werden zwar beide eingezeichnet, die Länge wird allerdings nur von einem zurückgegeben.

Gruss
using Skill
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3430
Herkunft: Trier -> München

beantworten | zitieren | melden

Hallo edsplash,
Zitat
Wenn es zwei Wege gibt, werden zwar beide eingezeichnet
Nicht wenn 2 Wege zum selben Ausgang führen. Kann auch eigentlich nicht, weil nach dem ersten Fund der Ausgang blockiert ist.
Deine Lösung findet aber problemlos mehrere Ausgänge

Die Kriterien der Aufgabenstellung sind also aus meiner Sicht erfüllt
Damit wärst Du dann dran.

Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
private Nachricht | Beiträge des Benutzers
edsplash
myCSharp.de - Member

Avatar #avatar-3111.jpg


Dabei seit:
Beiträge: 411

beantworten | zitieren | melden

Hallo Zusammen

Hier die neue Aufgabe:
Es geht um die Berechnung von Pi mit Hilfe des Monte Carlo Algorithmus.

Zu implementieren ist folgendes Interface:


interface IMonteCarloPi
  {
    int CircleRadius { get; set; }
    double Calculate(int iterations);
  }

Die Methode Calculate berechnet Pi. Der Parameter iterations gibt an wie viel mal iteriert werden soll. Das Property CircleRadius ist dazu gedacht, die Genauigkeit zu erhöhen: Statt mit dem Einheitskreis zu arbeiten (Radius = 1) kann man einen grösseren Radius einstellen und so ein genaueres Resultat erhalten.

Gruss
using Skill
private Nachricht | Beiträge des Benutzers
prakti08
myCSharp.de - Member



Dabei seit:
Beiträge: 336
Herkunft: Trier

beantworten | zitieren | melden

    public class MonteCarloPI : IMonteCarloPi
    {
        Random random = new Random();
        int m_Radius = 0;

        public int CircleRadius
        {
            get
            {
                return m_Radius;
            }
            set
            {
                m_Radius = value;
            }
        }

        public double Calculate(int iterations)
        {
            double x = 0, y = 0;
            int unter = 0;


            for (int i = 0; i < iterations; i++)
            {

                x = random.NextDouble()+ random.Next(0,m_Radius);
                y = random.NextDouble() + random.Next(0, m_Radius);
                
		        if(((x*x)+(y*y))≤(long)m_Radius*m_Radius))
		        unter++;
	        }
            return (((double)unter / iterations) * 4);
        }

    }

war aber bestimmt anders gedacht oder?^^
Dieser Beitrag wurde 5 mal editiert, zum letzten Mal von prakti08 am .
Use the source, Luke!




Nur, weil man vor sich eine CPU hat, muß man das Denken nicht
einstellen.
private Nachricht | Beiträge des Benutzers
edsplash
myCSharp.de - Member

Avatar #avatar-3111.jpg


Dabei seit:
Beiträge: 411

beantworten | zitieren | melden

Erm nö, eigentlich nicht ;)

Nur scheint die Berechnung bei grossen Zahlen für CircleRadius zunehmend nicht mehr zu stimmen. Verwendet man z.b. int.MaxValue gibt es 0.
using Skill
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3430
Herkunft: Trier -> München

beantworten | zitieren | melden

Hallo edsplash,

wieso soll eigentlich die Berechnung mit einem größeren Radius genauer sein als mit 1?
Die Zufallszahlen werden ja ohnehin über NextDouble() gezogen und die Multiplikation mit einem int erhöht ja nicht die "Auflösung"...

Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
private Nachricht | Beiträge des Benutzers
edsplash
myCSharp.de - Member

Avatar #avatar-3111.jpg


Dabei seit:
Beiträge: 411

beantworten | zitieren | melden

Hallo MarsStein

Wenn man es einfach mit dieser Zahl multipliziert wird das natürlich nichts. Man könnte aber z.b. Next(0, CircleRadius) verwenden: Da wird das Ergebnis natürlich zunehmend ungenau, wenn CircleRadius kleiner wird.
An und für sich ist der Double allerdings genauer als ein Int32. Ich könnte mir aber vorstellen, dass die Operation mit Ganzzahlen schneller geht als mit Gleitkommazahlen, getestet habe ich das allerdings nicht.

Gruss
using Skill
private Nachricht | Beiträge des Benutzers
prakti08
myCSharp.de - Member



Dabei seit:
Beiträge: 336
Herkunft: Trier

beantworten | zitieren | melden

zählt meine lösung oder wärs besser wenn man ne lösung für alle zahlen entwickelt?^^
Use the source, Luke!




Nur, weil man vor sich eine CPU hat, muß man das Denken nicht
einstellen.
private Nachricht | Beiträge des Benutzers
edsplash
myCSharp.de - Member

Avatar #avatar-3111.jpg


Dabei seit:
Beiträge: 411

beantworten | zitieren | melden

Ich hätte eigentlich ganz gerne noch eine komplette Lösung ;)
Du darfst Dir aber gerne bereits eine neue Aufgabe überlegen.
using Skill
private Nachricht | Beiträge des Benutzers
prakti08
myCSharp.de - Member



Dabei seit:
Beiträge: 336
Herkunft: Trier

beantworten | zitieren | melden

so.. hab den radius² auf long gecastet.. jetzt kann man auch int.MaxValue nutzen ;)

neue aufgabe
Schreiben Sie ein Programm, das mit Hilfe von Backtracking eine gültige Lösung für beliebige Sudoku ermittelt, falls eine solche existiert. Die Lösung kann direkt in das Sudoku eingetragen werden.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von prakti08 am .
Use the source, Luke!




Nur, weil man vor sich eine CPU hat, muß man das Denken nicht
einstellen.
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3430
Herkunft: Trier -> München

beantworten | zitieren | melden

Halllo prakti08,

ich will ja kein Spielverderber sein, aber

random.Next(0,m_Radius-1)
//und
(long)m_Radius*m_Radius
hier machst Du - abgesehen davon, daß Radius 1 nicht mehr funktioniert, auch noch den systematischen Fehler, die Koordinaten mit (m_Radius-1) zu ermitteln und den Abstand mit (m_Radius) zu prüfen
Da der zweite Parameter von Rand.Next() bereits exklusiv ist, kannst Du dir die -1 aber auch sparen.
Genau genommen müsste IMHO da sogar eine +1 hin (eben wegen exklusiv)...

Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
private Nachricht | Beiträge des Benutzers
prakti08
myCSharp.de - Member



Dabei seit:
Beiträge: 336
Herkunft: Trier

beantworten | zitieren | melden

warum sollte 1 nicht funktionieren?
selbst wenn der radius 1 ist bekommt man ne zahl zwischen 0 und 1 als zufallszahl..
wegen nextDouble

das exklusiv habe ich überlesen.. hab das -1 weggemacht..
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von prakti08 am .
Use the source, Luke!




Nur, weil man vor sich eine CPU hat, muß man das Denken nicht
einstellen.
private Nachricht | Beiträge des Benutzers
edsplash
myCSharp.de - Member

Avatar #avatar-3111.jpg


Dabei seit:
Beiträge: 411

beantworten | zitieren | melden

Hallo

Bei int.MaxValue kommt immer noch 0 raus. Es geht ja nicht darum, ob int.MaxValue rein passt, sondern darum, ob die Genauigkeit mit grösseren Werten für CircleRadius erhöht wird. Und das ist momentan so nicht gegeben.

Gruss
using Skill
private Nachricht | Beiträge des Benutzers
prakti08
myCSharp.de - Member



Dabei seit:
Beiträge: 336
Herkunft: Trier

beantworten | zitieren | melden

...
seltsam das es bei mir funktioniert?!
siehe Anhang

habe die variablen iteration und radius in der überwachung.
habe einige minuten gewartet und das war das ergebnis!
Attachments
Use the source, Luke!




Nur, weil man vor sich eine CPU hat, muß man das Denken nicht
einstellen.
private Nachricht | Beiträge des Benutzers
edsplash
myCSharp.de - Member

Avatar #avatar-3111.jpg


Dabei seit:
Beiträge: 411

beantworten | zitieren | melden

Hm.. komisch! Muss mir das morgen nochmal anschauen.
Erachte die Aufgabe aber als gelöst ;)
using Skill
private Nachricht | Beiträge des Benutzers
Gelöschter Benutzer

beantworten | zitieren | melden

bei diesem code kann es zu unterschieden zwischen debug und release kommen.
prakti08
myCSharp.de - Member



Dabei seit:
Beiträge: 336
Herkunft: Trier

beantworten | zitieren | melden

da ich drauf angesprochen wurde und meine aufgabe wohl weiter oben untergegangen ist poste ich sie nochmal..
Schreiben Sie ein Programm, das mit Hilfe von Backtracking eine gültige Lösung für beliebige Sudoku ermittelt, falls eine solche existiert. Die Lösung kann direkt in das Sudoku eingetragen werden.

Edit: Das Sudoku liegt in Form eines 2Dim Arrays vor
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von prakti08 am .
Use the source, Luke!




Nur, weil man vor sich eine CPU hat, muß man das Denken nicht
einstellen.
private Nachricht | Beiträge des Benutzers
Campac68
myCSharp.de - Member



Dabei seit:
Beiträge: 68

beantworten | zitieren | melden

Meine Lösung für die Soduku Aufgabe. Ich hoffe sie ist ungefähr dem genehm was du wolltest. Ich hab sie mit drei verschiedenen Sudokus verschiedener Schwierigkeitsgrade getestet und sie lieferte immer (ein) richtiges bzw das richtige Ergebnis in unter 300ms(Kann beim Deuggen abweichen). Bei der Eingabe von einem Sudoku, welches(wie bei meiner Lösung standartmäßig) mit Nullen gefüllt ist braucht sie 12 ms um eine oft im Internet als Beispielsudoku gesehene Lösung zu produzieren(ausprobieren;)). Die Klasse Sudoku wurde dabei Immutable gehalten(für die verwendete Rekursion recht praktisch:))

Zu sagen ist, dass man darauf achten sollte immer nur Mehrdimensionale Array mit wenigstens 9*9 Zahlen zu übergeben, anderes wird nicht abgefangen. Der restliche Code sollte nicht zu schnell zusammenbrechen(auch wenn bestimmte Teile nicht oft getestet wurde, da sie letztenendes nicht für die Gesamtlösung verwendet werden). Die entscheidenden Methoden sind die unteren 6(bis 9) welche auch ein wenig kommentiert sind(eher spärlich). Zu sagen ist, das eigentlich alles Null-basiert ist. Der Rest findet sich beim durschauen.

Benutzung:

    class Program
    {
        static void Main(string[] args)
        {
            Sudoku s = new Sudoku(
                new int[9, 9] {
                {0,8,0,4,0,0,2,0,9},
            {0,5,9,0,8,0,0,0,3},
            {0,0,0,0,0,9,0,0,7},
            {8,2,0,0,1,0,0,0,0},
            {5,0,0,0,7,0,0,0,6},
            {0,0,0,0,4,0,0,2,5},
            {3,0,0,7,0,0,0,0,0},
            {9,0,0,0,2,0,3,7,0},
            {7,0,5,0,0,8,0,9,0}}
            );

            /*Sudoku s = new Sudoku(
                new int[9, 9] {
                {0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0}}
            );*/

            s.drawToConsole();
            Sudoku solution = new Sudoku();
            
            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Start();
            solution = s.findSolution();
            stopWatch.Stop();
 
            Console.WriteLine("Zeit: " + stopWatch.ElapsedMilliseconds + "ms");

            solution.drawToConsole();
            Console.ReadLine();
        }
    }

Eigentlicher Code:

    class Sudoku
    {
        private int[,] m_content;

        public Sudoku()
        {
            m_content = new int[9, 9];

            for (int row = 0; row < 9; row++)
            {
                for (int column = 0; column < 9; column++)
                {
                    m_content[row, column] = 0;
                }
            }
        }

        public Sudoku(int[,] content)
        {
            m_content = new int[9, 9];

            for (int row = 0; row < 9; row++)
            {
                for (int column = 0; column < 9; column++)
                {
                    m_content[row, column] = content[row, column];
                }
            }
        }

        public void drawToConsole()
        {
            for (int row = 0; row < 9; row++)
            {

                if (row % 3 == 0)
                {
                    Console.WriteLine("-------------");
                }

                for (int column = 0; column < 9; column++)
                {
                    if (column % 3 == 0) Console.Write("|");
                    Console.Write(m_content[row, column]);
                }
                Console.WriteLine("|");
            }
            Console.WriteLine("-------------");
        }

        public int[,] toArray()
        {
            return m_content;
        }

        private bool isRowValid(int row)
        {
            List<int> numbers = new List<int>();

            for (int column = 0; column < 9; column++)
            {
                if (numbers.Contains(m_content[row, column]))
                {
                    return false;
                }
                else if (m_content[row, column] != 0)
                {
                    numbers.Add(m_content[row, column]);
                }
            }
            return true;
        }

        private bool isColumnValid(int column)
        {
            List<int> numbers = new List<int>();

            for (int row = 0; row < 9; row++)
            {
                if (numbers.Contains(m_content[row, column]))
                {
                    return false;
                }
                else if (m_content[row, column] != 0)
                {
                    numbers.Add(m_content[row, column]);
                }
            }
            return true;
        }

        /// <summary>
        /// Zero based!
        /// </summary>
        /// <param name="box">Box numbers from top-left to bottom right in each row from left to right</param>
        /// <returns></returns>
        private bool isBoxValid(int box)
        {
            List<int> numbers = new List<int>();

            int boxRow = box ≤ 2 ? 0 : box ≤ 5 ? 1 : 2;
            int boxColumn = box % 3;

            for (int row = boxRow * 3; row < boxRow * 3 + 3; row++)
            {
                for (int column = boxColumn * 3; column < boxColumn * 3 + 3; column++)
                {
                    if (numbers.Contains(m_content[row, column]))
                    {
                        return false;
                    }
                    else if (m_content[row, column] != 0)
                    {
                        numbers.Add(m_content[row, column]);
                    }
                }
            }

            return true;
        }

        public bool isValid()
        {
            for (int i = 0; i < 9; i++)
            {
                if (!(isRowValid(i) && isColumnValid(i) && isBoxValid(i)))
                {
                    Console.WriteLine((!isRowValid(i) ? "Row " : "") + (!isColumnValid(i) ? "Column " : "") + (!isBoxValid(i) ? "Box " : "") + i.ToString());
                    return false;

                }
            }
            return true;
        }

        private bool isNumberValidAt(int row, int column, int value)
        {
            Sudoku s = insertNumberAt(row, column, value);

            int box = (row < 3 ? 0 : (row < 6 ? 1 : 2)) * 3 + (column < 3 ? 0 : (column < 6 ? 1 : 2));

            return s.isRowValid(row) && s.isColumnValid(column) && s.isBoxValid(box);
        }

        private List<int> getValidNumbersAt(int row, int column)
        {
            List<int> validNumbers = new List<int>();
            Sudoku s;
            for (int i = 1; i ≤ 9; i++)
            {
                s = insertNumberAt(row, column, i);

                int box = (row < 3 ? 0 : (row < 6 ? 1 : 2)) * 3 + (column < 3 ? 0 : (column < 6 ? 1 : 2));

                if (s.isRowValid(row) && s.isColumnValid(column) && s.isBoxValid(box))
                {
                    validNumbers.Add(i);
                }
            }
            return validNumbers;

        }

        public Sudoku insertNumberAt(int row, int column, int value)
        {
            int[,] newContent = m_content;
            newContent[row, column] = value;
            return new Sudoku(newContent);
        }

        public Sudoku findSolution()
        {
            // If the incoming Sudoku is already wrong dont jump into the solution algorithm
            if (isValid())
            {
                Sudoku s = findSolution(0, 0);
                return s == null ? new Sudoku() : s;
            }
            else
            {
                return new Sudoku();
            }
        }

        private Sudoku findSolution(int row, int column)
        {
            // If ready...
            if (row == 9)
                return this;
            
            // If row changed
            if (column == 9)
                column = 0;

            if (m_content[row, column] == 0)
            {
                foreach (int i in getValidNumbersAt(row, column))
                {
                    // Check next field
                    Sudoku s = (insertNumberAt(row, column, i).findSolution(column + 1 == 9 ? row + 1 : row, column + 1));
                    // If something comes back the solution was found!
                    if (s != null) return s;
                }
                return null;
            }
            else
            {
                return new Sudoku(m_content).findSolution(column + 1 == 9 ? row + 1 : row, column + 1);
            }
        }
    }
private Nachricht | Beiträge des Benutzers
prakti08
myCSharp.de - Member



Dabei seit:
Beiträge: 336
Herkunft: Trier

beantworten | zitieren | melden

habs grade überflogen, sieht schonmal ganz gut aus..
allerdings wünsche ich mir eine lösung die auch größere Sudokus akzeptiert..
bsp 12er statt 9er

wenn du diesen punkt noch umsetzt kannst du die nächste aufgabe stellen ;)
Use the source, Luke!




Nur, weil man vor sich eine CPU hat, muß man das Denken nicht
einstellen.
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3430
Herkunft: Trier -> München

beantworten | zitieren | melden

Hallo Campac68,

folgende Eingabe:

                new int[9, 9] {
            {0,0,0,0,0,0,0,1,0},
            {4,0,0,0,0,0,0,0,0},
            {0,2,0,0,0,0,0,0,0},
            {0,0,0,0,5,0,4,0,7},
            {0,0,8,0,0,0,3,0,0},
            {0,0,1,0,9,0,0,0,0},
            {3,0,0,4,0,0,2,0,0},
            {0,5,0,1,0,0,0,0,0},
            {0,0,0,8,0,6,0,0,0}}
zur Kontrolle: Es soll dieses Sudoku aus der Wikipedia sein.

Ich habe dabei Deinen Algorithmus nach über 10 Minuten abgebrochen. Mein eigener Code löst das in 2m20s, mit reinem Backtracking, also gehe ich davon aus dass da noch etwas schiefläuft...

Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
private Nachricht | Beiträge des Benutzers
Campac68
myCSharp.de - Member



Dabei seit:
Beiträge: 68

beantworten | zitieren | melden

jo stimmt mal schauen

EDIT: Ich würde ehrlich gesagt behaupten das mein Code einfach nur relativ lahm ist. Ich hab nicht so auf Performance geachtet...
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Campac68 am .
private Nachricht | Beiträge des Benutzers
Campac68
myCSharp.de - Member



Dabei seit:
Beiträge: 68

beantworten | zitieren | melden

ne kein fehler dauert nur ewig:

lösung kam bei mir nach 6 1/2 minuten(2.5GHz) kann es sein das du es im Debug Modus ausgeführt hast? Das verlangsamt das ganze etwa um das doppelte^^
private Nachricht | Beiträge des Benutzers
Floste
myCSharp.de - Member

Avatar #avatar-2376.jpg


Dabei seit:
Beiträge: 1158
Herkunft: Norddeutschland

beantworten | zitieren | melden

schade, dass ich anysudoku nicht einreichen kann.
Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!
private Nachricht | Beiträge des Benutzers
prakti08
myCSharp.de - Member



Dabei seit:
Beiträge: 336
Herkunft: Trier

beantworten | zitieren | melden

Zitat von prakti08
habs grade überflogen, sieht schonmal ganz gut aus..
allerdings wünsche ich mir eine lösung die auch größere Sudokus akzeptiert..
bsp 12er statt 9er

wenn du diesen punkt noch umsetzt kannst du die nächste aufgabe stellen ;)

diesen punkt kannst du doch vernachlässigen^^
habe in den nächsten tagen seeehr wenig zeit um iwas nachzuprüfen.
akzeptiere deine lösung also :)
Use the source, Luke!




Nur, weil man vor sich eine CPU hat, muß man das Denken nicht
einstellen.
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo zusammen,

nachdem Campac68 - auch nach einer entsprechenden Aufforderung per PM - keine neue Aufgabe gestellt hat, gebe ich das Spiel wieder frei. Wer eine nette Aufgabe hat, möge diese bitte posten. Achtet dabei vor dem Absenden darauf, dass euch keiner zuvorgekommen ist. Nur die erste neue Aufgabe zählt.

herbivore
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3430
Herkunft: Trier -> München

beantworten | zitieren | melden

Hallo,

hier noch nachträglich eine gültige Lösung für die Sudoku-Aufgabe.
Da herbivore das Spiel wieder freigegeben hat, erhebe ich aber keinen Anspruch auf die nächste Aufgabe.
Wenn jemand eine schöne Idee hat, biite sehr...

zum Sudoku-Code:
in der public-Methode muss 'values' die gültigen Werte enthalten.
Der erste Wert muss der Wert sein, der für leere Felder benutzt wird
'blocksInRow' gibt an, wieviel Blöcke in einer Reihe liegen, so kann ein 12x12-Feld z.B. als 4x3 Blöcke (dann wäre die 4 anzugeben) oder als 3x4 Blöcke (dann wäre 3 anzugeben) interpretiert werden.

public static class SudokuSolver
{
  static bool Solve<T>(T[,] sudoku, T[] values, int width, int height, int row, int col)
  {
    if(col == sudoku.GetLength(0))
    {
      col = 0;
      row ++;
    }
    bool? result = (row == width * height) ? true : (bool?)null;
    if((!result.HasValue) && sudoku[col,row].Equals(values[0]))
    {
      result = false;
      for(int field = 1; (!result.Value) && (field < values.Length); field++)
      {
        result = true;
        T val = values[field];
        for(int i = sudoku.GetLength(0) - 1; result.Value && (i ≥ 0); i--)
        {
          result = !(val.Equals(sudoku[col,i]) || val.Equals(sudoku[i,row]));
        }
        int rowStart = height * (row / height);
        int colStart = width * (col / width);
        for(int i =  rowStart; result.Value && (i < rowStart + height); i++)
        {
          for(int j =  colStart; result.Value && (j < colStart + width); j++)
          {
            result = !val.Equals(sudoku[j,i]);
          }
        }
        if(result.Value)
        {
          sudoku[col,row] = val;
          result = Solve(sudoku, values, width, height, row, col+1);
          sudoku[col,row] = result.Value ? val : values[0];
        }
      }
    }
    return result.HasValue ? result.Value : Solve(sudoku, values, width, height, row, col+1);
  }

  public static bool Solve<T>(T[,] sudoku, T[] values, int blocksInRow)
  {
    return Solve(sudoku, values, sudoku.GetLength(0) / blocksInRow, blocksInRow, 0, 0);
  }
}

Gruß, MarsStein
Edit: Ich hatte eine Version mit vertauschten Col/Row eingestellt -> korrigiert.
Dieser Beitrag wurde 5 mal editiert, zum letzten Mal von MarsStein am .
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
private Nachricht | Beiträge des Benutzers
TheBrainiac
myCSharp.de - Member

Avatar #avatar-3152.png


Dabei seit:
Beiträge: 832
Herkunft: /dev/null

beantworten | zitieren | melden

Hi @ All.

Gegeben ist folgendes Snippet:

using System;
using System.Diagnostics;

public class Parameter {
	private string m_Name;
	private object m_Value;
	
	public Parameter(string name, object value) {
		m_Name = name;
		m_Value = value;
	}
	
	public Parameter(object value) {
		m_Name = null;
		m_Value = value;
	}
	
	public string Name {
		get { return m_Name; }
	}
	
	public object Value {
		get { return m_Value; }
	}
}

public static class StringEx {
    public static string Format(string format, params Parameter[] args) {
        // Hier eure Implementierung!
		throw new NotImplementedException();
    }
}

public class Program {
	public static void Main() {
		Debug.Assert("This is SPARTA!" == StringEx.Format("This is $what!", new Parameter("what", "SPARTA")));
		Debug.Assert("This is SPARTA!" == StringEx.Format("This is $1!", new Parameter("SPARTA")));
		DateTime date = new DateTime(2010, 06, 12, 17, 18, 32);
		Debug.Assert("Date is: 12.6.2010, Time is: 17:18:32" == StringEx.Format("Date is: ${date:Day}.${date:Month}.${date:Year}, Time is: ${date:Hour}:${date:Minute}:${date:Second}", new Parameter("date", date)));
		Debug.Assert("17:18:32" == StringEx.Format ("${date:TimeOfDay:Hours}:${date:TimeOfDay:Minutes}:${date:TimeOfDay:Seconds}", new Parameter("date", date)));
		Debug.Assert("$test = TEST" == StringEx.Format("$$test = $test", new Parameter("test", "TEST")));
	}
}

Eure Aufgabe ist es nun, mal wieder eine Art von Parser zu entwickeln. Wie Ihr dabei vorgeht, bleibt diesmal euch überlassen.

Die unterstützten Formate sollen Folgende sein:
  • $var wird durch den Wert des Parameters mit dem Namen var ersetzt
  • $1 wird durch den Wert des ersten übergebenen Parameters ersetzt (ACHTUNG! das ist nicht 0-basiert!)
  • ${var:Property1:Property2} wird durch den Wert von Property2 von Property1 des Parameters mit dem Namen var ersetzt
  • $$ wird durch ein einzelnes $ ersetzt (--> Escaping)

Als Lösungen ausgeschlossen ist:
String.Format(...) Extended

Gruß, Christian.
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von TheBrainiac am .
There are 10 types of people in the world:
Those, who think they understand the binary system
Those who don't even have heard about it
And those who understand "Every base is base 10"
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3430
Herkunft: Trier -> München

beantworten | zitieren | melden

Hallo,

hier mal eine lebenserhaltende Maßnahme für diesen schönen Thread.

Ich hoffe der Code erfüllt die Anforderungen, Fälle wie Parameter mit '$' im Namen oder numerischen Namen habe ich jetzt nicht weiter berücksichgt

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;

public class Parameter {
    private string m_Name;
    private object m_Value;

    public Parameter(string name, object value) {
        m_Name = name;
        m_Value = value;
    }

    public Parameter(object value) {
        m_Name = null;
        m_Value = value;
    }

    public string Name {
        get { return m_Name; }
    }

    public object Value {
        get { return m_Value; }
    }
}

public static class StringEx {
  public static string Format(string format, params Parameter[] args) {
      // Hier eure Implementierung!
    string[] tokens = format.Split(new string[]{ "$$" }, StringSplitOptions.None);
    IEnumerable<Parameter> sorted = args.OrderByDescending((p) => p.Name);
    for(int tokenIdx = 0; tokenIdx < tokens.Length; tokenIdx++)
    {
      for(int i = args.Length; i ≥ 1; i--)
      {
        tokens[tokenIdx] = tokens[tokenIdx].Replace("$" + i, args[i-1].Value.ToString());
      }
      foreach(Parameter p in sorted)
      {
        if(!String.IsNullOrEmpty(p.Name))
        {
          tokens[tokenIdx] = tokens[tokenIdx].Replace("$" + p.Name, p.Value.ToString());
        }
      }
      int start = tokens[tokenIdx].IndexOf("${");
      while(start ≥ 0)
      {
        int stop = tokens[tokenIdx].IndexOf("}", start);
        if(stop < start)
        {
          break;
        }
        string orig = tokens[tokenIdx].Substring(start, stop - start + 1);
        string[] path = orig.Substring(2, orig.Length - 3)
                            .Split(new char[]{':'}, StringSplitOptions.None);
        Parameter param = args.First((p) => p.Name == path[0]);
        if(param != null)
        {
          object o = param.Value;
          for(int i = 1; i < path.Length; i++)
          {
            o = o.GetType().InvokeMember(path[i], System.Reflection.BindingFlags.GetProperty, null, o, null);
          }
          tokens[tokenIdx] = tokens[tokenIdx].Replace(orig, o.ToString());
          stop = start;
        }
        start = tokens[tokenIdx].IndexOf("${", stop);
      }
    }
    return tokens.Aggregate((left,right) => left + "$" + right);
  }
}

public class Program {
    public static void Main() {
        Debug.Assert("This is SPARTA!" == StringEx.Format("This is $what!", new Parameter("what", "SPARTA")));
        Debug.Assert("This is SPARTA!" == StringEx.Format("This is $1!", new Parameter("SPARTA")));
        DateTime date = new DateTime(2010, 06, 12, 17, 18, 32);
        Debug.Assert("Date is: 12.6.2010, Time is: 17:18:32" == StringEx.Format("Date is: ${date:Day}.${date:Month}.${date:Year}, Time is: ${date:Hour}:${date:Minute}:${date:Second}", new Parameter("date", date)));
        Debug.Assert("17:18:32" == StringEx.Format ("${date:TimeOfDay:Hours}:${date:TimeOfDay:Minutes}:${date:TimeOfDay:Seconds}", new Parameter("date", date)));
        Debug.Assert("$test = TEST" == StringEx.Format("$$test = $test", new Parameter("test", "TEST")));
    }
}

Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
private Nachricht | Beiträge des Benutzers
TheBrainiac
myCSharp.de - Member

Avatar #avatar-3152.png


Dabei seit:
Beiträge: 832
Herkunft: /dev/null

beantworten | zitieren | melden

Hi, MarsStein.

Du bist dran!

Gruß, Christian.
There are 10 types of people in the world:
Those, who think they understand the binary system
Those who don't even have heard about it
And those who understand "Every base is base 10"
private Nachricht | Beiträge des Benutzers