爱因斯坦谜题:谁养鱼(C#版)

一个偶然的机会再次接触到了爱因斯坦谜题,一时来了兴致,用C#做了一个程序,看看到底是谁养鱼(大学毕业后接触过这道题,不过很遗憾,那时的我没有成为2%的人,所以不知道是谁在养鱼)?

这道迷题出自1981年柏林的德国逻辑思考学院,据说世界上只有2%的人能出答案,就连大名鼎鼎的爱因斯坦也成为此题大伤脑。爱因斯坦谜题的中文表述是这样的:

1. 有5栋5种颜色的房子

2. 每一位房子的主人国籍都不同

3. 这五个人每人只喝一个牌子的饮料,只抽一个牌子的香烟,只养一种宠物

4. 没有人有相同的宠物,抽相同牌子的烟,喝相同牌子的饮料

已知条件:

1. 英国人住在红房子里

2. 瑞典人养了一条狗

3. 丹麦人喝?

4. 绿房子在白房子的左边

5. 绿房子主人喝咖啡

6. 抽pallmall烟的人养了一只鸟

7. 黄房子主人抽dunhill烟

8. 住在中间房子的人喝牛奶

9. 挪威人住在第一间房子

10.抽混合烟的人住在养猫人的旁边

11.养马人住在抽dunhill烟人的旁边

12.抽bluemaster烟的人喝啤酒

13.德国人抽prince烟

14.挪威人住在蓝房子旁边

15.抽混合烟的人的邻居喝矿泉水

问题:谁养鱼?

很遗憾的是,这个中文表述有问题,至少有以下几方面的歧义:

一、如何区分左右?二、已知条件中的第4条,绿房子在白房子的左边,是紧邻?还是可以分开?三、第一个房子,从什么方向开始算起,左,还是右?

如果仅把上面的第二点提到的绿房子在白房子的左边,不限于紧邻,则会出现7组符合条件的组合,3个答案:丹麦人养鱼(3组)、德国人养鱼(3组)、挪威人养鱼(1组)。

这显然不符合爱因斯坦谜题的本意,所以又查了查英文原题,结果真相大白,其严谨的表述有效的消除了以上的歧义。那最终的结果究竟又如何呢?

英文原题:

The Einstein Puzzle

 

There are 5 houses in five different colors. They are lined up in a row side by side.

In each house lives a person with a different nationality.

These 5 owners drink a certain drink, smoke a certain brand of tobacco and keep a certain pet.

No owners have the same pet, smoke the same tobacco, or drink the same drink.

As you look at the 5 houses from across the street, the green house is adjacent(woog注释:adjacent adj,毗连的,邻近的,接近的;n,近邻) to the left of the white house

The Big Question is:

Who owns the Fish?

 

CLUES:

1、The Brit lives in the red house

2、The Swede keeps dogs as pets

3、The Dane drinks tea

4、The green house is on the immediate left of the white house as you stare at the front of the 5 houses

5、The green house owner drinks coffee

6、The person who smokes Pall Mall raises birds

7、The owner of the yellow house smokes Dunhill

8、The man living in the house right in the center drinks milk

9、The Norwegian lives in the first house

10、The man who smokes Blends lives next to the one who keeps cats

11、The man who keeps horses lives next to the one who smokes Dunhill

12、The owner who smokes Bluemaster drinks juice

13、The German smokes Prince

14、The Norwegian lives next to the blue house

15、The man who smokes Blend has a neighbor who drinks water.

 

相关代码如下(考虑了两种情况,当#define FastCompute时,仅有一组答案):

 

[c-sharp]  view plain copy
  1. //[叶帆工作室] http://blog.csdn.net/yefanqiu   
  2. #define FastCompute       
  3. using System;  
  4. using System.Collections.Generic;  
  5. using System.ComponentModel;  
  6. using System.Data;  
  7. using System.Drawing;  
  8. using System.Text;  
  9. using System.Windows.Forms;  
  10. using System.Diagnostics;      
  11.   
  12. namespace Einstein  
  13. {  
  14.     public partial class frmMain : Form  
  15.     {  
  16.         public frmMain()  
  17.         {  
  18.             InitializeComponent();  
  19.         }  
  20.   
  21.         private void btnRun_Click(object sender, EventArgs e)  
  22.         {                                                    
  23.             Arithmetic arithmetic = new Arithmetic();        
  24.             DateTime dt = DateTime.Now;  
  25.             string  result = arithmetic.DoResult();  
  26.             MessageBox.Show(result + "/r/n耗时:" + (DateTime.Now - dt).TotalSeconds.ToString() + "秒");  
  27.         }             
  28.     }  
  29.   
  30.     public class Arithmetic  
  31.     {  
  32.         string[] people   = new string[] { "英国""瑞典""丹麦""挪威""德国" };  
  33.         string[] house = new string[] { "红""绿""白""黄""蓝" };  
  34.         string[] drink = new string[] { "茶""咖啡""牛奶""啤酒""水" };  
  35.         string[] smoke = new string[] { "Pall Mall""Dunhill""Blends""Blue Master""Prince" };  
  36.         string[] pet = new string[] { "狗""鸟""猫""马""鱼" };  
  37.   
  38.         List<string[]> lstCombination = new List<string[]>();   //存放全部结果(预删减后的结果)  
  39.         List<string[]> lstCombination0 = new List<string[]>();  
  40.         List<string[]> lstCombination1 = new List<string[]>();  
  41.         List<string[]> lstCombination2 = new List<string[]>();  
  42.         List<string[]> lstCombination3 = new List<string[]>();  
  43.         List<string[]> lstCombination4 = new List<string[]>();  
  44.                                 
  45.         public string DoResult()  
  46.         {  
  47.             string[,] result = new string[5, 5];  
  48.   
  49.             //生成全部的组合  
  50.             MakeCombination();  
  51.             //预剔除不符合条件的组合  
  52.             EliminateCombination();  
  53.             //获得有可能的组合0  
  54.             EliminateCombination0();  
  55.             //获得有可能的组合1  
  56.             EliminateCombination1();  
  57.             //获得有可能的组合2  
  58.             EliminateCombination2();  
  59.             //获得有可能的组合3  
  60.             EliminateCombination3();  
  61.             //获得有可能的组合4  
  62.             EliminateCombination4();  
  63.   
  64.             string strInfo = "";  
  65.             int intNum = 0;  
  66.   
  67.             for (int i = 0; i < lstCombination0.Count; i++)      
  68.             {  
  69.                 ToCombination(result, 0, lstCombination0,i);  
  70.                 for (int j =0; j < lstCombination1.Count; j++)    
  71.                 {  
  72.                     ToCombination(result, 1, lstCombination1,j);  
  73.                     for (int k = 0; k < lstCombination2.Count; k++)   
  74.                     {  
  75.                         ToCombination(result,  2,lstCombination2, k);  
  76.                         for (int l =0; l < lstCombination3.Count; l++)    
  77.                         {  
  78.                             ToCombination(result,  3,lstCombination3, l);  
  79.                             for (int m =0; m < lstCombination4.Count; m++)   
  80.                             {  
  81.                                 ToCombination(result, 4,lstCombination4, m);  
  82.   
  83.                                 bool Flag=true;  
  84.                                 for (int e = 0; e < 5; e++)  
  85.                                 {  
  86.                                     if (result[0, e] == result[1, e] || result[0, e] == result[2, e] || result[0, e] == result[3, e] || result[0, e] == result[4, e] ||  
  87.                                         result[1, e] == result[2, e] || result[1, e] == result[3, e] || result[1, e] == result[4, e] ||  
  88.                                         result[2, e] == result[3, e] || result[2, e] == result[4, e] ||  
  89.                                         result[3, e] == result[4, e])  
  90.                                     {  
  91.                                         Flag = false;  
  92.                                         break;  
  93.                                     }  
  94.                                 }  
  95.     
  96.                                 //判断组合是否成立  
  97.                                 if (Flag && Judge(result))  
  98.                                 {  
  99.                                     strInfo += "---------------- " + (++intNum).ToString()+" ----------------/r/n";  
  100.                                     for (int ii = 0; ii < 5; ii++)  
  101.                                     {  
  102.                                         for (int jj = 0; jj < 5; jj++)  
  103.                                         {  
  104.                                             strInfo += result[ii, jj] + " ";  
  105.                                         }  
  106.                                         strInfo += "/r/n";  
  107.                                     }  
  108. #if FastCompute  
  109.                                     strInfo += "------------------------------------/r/n";  
  110.                                     return strInfo;  
  111. #endif  
  112.                                 }  
  113.                             }  
  114.                         }  
  115.                     }  
  116.                 }  
  117.             }  
  118.   
  119.             strInfo += "------------------------------------/r/n";  
  120.             return strInfo;             
  121.         }  
  122.   
  123.         private void ToCombination(string[,] result,int index, List<string[]>  lst,int num)  
  124.         {  
  125.             for (int i = 0; i < 5; i++)  
  126.             {  
  127.                 result[index, i] = lst[num][i];  
  128.             }  
  129.         }  
  130.   
  131.         //生成全部的组合  
  132.         private void MakeCombination()  
  133.         {  
  134.             string[] combination = new string[5];  
  135.   
  136.             //5*5*5*5*5=3125  
  137.             for (int i = 0; i < 5; i++) //国籍  
  138.             {  
  139.                 combination[0] = people[i];  
  140.                 for (int j = 0; j < 5; j++)  //房子  
  141.                 {  
  142.                     combination[1] = house[j];  
  143.                     for (int k = 0; k < 5; k++)  //饮料  
  144.                     {  
  145.                         combination[2] = drink[k];  
  146.                         for (int l = 0; l < 5; l++)  //香烟  
  147.                         {  
  148.                             combination[3] = smoke[l];  
  149.                             for (int m = 0; m < 5; m++)  //宠物  
  150.                             {  
  151.                                 combination[4] = pet[m];  
  152.                                 lstCombination.Add((string[])combination.Clone());  
  153.                             }  
  154.                         }  
  155.                     }  
  156.                 }  
  157.             }  
  158.         }  
  159.   
  160.         //剔除组合的判断条件  
  161.         private bool JudgeCombination(string[] combination)  
  162.         {  
  163.             //1、英国住红房子  
  164.             if (combination[0] == "英国" && combination[1] != "红"return false;  
  165.             //2、瑞典养狗  
  166.             if (combination[0] == "瑞典" && combination[4] != "狗"return false;  
  167.             //3、丹麦喝茶  
  168.             if (combination[0] == "丹麦" && combination[2] != "茶"return false;  
  169.             //5、绿房子主喝咖啡  
  170.             if (combination[1] == "绿" && combination[2] != "咖啡"return false;  
  171.             //6、抽Pall Mall香烟的养鸟  
  172.             if (combination[3] == "Pall Mall" && combination[4] != "鸟"return false;  
  173.             //7、黄房子主抽Dunhill香烟  
  174.             if (combination[1] == "黄" && combination[3] != "Dunhill"return false;  
  175.             //12、抽Blue Master的喝啤酒  
  176.             if (combination[3] == "Blue Master" && combination[2] != "啤酒"return false;  
  177.             //13、德国抽Prince香烟  
  178.             if (combination[0] == "德国" && combination[3] != "Prince"return false;  
  179.             return true;  
  180.         }  
  181.   
  182.         //预剔除不符合条件的组合  
  183.         private void EliminateCombination()  
  184.         {  
  185.             string[] combination=new string[5];  
  186.             int num=lstCombination.Count;  
  187.             int index = 0;  
  188.             while ((num--)>0)  
  189.             {  
  190.                 if (!JudgeCombination(lstCombination[index]))  
  191.                 {  
  192.                     lstCombination.RemoveAt(index);  
  193.                 }  
  194.                 else  
  195.                 {  
  196.                     index++;  
  197.                 }                  
  198.             }  
  199.         }  
  200.   
  201.         //创建组合0  
  202.         private void EliminateCombination0()  
  203.         {  
  204.             lstCombination0.Clear();   
  205.             foreach (string[] combination in lstCombination)  
  206.             {  
  207.                 //combination[1] != "红" && combination[1] != "蓝" && combination[1] != "白" && combination[1] != "绿"  
  208. #if FastCompute  
  209.                 if (combination[0] == "挪威" && combination[1] == "黄" && combination[2] != "牛奶" && combination[2] != "茶" && combination[3] != "Prince" && combination[4] != "狗")  
  210. #else  
  211.                 if (combination[0] == "挪威" && combination[1] != "红" && combination[1] != "蓝" && combination[1] != "白"  && combination[2] != "牛奶" && combination[2] != "茶" && combination[3] != "Prince" && combination[4] != "狗")  
  212. #endif  
  213.                 {            
  214.                     lstCombination0.Add(combination);  
  215.                 }                                                                         
  216.             }      
  217.         }  
  218.   
  219.         //创建组合1  
  220.         private void EliminateCombination1()  
  221.         {  
  222.             lstCombination1.Clear();  
  223.             foreach (string[] combination in lstCombination)  
  224.             {  
  225.                 if (combination[0] != "挪威" &&  combination[1] == "蓝" && combination[2] != "牛奶")  
  226.                 {  
  227.                     lstCombination1.Add(combination);  
  228.                 }  
  229.             }  
  230.         }  
  231.   
  232.         //创建组合2  
  233.         private void EliminateCombination2()  
  234.         {  
  235.             lstCombination2.Clear();  
  236.             foreach (string[] combination in lstCombination)  
  237.             {  
  238. #if FastCompute  
  239.                 if (combination[0] != "挪威" && combination[0] != "丹麦" && combination[1] != "蓝" && combination[1] != "黄" && combination[1] != "白" && combination[2] == "牛奶")  
  240. #else                 
  241.                 if (combination[0] != "挪威" && combination[0] != "丹麦" && combination[1] != "蓝"  && combination[2] == "牛奶")  
  242. #endif  
  243.                 {  
  244.                     lstCombination2.Add(combination);  
  245.                 }  
  246.             }  
  247.         }  
  248.   
  249.         //创建组合3  
  250.         private void EliminateCombination3()  
  251.         {  
  252.             lstCombination3.Clear();  
  253.             foreach (string[] combination in lstCombination)  
  254.             {  
  255. #if FastCompute  
  256.                 if (combination[0] != "挪威" && combination[1] != "黄" && combination[1] != "蓝" && combination[2] != "牛奶")  
  257. #else  
  258.                 if (combination[0] != "挪威" && combination[1] != "蓝" && combination[2] != "牛奶")  
  259. #endif  
  260.                 {  
  261.                     lstCombination3.Add(combination);  
  262.                 }  
  263.             }  
  264.         }  
  265.   
  266.         //创建组合4  
  267.         private void EliminateCombination4()  
  268.         {  
  269.             lstCombination4.Clear();  
  270.             foreach (string[] combination in lstCombination)  
  271.             {  
  272. #if FastCompute  
  273.                 if (combination[0] != "挪威" && combination[1] != "黄" && combination[1] != "蓝" && combination[1] != "绿" && combination[2] != "牛奶")  
  274. #else                 
  275.                 if (combination[0] != "挪威" && combination[1] != "蓝" && combination[1] != "绿" && combination[2] != "牛奶")  
  276. #endif  
  277.                 {  
  278.                     lstCombination4.Add(combination);  
  279.                 }  
  280.             }  
  281.         }  
  282.        
  283.         //判断  
  284.         private static bool Judge(string[,] combination)  
  285.         {             
  286.             for (int index = 0;index < 5; index++)  
  287.             {  
  288.                 //4、绿房子在白房子左面  
  289. #if FastCompute  
  290.                 if (index > 0 && combination[index, 1] == "白" && combination[index - 1, 1] != "绿"return false;  
  291. #else  
  292.                 if (combination[index, 1] == "白")  
  293.                 {  
  294.                     for (int i = index + 1; i < 5; i++)  
  295.                     {  
  296.                         if (combination[i, 1] == "绿")  //绿房子不可能出现在白房子的右边  
  297.                             return false;  
  298.                     }   
  299.                 }  
  300. #endif          
  301.                 //8、住在中间的喝牛奶  
  302.                 if (combination[2, 2] != "牛奶"return false;  
  303.                 //9、挪威住第一间房  
  304.                 if (combination[0, 0] != "挪威"return false;  
  305.                 //10、抽Blends香烟的住在养猫的隔壁  
  306.                 if (combination[index, 3] == "Blends")  
  307.                 {  
  308.                     if(!((index>0 && combination[index-1,4]=="猫") || (index<4 && combination[index+1,4]=="猫")))  
  309.                     {  
  310.                          return false;  
  311.                     }  
  312.                 }  
  313.                 //11、养马住在抽Dunhill香烟的隔壁  
  314.                 if (combination[index, 4] == "马")  
  315.                 {  
  316.                     if (!((index > 0 && combination[index - 1, 3] == "Dunhill") || (index < 4 && combination[index + 1, 3] == "Dunhill")))  
  317.                     {  
  318.                         return false;  
  319.                     }  
  320.                 }  
  321.                 //14、挪威住蓝房子隔壁  
  322.                 if (combination[index, 0] == "挪威")  
  323.                 {  
  324.                     if (!((index > 0 && combination[index - 1, 1] == "蓝") || (index < 4 && combination[index + 1, 1] == "蓝")))  
  325.                     {  
  326.                         return false;  
  327.                     }  
  328.                 }  
  329.                 //15、抽Blends香烟的人有一个喝水的邻居  
  330.                 if (combination[index, 3] == "Blends")  
  331.                 {  
  332.                     if (!((index > 0 && combination[index - 1, 2] == "水") || (index < 4 && combination[index + 1, 2] == "水")))  
  333.                     {  
  334.                         return false;  
  335.                     }  
  336.                 }  
  337.             }           
  338.   
  339.             return true;  
  340.         }  
  341.   
  342.     }  
  343. }  

 

最终的计算结果如下(7组结果由于不合理,故省略,有兴趣的朋友可以自己把上面的代码运行一下):

-----------------------------------

挪威 黄 水 Dunhill 猫  

丹麦 蓝 茶 Blends 马      

英国 红 牛奶 Pall Mall 鸟

德国 绿 咖啡 Prince 鱼    

瑞典 白 啤酒 Blue Master 狗  

-----------------------------------

耗时:115.15625秒

【6层】一字型框架办公楼(含建筑结构图、计算书) 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值