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 }