在前一篇随笔谋杀脑细胞:13球称重问题及我的解法中我描述了一下我的解法,但有好几个朋友都说我的解法有些问题, 说的我都信心动摇.. 于是把写过的一个验证我的解法的程序修改一下再跑一遍... 其实吧,当时是想写自动求解的程序的, 没思路,没写成,只好改成一个验证程序了. (像UnitTest不? 嘿嘿)
代码送上:
Main Console App
1
using
System;
2 using System.Linq;
3
4 class Program
5 {
6 static void Main( string [] args)
7 {
8 var resolver = new Ball13Resolver();
9 IBall13Simulator simulator = null ;
10 for ( int i = 2 ; i <= 27 ; i ++ )
11 {
12 int wishBadBall = i / 2 ;
13 bool wishLighter = (i & 1 ) == 0 ;
14 simulator = new Ball13Simulator(wishBadBall, wishLighter);
15 bool ? isLighter = null ;
16 int badBall = resolver.Resolve(simulator, out isLighter);
17
18 if (wishBadBall != badBall) // Incorrect detection.
19 {
20 Console.ForegroundColor = ConsoleColor.Red;
21 }
22 else if (isLighter.HasValue && isLighter == wishLighter) // Correct detection.
23 {
24 Console.ForegroundColor = ConsoleColor.DarkGreen;
25 }
26 else // Correctly detected the bad ball, but could not tell or telled a wrong result that the bad ball is lighter or heavier.
27 {
28 Console.ForegroundColor = ConsoleColor.Yellow;
29 }
30
31 Console.WriteLine( " Wish: {0}:{1} \t\tGet:{2}:{3} " ,
32 wishBadBall,
33 wishLighter ? " Lighter " : " Heavier " ,
34 badBall,
35 isLighter.HasValue ? (isLighter.Value ? " Lighter " : " Heavier " ) : " Unknown " ,
36 simulator.TestedCount);
37 }
38
39 Console.ResetColor();
40 Console.Read();
41 }
42 }
2 using System.Linq;
3
4 class Program
5 {
6 static void Main( string [] args)
7 {
8 var resolver = new Ball13Resolver();
9 IBall13Simulator simulator = null ;
10 for ( int i = 2 ; i <= 27 ; i ++ )
11 {
12 int wishBadBall = i / 2 ;
13 bool wishLighter = (i & 1 ) == 0 ;
14 simulator = new Ball13Simulator(wishBadBall, wishLighter);
15 bool ? isLighter = null ;
16 int badBall = resolver.Resolve(simulator, out isLighter);
17
18 if (wishBadBall != badBall) // Incorrect detection.
19 {
20 Console.ForegroundColor = ConsoleColor.Red;
21 }
22 else if (isLighter.HasValue && isLighter == wishLighter) // Correct detection.
23 {
24 Console.ForegroundColor = ConsoleColor.DarkGreen;
25 }
26 else // Correctly detected the bad ball, but could not tell or telled a wrong result that the bad ball is lighter or heavier.
27 {
28 Console.ForegroundColor = ConsoleColor.Yellow;
29 }
30
31 Console.WriteLine( " Wish: {0}:{1} \t\tGet:{2}:{3} " ,
32 wishBadBall,
33 wishLighter ? " Lighter " : " Heavier " ,
34 badBall,
35 isLighter.HasValue ? (isLighter.Value ? " Lighter " : " Heavier " ) : " Unknown " ,
36 simulator.TestedCount);
37 }
38
39 Console.ResetColor();
40 Console.Read();
41 }
42 }
Simulate the balance
public
interface
IBall13Simulator
{
char Test( int [] left, int [] right);
int BadBallNumber { get ; }
int TestedCount { get ; }
bool IsBadBallLighter { get ; }
}
public class Ball13Simulator : IBall13Simulator
{
private int _badBall;
private bool _isBadBallLighter;
private int _testedCount;
public Ball13Simulator( int badBallNum, bool isBadBallLighter)
{
this ._badBall = badBallNum;
this ._isBadBallLighter = isBadBallLighter;
this ._testedCount = 0 ;
}
#region IBall13Simulator Members
public char Test( int [] left, int [] right)
{
this ._testedCount ++ ;
char result = ' X ' ;
if (left == null || left.Length == 0 || right == null || right.Length == 0 || left.Length != right.Length)
{
throw new Exception( " Input error. " );
}
if (left.Contains( this .BadBallNumber))
{
result = IsBadBallLighter ? ' < ' : ' > ' ;
}
else if (right.Contains( this .BadBallNumber))
{
result = IsBadBallLighter ? ' > ' : ' < ' ;
}
else
{
result = ' = ' ;
}
return result;
}
public int BadBallNumber
{
get { return this ._badBall; }
}
public bool IsBadBallLighter
{
get { return this ._isBadBallLighter; }
}
public int TestedCount
{
get { return _testedCount; }
}
#endregion
}
{
char Test( int [] left, int [] right);
int BadBallNumber { get ; }
int TestedCount { get ; }
bool IsBadBallLighter { get ; }
}
public class Ball13Simulator : IBall13Simulator
{
private int _badBall;
private bool _isBadBallLighter;
private int _testedCount;
public Ball13Simulator( int badBallNum, bool isBadBallLighter)
{
this ._badBall = badBallNum;
this ._isBadBallLighter = isBadBallLighter;
this ._testedCount = 0 ;
}
#region IBall13Simulator Members
public char Test( int [] left, int [] right)
{
this ._testedCount ++ ;
char result = ' X ' ;
if (left == null || left.Length == 0 || right == null || right.Length == 0 || left.Length != right.Length)
{
throw new Exception( " Input error. " );
}
if (left.Contains( this .BadBallNumber))
{
result = IsBadBallLighter ? ' < ' : ' > ' ;
}
else if (right.Contains( this .BadBallNumber))
{
result = IsBadBallLighter ? ' > ' : ' < ' ;
}
else
{
result = ' = ' ;
}
return result;
}
public int BadBallNumber
{
get { return this ._badBall; }
}
public bool IsBadBallLighter
{
get { return this ._isBadBallLighter; }
}
public int TestedCount
{
get { return _testedCount; }
}
#endregion
}
My Resolver
public
class
Ball13Resolver
{
public int Resolve(IBall13Simulator simulator, out bool ? isLighter)
{
#region Draft
/*
1,2,3,4 v 5,6,7,8
=
1,2,3 v 9,10,11
= # Bad in(12,13)
1 v 12
= @ 13 Bad
< @ 12 Bad #wBad > wGood
> @ 12 Bad #wBad < wGood
> #Bad in(9, 10, 11), wBad < wGood
9 v 10
= @ 11 Bad
< @ 9 Bad
> @ 10 Bad
< #Bad in(9, 10, 11), wBad > wGood
9 v 10
= @ 11 Bad
< @ 10 Bad
> @ 9 Bad
< # Bad in (1-8); (9 - 13) Good
1,2,3,5,6 v 9,10,11,12,13
= #Bad in(4,7,8), (Bad=4 wB<wG || Bad in (7,8) wB>wG)
7 v 8
= @ Bad = 4 #wB < wG
< @ Bad = 8
> @ Bad = 7
< #Bad in(1,2,3), wBad < wGood
$((1,2,3),<)
> #Bad in(5,6), wBad > wGood
$((5,6),>)
> #The opposite to '<'
*/
#endregion
int badBall = 0 ;
isLighter = null ;
switch (simulator.Test( new int [] { 1 , 2 , 3 , 4 }, new int [] { 5 , 6 , 7 , 8 }))
{
case ' = ' : // Bad in 9 - 13
switch (simulator.Test( new int [] { 1 , 2 , 3 }, new int [] { 9 , 10 , 11 }))
{
case ' = ' : // Bad in 12,13
badBall = solve2( new int [] { 12 , 13 }, 1 , out isLighter, simulator);
break ;
case ' < ' : // Bad in 9,10,11, Heavier
isLighter = false ;
badBall = solve3( new int [] { 9 , 10 , 11 }, false , simulator);
break ;
case ' > ' : // Bad in 9,10,11, Lighter
isLighter = true ;
badBall = solve3( new int [] { 9 , 10 , 11 }, true , simulator);
break ;
}
break ;
case ' < ' :
switch (simulator.Test( new int [] { 1 , 2 , 3 , 5 , 6 }, new int [] { 9 , 10 , 11 , 12 , 13 }))
{
case ' = ' : // Bad in(4,7,8), (Bad=4 wB<wG || Bad in (7,8) wB>wG)
badBall = solve3( new int [] { 7 , 8 , 4 }, false , simulator);
isLighter = badBall == 4 ;
break ;
case ' < ' : // Bad in(1,2,3), wBad < wGood
isLighter = true ;
badBall = solve3( new int [] { 1 , 2 , 3 }, true , simulator);
break ;
case ' > ' : // Bad in(5,6), wBad > wGood
isLighter = false ;
badBall = solve2( new int [] { 5 , 6 }, false , simulator);
break ;
}
break ;
case ' > ' : // The opposite to '<'
switch (simulator.Test( new int [] { 5 , 6 , 7 , 1 , 2 }, new int [] { 9 , 10 , 11 , 12 , 13 }))
{
case ' = ' : // Bad in(8,3,4), (Bad=8 wB<wG || Bad in (3,4) wB>wG)
badBall = solve3( new int [] { 3 , 4 , 8 }, false , simulator);
isLighter = badBall == 8 ;
break ;
case ' < ' : // Bad in(5,6,7), wBad < wGood
isLighter = true ;
badBall = solve3( new int [] { 5 , 6 , 7 }, true , simulator);
break ;
case ' > ' : // Bad in(1,2), wBad > wGood
isLighter = false ;
badBall = solve2( new int [] { 1 , 2 }, false , simulator);
break ;
}
break ;
}
return badBall;
}
private int solve3( int [] balls, bool isLighter, IBall13Simulator simulator)
{
int badBall = 0 ;
switch (simulator.Test( new int [] { balls[ 0 ] }, new int [] { balls[ 1 ] }))
{
case ' = ' :
badBall = balls[ 2 ];
break ;
case ' < ' :
badBall = isLighter ? balls[ 0 ] : balls[ 1 ];
break ;
case ' > ' :
badBall = isLighter ? balls[ 1 ] : balls[ 0 ];
break ;
}
return badBall;
}
private int solve2( int [] balls, int goodBall, out bool ? isLighter, IBall13Simulator simulator)
{
int badBall = 0 ;
bool ? islighter = null ;
switch (simulator.Test( new int [] { balls[ 0 ] }, new int [] { goodBall }))
{
case ' = ' :
badBall = balls[ 1 ];
islighter = null ;
break ;
case ' < ' :
badBall = balls[ 0 ];
islighter = true ;
break ;
case ' > ' :
badBall = balls[ 0 ];
islighter = false ;
break ;
}
isLighter = islighter;
return badBall;
}
private int solve2( int [] balls, bool isLighter, IBall13Simulator simulator)
{
int badBall = 0 ;
switch (simulator.Test( new int [] { balls[ 0 ] }, new int [] { balls[ 1 ] }))
{
case ' = ' :
badBall = balls[ 2 ];
break ;
case ' < ' :
badBall = isLighter ? balls[ 0 ] : balls[ 1 ];
break ;
case ' > ' :
badBall = isLighter ? balls[ 1 ] : balls[ 0 ];
break ;
}
return badBall;
}
}
{
public int Resolve(IBall13Simulator simulator, out bool ? isLighter)
{
#region Draft
/*
1,2,3,4 v 5,6,7,8
=
1,2,3 v 9,10,11
= # Bad in(12,13)
1 v 12
= @ 13 Bad
< @ 12 Bad #wBad > wGood
> @ 12 Bad #wBad < wGood
> #Bad in(9, 10, 11), wBad < wGood
9 v 10
= @ 11 Bad
< @ 9 Bad
> @ 10 Bad
< #Bad in(9, 10, 11), wBad > wGood
9 v 10
= @ 11 Bad
< @ 10 Bad
> @ 9 Bad
< # Bad in (1-8); (9 - 13) Good
1,2,3,5,6 v 9,10,11,12,13
= #Bad in(4,7,8), (Bad=4 wB<wG || Bad in (7,8) wB>wG)
7 v 8
= @ Bad = 4 #wB < wG
< @ Bad = 8
> @ Bad = 7
< #Bad in(1,2,3), wBad < wGood
$((1,2,3),<)
> #Bad in(5,6), wBad > wGood
$((5,6),>)
> #The opposite to '<'
*/
#endregion
int badBall = 0 ;
isLighter = null ;
switch (simulator.Test( new int [] { 1 , 2 , 3 , 4 }, new int [] { 5 , 6 , 7 , 8 }))
{
case ' = ' : // Bad in 9 - 13
switch (simulator.Test( new int [] { 1 , 2 , 3 }, new int [] { 9 , 10 , 11 }))
{
case ' = ' : // Bad in 12,13
badBall = solve2( new int [] { 12 , 13 }, 1 , out isLighter, simulator);
break ;
case ' < ' : // Bad in 9,10,11, Heavier
isLighter = false ;
badBall = solve3( new int [] { 9 , 10 , 11 }, false , simulator);
break ;
case ' > ' : // Bad in 9,10,11, Lighter
isLighter = true ;
badBall = solve3( new int [] { 9 , 10 , 11 }, true , simulator);
break ;
}
break ;
case ' < ' :
switch (simulator.Test( new int [] { 1 , 2 , 3 , 5 , 6 }, new int [] { 9 , 10 , 11 , 12 , 13 }))
{
case ' = ' : // Bad in(4,7,8), (Bad=4 wB<wG || Bad in (7,8) wB>wG)
badBall = solve3( new int [] { 7 , 8 , 4 }, false , simulator);
isLighter = badBall == 4 ;
break ;
case ' < ' : // Bad in(1,2,3), wBad < wGood
isLighter = true ;
badBall = solve3( new int [] { 1 , 2 , 3 }, true , simulator);
break ;
case ' > ' : // Bad in(5,6), wBad > wGood
isLighter = false ;
badBall = solve2( new int [] { 5 , 6 }, false , simulator);
break ;
}
break ;
case ' > ' : // The opposite to '<'
switch (simulator.Test( new int [] { 5 , 6 , 7 , 1 , 2 }, new int [] { 9 , 10 , 11 , 12 , 13 }))
{
case ' = ' : // Bad in(8,3,4), (Bad=8 wB<wG || Bad in (3,4) wB>wG)
badBall = solve3( new int [] { 3 , 4 , 8 }, false , simulator);
isLighter = badBall == 8 ;
break ;
case ' < ' : // Bad in(5,6,7), wBad < wGood
isLighter = true ;
badBall = solve3( new int [] { 5 , 6 , 7 }, true , simulator);
break ;
case ' > ' : // Bad in(1,2), wBad > wGood
isLighter = false ;
badBall = solve2( new int [] { 1 , 2 }, false , simulator);
break ;
}
break ;
}
return badBall;
}
private int solve3( int [] balls, bool isLighter, IBall13Simulator simulator)
{
int badBall = 0 ;
switch (simulator.Test( new int [] { balls[ 0 ] }, new int [] { balls[ 1 ] }))
{
case ' = ' :
badBall = balls[ 2 ];
break ;
case ' < ' :
badBall = isLighter ? balls[ 0 ] : balls[ 1 ];
break ;
case ' > ' :
badBall = isLighter ? balls[ 1 ] : balls[ 0 ];
break ;
}
return badBall;
}
private int solve2( int [] balls, int goodBall, out bool ? isLighter, IBall13Simulator simulator)
{
int badBall = 0 ;
bool ? islighter = null ;
switch (simulator.Test( new int [] { balls[ 0 ] }, new int [] { goodBall }))
{
case ' = ' :
badBall = balls[ 1 ];
islighter = null ;
break ;
case ' < ' :
badBall = balls[ 0 ];
islighter = true ;
break ;
case ' > ' :
badBall = balls[ 0 ];
islighter = false ;
break ;
}
isLighter = islighter;
return badBall;
}
private int solve2( int [] balls, bool isLighter, IBall13Simulator simulator)
{
int badBall = 0 ;
switch (simulator.Test( new int [] { balls[ 0 ] }, new int [] { balls[ 1 ] }))
{
case ' = ' :
badBall = balls[ 2 ];
break ;
case ' < ' :
badBall = isLighter ? balls[ 0 ] : balls[ 1 ];
break ;
case ' > ' :
badBall = isLighter ? balls[ 1 ] : balls[ 0 ];
break ;
}
return badBall;
}
}
编译运行一下,很好玩的. 输出结果也说明了我在前一篇随笔<<谋杀脑细胞:13球称重问题及我的解法>>中的解法和结论是正确的. 希望几天后能把自动求解的程序也发上来.