Finding a defective ball out of 12 in three weighings
/*
Methodology for finding the odd ball in three weighings:
Name the balls 1,2,3...12.
In the following paragraphs,
> means heavier
= means equal
< means lighter
(1,2,3,4) means the group of 4 balls.
- in the left margin means the first weighing
-- second weighing
*-- third and final weighing
=> inference
-(1,2,3,4)=(5,6,7,8) => odd one in (9,10,11,12)
-- (9,10)=(11,8) => odd one is 12
*-- (12)>(1) => 12 is heavier
*-- (12)>(1) => 12 is lighter
-- (9,10)>(11,8) => 11 lighter, or, one of 9 or 10 heavier
*-- (9)>(10) => 9 heavier
*-- (9)<(10) => 10 heavier
*-- (9)=(10) => 11 lighter
-- (9,10)<(11,8) => 11 heavier, or, one of 9 or 10 lighter
*-- (9)>(10) => 10 lighter
*-- (9)<(10) => 9 lighter
*-- (9)=(10) => 11 heavier
-(1,2,3,4)>(5,6,7,8) => one of 1,2,3,4 heavier, or, one of 5,6,7,8 lighter
-- (1,2,5)=(3,6,9) => 4 is heavier, or 7 is light, or 8 is light
*-- (7)=(8) => 4 is heavier
*-- (7)>(8) => 8 is light
*-- (7)<(8) => 7 is light
-- (1,2,5)>(3,6,9) => one of 1,2 heavy, or 6 light
*-- (1)=(2) => 6 is light
*-- (1)>(2) => 1 is heavier
*-- (1)<(2) => 2 is heavier
-- (1,2,5)<(3,6,9) => 5 light, or, 3 heavy
*-- (1)=(5) =>3 is heavy
*-- (1)>(5) =>5 is light
-(1,2,3,4)<(5,6,7,8) => one of 1,2,3,4 is lighter, or, one of 5,6,7,8 is heavier
-- (1,2,5)=(3,6,9) => 4 is lighter, or 7 is heavier, or 8 is heavier
*-- (7)=(8) => 4 is lighter
*-- (7)>(8) => 8 is heavier
*-- (7)<(8) => 7 is heavier
-- (1,2,5)>(3,6,9) => 5 is heavier, or 3 is lighter
*-- (1)=(5) => 3 is lighter
*-- (1)<(5) => 5 is heavier
-- (1,2,5)<(3,6,9) => 1,2 ligher, 6 heavier
*-- (1)=(2) => 6 is heavier
*-- (1)>(2) => 2 is lighter
*-- (1)<(2) => 1 is lighter
As the reader can see, there are 24 third and final weighings, reflecting the 24 possible outcomes.
Reference:
http://www.newton.dep.anl.gov/newton/askasci/1995/math/MATH007.HTM
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.lang.Math.*;
import java.math.BigInteger;
public class Weighing extends JApplet implements ActionListener{
JTextArea tInstructions;
//JButton bL=new JButton("L"), bR=new JButton("R");
JButton bBalls[]=new JButton[12];
JButton bWeigh=new JButton("WEIGH");
JButton bAnswer=new JButton("ANSWER");
JButton bReset=new JButton("RESET");
JTextArea tDisplay=new JTextArea(600,100);
Color red=new Color(255,200,200);
Color blue=new Color(200,200,255);
Color white=new Color(255,255,255);
Color col[]={white,red,blue};
int sizeX=50, sizeY=50;
String Instr="Each of 12 balls of identical appearance has the same weight except for an odd\none, which can be heavier or lighter than the other ones.\nGiven a balance, try to find the odd ball with a minimum number of weighings.\nNote: successively clicking on the boxes will put balls on left side (pink),\nright side (blue) or off balance\n";
Container c=getContentPane();
int side[]=new int[12]; // 0=off balance, 1=left, 2=right;
int weight[]=new int[12];
int weighCount;
final int NORMAL_WEIGHT=10;
public void makeBoxes(JButton b[],int n, int origX, int origY, boolean visible){
// initialize an array of buttons
for(int i=0; i1)left+=";"; left+=i+1;
} else {
sum-=weight[i];
if(right.length()>1)right+=";"; right+=i+1;
}
}
weighCount++;
left+=")"; right+=")";
if(sum==0)relation=" is equal to ";
else if(sum<0)relation=" is lighter than ";
else relation=" is heavier than ";
tDisplay.append(left+relation+right+"\n");
}
public void init(){
int yInst=90, yMarg=10;
c.setLayout(null);
tInstructions=new JTextArea();
tInstructions.setText(Instr);
tInstructions.setEditable(false);
tInstructions.setLocation(2*sizeX,0);
tInstructions.setSize(450,yInst-10);
c.add(tInstructions);
makeBoxes(bBalls,12,sizeX/2,yInst,true);
makeBox(bWeigh,sizeX*2,yInst+1*(sizeY+yMarg),true);
bWeigh.setSize(2*sizeX,sizeY);
bWeigh.setToolTipText("Make another weighing");
makeBox(bAnswer,sizeX*5,yInst+1*(sizeY+yMarg),true);
bAnswer.setSize(2*sizeX,sizeY);
bAnswer.setToolTipText("Display answer, press reset to start new game");
makeBox(bReset,sizeX*8,yInst+1*(sizeY+yMarg),true);
bReset.setSize(2*sizeX,sizeY);
bReset.setToolTipText("New Game");
ScrollPane scr=new ScrollPane();
scr.add(tDisplay);
scr.setSize(700,150);
scr.setLocation(0,yInst+2*(sizeY+10));
tDisplay.setEditable(false);
c.add(scr);
newGame();
setSize(700,380);
setVisible(true);
showStatus("Choose balls to weigh");
}
public void actionPerformed(ActionEvent event){
if(event.getSource()==bAnswer){
displayAnswer();
return;
}
if(event.getSource()==bReset){
newGame();
}
if(event.getSource()==bWeigh){
weighBalls();
resetBalls(side);
}
int nBall;
for(nBall=0; nBall<12;nBall++){
if(event.getSource()==bBalls[nBall]){
side[nBall]=(side[nBall]+1)%3;
bBalls[nBall].setBackground(col[side[nBall]]);
return;
}
}
}
}