001    package de.hska.java.aufgaben.kontrollstrukturen;
002    
003    /**
004     * Raetselloeser ist verantwortlich für das Lösen aussagenlogisch
005     * formulierter Rätsel. Dazu werden systematisch alle Kombinationen
006     * aussagenlogischer Variablen aufgezählt, bis die Formel wahr ist.
007     * 
008     * 
009     * <p>
010     *   <a href="http://www.home.hs-karlsruhe.de/~pach0003/informatik_1/aufgaben/kontrollanweisungen.html#raetselloeser">Zurück zum Aufgabentext</a>
011     * </p>
012     * 
013     * @author Christian Pape
014     *
015     */
016    public class Raetselloeser {
017    
018            /**
019             * Probiert alle Kombinationen boolescher Variablen aus,
020             * bis die {@link #raetselEvaluieren(boolean, boolean, boolean)}
021             *  <code>true</code> zurück gibt. Danach wird
022             *  die Lösung angezeigt.
023             */
024            public static void main(String [] argv) {
025                    boolean a = false;
026                    boolean b = false;
027                    boolean c = false;
028                    int z = 0;
029                    
030                    do {
031                            a = (z % 2) == 1;
032                            b = (z / 2 % 2) == 1;
033                            c = (z / 4 % 2) == 1;
034                            z++;
035                    } while ( z < 8 & ! raetselEvaluieren(a, b, c) );
036                    
037                    if (z < 8) {
038                            loesungAnzeigen(a, b, c);
039                    } else {
040                            System.out.println("Es gibt keine Lösung");
041                    }
042            }
043            
044            /**
045             * Ein Rätsel von Raymond Smullyan.
046             * Es geht dabei um einen Hutmacher, einen Schnapphase und eine (Hasel-)Maus.
047             * Unter diesen drei Verdächtigen  gibt es einen Dieb.
048             * Die Ermittlungen haben folgendes ergeben:
049             * <ul>
050             * <li>Genau einer von den drei ist der Dieb</li>
051             * <li>Unschuldige sagen immer die Wahrheit</li>
052             * <li>Der Schnapphase sagt, dass der Hutmacher unschuldig ist</li>
053             * <li>Der Hutmacher sagt, dass die Haselmaus unschuldig ist</li>
054             * </ul>
055             * Wir formalisieren diesen Sachverhalt mit drei aussagenlogischen Variablen <code>hutmacher</code>,
056             * <code>schnapphase</code> und <code>maus</code>. Diese sollen genau dann
057             * <code>true</code> sein , wenn die entsprechende Person der Dieb ist.
058             * Wir verwenden die Java-Operatore !, &, ^, | und => als Implikation.
059             * Die resultierenden, konjunktiv zu verknüpfende Formeln sind:
060             * <ul>
061             * <li>hutmacher ^ schnapphase ^ maus</li>
062             * <li>(hutmacher => ! (schnapphase | maus))
063             *     & (schnapphase => ! (hutmacher | maus))
064             *     & (maus => ! (hutmacher | schnapphase))</li>
065             * <li>schnapphase => ! hutmacher</li>
066             * <li>hutmacher => ! maus</li>
067             * </ul>
068             * Die Implikation <code>A => B</code> kann durch
069             * <code>! A | B</code> ersetzt werden.
070             */
071            public static boolean raetselEvaluieren(boolean hutmacher, boolean schnapphase, boolean maus) {
072                    return (hutmacher ^ schnapphase ^ maus)
073                         & (! hutmacher | ! (schnapphase | maus))
074                         & (! schnapphase | ! (hutmacher | maus))
075                         & (! maus | ! (hutmacher | schnapphase))
076                         & (schnapphase | ! hutmacher)
077                         & (hutmacher | ! maus);
078            }
079            
080            /**
081             * Gibt den Dieb auf den Bildschirm aus.
082             */
083            public static void loesungAnzeigen(boolean hutmacher, boolean schnapphase, boolean maus) {
084                    System.out.print("Der Dieb ist: ");
085                    if (hutmacher) {
086                            System.out.println("Hutmacher");
087                    }
088                    if (schnapphase) {
089                            System.out.println("Schnapphase");
090                    }
091                    if (maus) {
092                            System.out.println("Maus");
093                    }
094            }
095    }