20-CS-694 Advanced Programming Techniques Spring 2012
Exceptions

Interfaces, Exceptions, Graphics, Animation, Threads, Reflection, Networking, RMI, JDBC, JNI

    Previous     Next     All lectures        Code     Exception Hierarchy    

An Example - A Logic Puzzle

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import java.applet.*;

// Kaloton Puzzle
//   The Kalotans are a tribe with a peculiar quirk: their 
//   females always tell the truth.  Their males never make 
//   two consecutive true statements, or two consecutive 
//   untrue statements.
//
//   An anthropologist (let's call him Worf) has begun to 
//   study them.   Worf does not yet know the Kalotan language.  
//   One day, he meets a Kalotan (heterosexual) couple and 
//   their child Kibi (also called "kid").  Worf asks the kid:
//   "Are you a boy?"  The kid answers in Kalotan, which of 
//   course Worf doesn't understand.  Worf turns to the parents 
//   (who know English) for explanation.  One of them (parent1) 
//   says: "Kibi said: `I am a girl.'" The other (parent2) adds:
//    "Kibi is a boy.  Kibi lied."
//
//   Solve for the sex of the parents and Kibi.
//
//   Let variable parent1 be the first responding parent,
//   let variable parent2 be the second responding parent,
//   let variable kid be the sex of Kibi
//   let variable kid_said be the response of Kibi to Worf's question
//   let variable kid_lied be true iff Kibi lied
class KalotanPuzzle extends Puzzle implements Variable {
   Variable parent1, parent2, kid, kid_lied, kid_said;
   PuzzleFrame f;

   public KalotanPuzzle (PuzzleFrame f) {  this.f = f; }

   public boolean xor (boolean exp1, boolean exp2) {
      return (!exp1 && exp2) || (exp1 && !exp2);
   }

   public void checkit () throws Up, Out {
      // Parents must be of different sex
      assert_(!parent1.value().equals(parent2.value()));
      // Definition of lied
      assert_(xor(kid_said.value().equals(kid.value()), 
	  kid_lied.value().equals("true")));
      // If parent1 is female, then Kibi must have said female,
      // according to parent1, and either Kibi is male or Kibi lied,
      // according to parent2.  If parent1 is male, then Kibi must be
      // male and must have lied, according to parent2.
      assert_(parent1.value().equals("female") ?
	      (kid_said.value().equals("female") && 
	       (xor(kid.value().equals("male"),
	    kid_lied.value().equals("true")))) :
	      (kid.value().equals("male") &&
      kid_lied.value().equals("true")));

      f.out.append("Parent1:"+parent1.value()+"   "+
			 "Parent2:"+parent2.value()+"   "+
			 "Kid:"+kid.value()+"\n");
      throw new Out();
   }

   public void solve () {
      try { 
         parent1  = new Choose("male female", this);
         parent2  = new Choose("male female", parent1);
         kid      = new Choose("male female", parent2);
         kid_lied = new Choose("true false", kid);
         kid_said = new Choose("male female", kid_lied);
         kid_said.checkit(); 
      } 
      catch (Up up) {
         f.out.append("No solution\n");
      }
      catch (Out out) { 
         f.out.append("Done\n"); 
      }
   }
}

/*** The following common to all problems of this type  ***/
interface Variable {  
   void checkit () throws Up, Out;  String value ();  
}

class Up extends Exception { }

class Out extends Exception { }

class Choose implements Variable {
   Variable next_for;
   String [] strs;
   String val;
   int n;
   
   public Choose(String s, Variable next_for) {  
      this.next_for = next_for;
      StringTokenizer t = new StringTokenizer(s," ");
      n = t.countTokens();
      strs = new String[n];
      for (int i=0 ; i < n ; i++) strs[i] = t.nextToken();
   }

   public String value () { return val; }

   public void checkit () throws Up, Out {
      for (int i=0 ; i < n ; i++)  {
         val = strs[i];
         try {  next_for.checkit();  } catch (Up up) { }
      }
      throw new Up();
   }
}

class Puzzle {
   public String value () { return null; }
   public void assert_ (boolean e) throws Up { 
      if (!e) throw new Up(); 
   }
}

/*** end of the common code section  ***/

class PuzzleFrame 
   extends JFrame implements ActionListener {
   JTextArea out;
   JButton button;

   public PuzzleFrame () {
      setLayout(new FlowLayout());
      add(new JScrollPane(out = new JTextArea(16,30)));
      add(button = new JButton("Press Me"));
      button.addActionListener(this);
      out.setFont(new Font("TimesRoman", Font.PLAIN, 18));
   }

   public void doit() {
      KalotanPuzzle kalotan = new KalotanPuzzle(this);
      kalotan.solve();
   }

   public void actionPerformed (ActionEvent evt) {  
      doit(); 
   }
}

public class puzzle 
   extends Applet implements ActionListener {
   JButton go;

   public void init () {
      setLayout(new BorderLayout());
      setBackground(new Color(255,255,223));
      add("Center", go = new JButton("Applet"));
      go.addActionListener(this);
   }

   public void actionPerformed (ActionEvent evt) {
      PuzzleFrame hf = new PuzzleFrame();
      hf.setSize(550,450);
      hf.setVisible(true);
   }
}
 -  The Kalotans are a tribe with a peculiar quirk: their males always tell the truth. Their females never make two consecutive true statements, or two consecutive untrue statements.

An anthropologist (let's call him Worf) has begun to study them. Worf does not yet know the Kalotan language. One day, he meets a Kalotan (heterosexual) couple and their child Kibi (also called "kid"). Worf asks the kid: ``Are you a boy?'' The kid answers in Kalotan, which of course Worf doesn't understand.

Worf turns to the parents (who know English) for explanation. One of them says: "Kibi said: `I am a boy.'" The other adds: "Kibi is a girl. Kibi lied."

Solve for the sex of the parents and Kibi.

Let variable prnt1 be the first responding parent, let variable prnt2 be the second responding parent, let variable kid be the sex of Kibi, let variable kid-lied be true if and only if Kibi lied.