Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » Rätselecke » 5. Sonntagsrätsel

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: [ 1 ] > 2 <
010
15.09.2002, 19:44 Uhr
Christian
C/C++ Master
(Operator)


Hallo!

Mein Programm liefert 88 Lösungen. Die Funktion Station wird rekursiv aufgerufen:


C++:

/*******************************************************************************
/ Das Haus vom Nikolaus
/ gesucht: Anzahl der Möglichkeiten das Haus zu zeichnen
/ Skizze:
/
/                           *5
/                          * *
/                         *   *
/                       3*******4
/                        *     *
/                        *     *
/                        *     *
/                       1*******2
/*******************************************************************************/


int Gesamtzahl = 0;
int Stationen[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
int Wege[5][4] = {        2, 3, 4, 0,
                        1, 3, 4, 0,
                        1, 2, 4, 5,
                        1, 2, 3, 5,
                        3, 4, 0, 0};




bool WegTesten()
{
    int Anzahl = 0;
    
    while(Stationen[Anzahl] != 0)
        Anzahl ++;
    
    if(Anzahl <= 2)
        return true;

    
    int zahl1, zahl2;

    for(int index = 0; index < Anzahl; index ++)
    {
        zahl1 = Stationen[index];
        zahl2 = Stationen[index + 1];

        for(int r = index + 2; r < Anzahl - 1; r++)    
        {
            if((Stationen[r] == zahl1) && (Stationen[r+1] == zahl2))
                return false;
        }

        for(r = index +1; r < Anzahl; r++)
        {
            if( (Stationen[r] == zahl2) && (Stationen[r+1] == zahl1))
                return false;
        }
    }
    return true;
}



bool Station(int jetzt)
{
    int wegindex = 0;
    
    while( (Wege[Stationen[jetzt - 1] - 1][wegindex] != 0) && (wegindex <= 3))
    {
        int posway = Wege[Stationen[jetzt - 1] - 1][wegindex];
    
        Stationen[jetzt] = posway;
        if(WegTesten() && (jetzt == 8))
        {
            /*cout << "Lösung gefunden!" << endl;
            for(int w = 0; w <= 8; w++)
            {
                cout << "Station: " << w +1 << ": " << Stationen[w] << endl;
            }*/

            
            
            Gesamtzahl ++;
            Stationen[jetzt] = 0;
            return false;
        }

    
        if(WegTesten() && (jetzt <= 8))
        {
        
            Station(jetzt + 1);
        }
        

        wegindex ++;        
    }
    Stationen[jetzt] = 0;
    return (false);
}



int main(int argc, char* argv[])
{
    
        
    for(int Startpunkt = 1; Startpunkt <= 5; Startpunkt ++)
    {
        Stationen[0] = Startpunkt;
        Station(1);
        cout << "Begin bei Punkt " << Startpunkt << ": Anzahl der Wege: " << Gesamtzahl << endl;
        Gesamtzahl = 0;
    }
    
    return 0;
}



Mein Programm achtet nicht darauf, ob die Lösung rückwärts schonmal da war.
Da man ja jede Lösung rückwarts nochmal finden kann gibt es also 44.


Grüße
--
Grüße, Christian

Dieser Post wurde am 15.09.2002 um 19:53 Uhr von Christian editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
011
18.09.2002, 09:45 Uhr
virtual
Sexiest Bit alive
(Operator)


Hallo Christian,

hier die im anderen Thread angesprochene Nicht-Rekursive Loesung. STL rules!
Habe auch 44 Moeglichkeiten gefunden.

C++:
#include <iostream>
#include <string>
#include <map>
#include <algorithm>

// Die einzelnen Striche des Hauses seien wie folgt durchnummeriert:
//                            /\
//                           /  \
//                        0 /    \ 1
//                         /  2   \
//                        +-------+
//                        |\     /|
//                        | \4  / |
//                        |  \ /  |
//                      3 |   X   | 6
//                        |  / \  |
//                        | /5  \ |
//                        |/     \|
//                        +-------+
//                            7

typedef char zeichnung_t[9]; // Repraesentiert eine Zeichnung vom Haus
typedef std::map<std::string, bool> loesungen_t; // Map mit allen Zeichnungen, vlaue==1 -> Gueltig

//
// jeder Strich ist gerichtet, d.h an jedem Endounkt geht es mit 1..N anderen Strichen weiter.
// Diese Struktur dient dazu, diese Nachbarschaftsverältnisse zu beschreiben:
struct nachbarn_t
{
    zeichnung_t nachbarn[2];
};


//
// Prüft, ob eine Zeichnung gültig ist, ob ohne absetzen gezeichnet werden kann
//
bool
ist_zeichnung_gueltig(
    const zeichnung_t zeichnung)
{
    //
    // Dieses Array beschreibt alle möglichen Verbindungen. zB. ist Strich 1 an dem
    // einen Ende mit Strich 0, am anderen mit den Strichen 2, 5, und 6 verbunden.
    //
    const nachbarn_t verbindungen[] = {
        { "234", "1" },         // 0
        { "0", "256" },         // 1
        { "034", "156" },       // 2
        { "024", "57"},         // 3
        { "023", "67"},         // 4
        { "37", "126"},         // 5
        { "125", "47"},         // 6
        { "35", "46" }          // 7
    };

    //
    // Prüfe alle striche
    //
    for(int i=1; i<8; ++i)
    {
        int richtung;

        //
        // Zunächst wird geprüft, ob die Striche zeichnung[ i ] und zeichnung[i-1] überhaupt
        // verbunden sind. In richtung steht am ende 2, wenn keine Verbindung da ist, ansonsten
        // entweder 0 oder 1
        //
        for(richtung=0; richtung<2; ++richtung)
        {
            if (std::strchr(verbindungen[zeichnung[ i ]-'0'].nachbarn[richtung], zeichnung[i-1]))
            {
                break;
            }

        }
        if (2 == richtung) return false;

        //
        // Nun wird geprüft, ob es auch korrekt weiter geht. dh von Strich zeichnung[ i ] mit
        // zeuichnung[i-1] über die Richtung 0 miteinander verbunden ist, dann muss zeichnung[ i ]
        // über Richtung (1-richtung) mit zeichung[i+1] verbunden sein-
        if (i<7)
        {
            richtung = 1-richtung;
            if (!std::strchr(verbindungen[zeichnung[ i ]-'0'].nachbarn[richtung], zeichnung[i+1]))
                return false;
        }
    }

    return true;
}

int
main()
{
    zeichnung_t zeichnung = "01234567";
    loesungen_t loesungen;
    zeichnung_t umgekehrt;
    bool gueltig = false;

    //
    // Hauptschleife zur berechnung - Gehe alle Kombinationen durch,
    // Wie das Haus gezeichnet werden koennte.
    //
    do
    {
        //
        // Pruefe, ob umgekehrte Zeichnung schon getestet
        // Wenn die Zeichnung auch umgekehrt noch nicht getestet wurde,
        // wird der naechste if - Block durchlaufen
        //
        std::reverse_copy(zeichnung, zeichnung+8, umgekehrt);
        umgekehrt[8] = 0;
        gueltig = false;
        if (loesungen.end() == loesungen.find(umgekehrt))
        {
            //
            // Prüfe zeichnung auf Gueltigkeit
            //
            gueltig = ist_zeichnung_gueltig(zeichnung);
        }

        //
        // Trage ergebnis in map ein
        //
        loesungen.insert(loesungen_t::value_type(zeichnung, gueltig));
    }while (std::next_permutation(zeichnung, zeichnung+8));

    //
    // Ausgabe aller gueltigen Zeichnungen
    //
    for(loesungen_t::const_iterator i=loesungen.begin(); loesungen.end()!=i; ++i)
    {
        if (i->second) std::cout << i->first << std::endl;
    }
}



--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 18.09.2002 um 09:46 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
012
18.09.2002, 09:50 Uhr
virtual
Sexiest Bit alive
(Operator)


Wie viele Moeglichkeiten es woh gibt "Das-Ist-Das-Haus-Vom-Ni-Ko-Laus-Mit-Klo-Sett-und-Fahne-oben-Drauf" zu zeichnen ???
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
013
18.09.2002, 11:39 Uhr
Christian
C/C++ Master
(Operator)


Hi virtual!

Mit deinem Programm checkst du alle möglichen Permutationen durch. Genau eben das tut mein Programm ja nicht, es hält sich stets an die Wegeregel mit dem Wege Array.
Also next_permutation find ich super, diese Fkt. kannte ich bis jetzt nicht.

Grüße
--
Grüße, Christian
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
014
18.09.2002, 14:07 Uhr
virtual
Sexiest Bit alive
(Operator)


Es gibt uebrigens auch prev_permutation. Es lohnt sich, die Algorithmen der STL naeher zu betrachten .
Mir fehlt jetzt die Zeit, noch eine weitere - dann aber deutlich komplizierte Loesung zu entwicklen, die auf Deinen Einwand eingeht: man kann auch nicht-rekursiv die deinige Loesung nachprogrammieren. Der wesentliche teil dabei duerfte die Verwendung einer std::stack Variable sein, die praktisch die informationen enthält, die du normalerweise durch die rekursiven Funktionsaufrufe geschenkt bekommst. Aber - und da sind wir uns glaube ich einig - die rekursive Lösung ist dann schon eher elegant.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 18.09.2002 um 14:08 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
015
19.09.2002, 13:57 Uhr
NemoEimi



Ich habe jetzt einmal meine Lösung in ein einfaches Applet verwandelt, das meine Häuschen auch zeichnet.
Bei Gelegenheit werde ich mal schauen, warum genau ich eine andere Anzahl von Lösungen bekomme als die anderen hier. Die Skizze von virtual sieht ja in etwa aus wie mein Haus .

Grüße,
NemoEimi

Dieser Post wurde am 19.09.2002 um 13:58 Uhr von NemoEimi editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
016
20.09.2002, 13:38 Uhr
Christian
C/C++ Master
(Operator)


Hallo NemoEimi!

Das liegt doch daran, dass es bei dir erlaubt ist, in der Mitte des Hauses die Richtung zu wechseln. Bei unseren Lösungen muss man die Richtung beibehalten.

Grüße
--
Grüße, Christian
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: [ 1 ] > 2 <     [ Rätselecke ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: