`

Given n coins and a pan balance,find the only counterfeit 4

阅读更多
The Utils class is composed of some common methods:

java 代码
 
  1. package solve;  
  2.   
  3. import scale.Ball;  
  4. import scale.Scale;  
  5.   
  6. import java.util.Iterator;  
  7. import java.util.Set;  
  8.   
  9. /** 
  10.  * utility class, shared common methods. 
  11.  */  
  12. public class Utils  
  13. {  
  14.     public static Ball findGoodBall(Set ballSet)  
  15.     {  
  16.         for (Iterator it=ballSet.iterator(); it.hasNext();)  
  17.         {  
  18.             Ball ball = (Ball)it.next();  
  19.             if (ball.getStatus().equals(Ball.NORMAL)) return ball;  
  20.         }  
  21.   
  22.         return null;  
  23.     }  
  24.   
  25.     public static String convertToBallStatus(int scaleResult)  
  26.     {  
  27.         if (scaleResult == Scale.EVEN) return Ball.NORMAL;  
  28.         else if (scaleResult == Scale.HEAVIER) return Ball.HEAVIER;  
  29.         else return Ball.LIGHTER;  
  30.     }  
  31.   
  32.     public static void markStatus(Set ballSet, String status)  
  33.     {  
  34.         for (Iterator it=ballSet.iterator(); it.hasNext();)  
  35.         {  
  36.             Ball ball = (Ball)it.next();  
  37.             if (!ball.getStatus().equals(Ball.NORMAL))  
  38.             {  
  39.                 ball.setStatus(status);  
  40.             }  
  41.         }  
  42.     }  
  43. }  

The test class is as follows:

java 代码
 
  1. package solve;  
  2.   
  3. import junit.framework.TestCase;  
  4.   
  5. import java.util.Set;  
  6. import java.util.HashSet;  
  7. import java.util.Iterator;  
  8. import java.math.BigDecimal;  
  9.   
  10. import scale.Ball;  
  11. import scale.Weight;  
  12. import scale.Scale;  
  13.   
  14. /** 
  15.  * 
  16.  */  
  17. public class SolverTest extends TestCase  
  18. {  
  19.     public void test12Balls()  
  20.     {  
  21.         Set ballSet = createBallSet(124, Ball.WEIGHT_HEAVIER);  
  22.         ProblemSolver solver = new ProblemSolver(ballSet);  
  23.         solver.findWeight();  
  24.   
  25.         print(ballSet);  
  26.         System.out.println("scale usage=" + solver.getScale().getNumOfTrials());  
  27.         verifyResult(ballSet, solver.getScale());  
  28.     }  
  29.   
  30.     public void test13Balls()  
  31.     {  
  32.         Set ballSet = createBallSet(135, Ball.WEIGHT_HEAVIER);  
  33.         ProblemSolver solver = new ProblemSolver(ballSet);  
  34.         solver.findWeight();  
  35.   
  36.         print(ballSet);  
  37.         System.out.println("scale usage=" + solver.getScale().getNumOfTrials());  
  38.         verifyResult(ballSet, solver.getScale());  
  39.     }  
  40.   
  41.     public void testLoops()  
  42.     {  
  43.         int start = 500;  
  44.         int end = 1000;  
  45.         for (int i=start; i
  46.         {  
  47.             for (int j=0; j
  48.             {  
  49.                 Set ballSet = createBallSet(i, j, Ball.WEIGHT_HEAVIER);  
  50.                 ProblemSolver solver = new ProblemSolver(ballSet);  
  51.                 solver.findWeight();  
  52.   
  53.                 System.out.println("num of balls=" + ballSet.size());  
  54.                 //print(ballSet);  
  55.                 System.out.println("scale usage=" + solver.getScale().getNumOfTrials());  
  56.                 System.out.println("-------------------------------------------------");  
  57.                 verifyResult(ballSet, solver.getScale());  
  58.             }  
  59.         }  
  60.     }  
  61.     private Set createBallSet(int size, int badBallIndex, Weight weight)  
  62.     {  
  63.         Set ballSet = new HashSet();  
  64.         for (int i=0; i
  65.         {  
  66.             Weight weight1;  
  67.             if (i == badBallIndex) weight1 = weight;  
  68.             else weight1 = Ball.WEIGHT_NORNAL;  
  69.             Ball ball = new Ball("" + i, weight1);  
  70.             ballSet.add(ball);  
  71.         }  
  72.   
  73.         return ballSet;  
  74.     }  
  75.   
  76.     private void verifyResult(Set ballSet, Scale scale)  
  77.     {  
  78.         for (Iterator it=ballSet.iterator(); it.hasNext();)  
  79.         {  
  80.             Ball ball = (Ball)it.next();  
  81.             assertTrue(ball.validate());  
  82.         }  
  83.   
  84.         // now computer the theoretic limit number of balls <=(3^n-3)/2, upper limit.  
  85.         // Number of balls  3  12  39  120  363  1092 3279 .....  
  86.         // Number of trials 2  3   4   5    6    7    8  
  87.         BigDecimal aa = new BigDecimal(Math.log(2 * ballSet.size() + 3));  
  88.         BigDecimal bb = aa.divide(new BigDecimal(Math.log(3)), BigDecimal.ROUND_UP);  
  89.         int limit = (int)Math.ceil(bb.floatValue());  
  90.         assertTrue("limit=" + limit + ", trials=" + scale.getNumOfTrials(), limit >= scale.getNumOfTrials());  
  91.     }  
  92.   
  93.     private void print(Set ballSet)  
  94.     {  
  95.         for (Iterator it=ballSet.iterator(); it.hasNext();)  
  96.         {  
  97.             Ball ball = (Ball)it.next();  
  98.             System.out.println(ball.toString());  
  99.         }  
  100.     }  
  101. }  

The testing is a little hard because of the recursion. Any change requires a full test. The testing checks whether the status flags we set matches the weights from the input and the times of weighings stays inside the limit.
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics