博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linq编程小趣味爱因斯坦谜题
阅读量:6786 次
发布时间:2019-06-26

本文共 7477 字,大约阅读时间需要 24 分钟。

最近看到一个比较老的题目,题目----在一条街上,有5座房子,喷了5种颜色,每个房里住着不同国籍的人,每个人喝不同的饮料,抽不同品牌的香烟,养不同的宠物,问题---谁养鱼?

以前没事还做过这个题,现在写个代码实现一下,还是感觉还是挺有意思的,先来看下推导条件吧:

    1.英国人住红色房子 

    2.瑞典人养狗 
    3.丹麦人喝茶 
    4.绿色房子在白色房子左面 
    5.绿色房子主人喝咖啡 
    6.抽Pall Mall 香烟的人养鸟 
    7.黄色房子主人抽Dunhill 香烟 
    8.住在中间房子的人喝牛奶 
    9. 挪威人住第一间房 
    10.抽Blends香烟的人住在养猫的人隔壁 
    11.养马的人住抽Dunhill 香烟的人隔壁 
    12.抽Blue Master的人喝啤酒 
    13.德国人抽Prince香烟 
    14.挪威人住蓝色房子隔壁 
    15.抽Blends香烟的人有一个喝水的邻居

人工推导

自己开始做的时候在本子上推导的,就是画画改改,本来想拍图片的,这样就不用费劲了,鉴于本人字体需要提高,还是重新弄了几张图上来,简单说下推导过程:

1选择确定条件和不确定条件:

不确定条件: 4.绿色房子在白色房子左面 ;  8.住在中间房子的人喝牛奶 ; 9. 挪威人住第一间房;  10.抽Blends香烟的人住在养猫的人隔壁;11.养马的人住抽Dunhill 香烟的人隔壁 ;   14.挪威人住蓝色房子隔壁 ;15.抽Blends香烟的人有一个喝水的邻居

(特别说明:条件9和14算是确定条件,一号房是挪威人住,二号房是蓝色,不用画图,也不用推导,直接可以得出的结论,放在不确定里面是因为不好在确定条件里面展示)

2.条件推导

推导的步骤  8,9,14(二号房是蓝色)→4,5(四号房是绿色,五号房是白色)→1,7(一号房是黄色,三号房是红色)→11(二号房养马),最后推导出的结果图如下:

 

3.这个时候剩下的条件:2,3,6,10,12,13,15,自己推导的时候在这里困扰了一下,像填字游戏一样,条件怎么弄进去感觉都是对的,观察了最后剩下的三种饮料:啤酒, 茶,水,而且给出的条件比较多,3,12,15,条件3丹麦人喝茶,适用范围是二号房和五号房,假设丹麦人是五号房(走不通),丹麦人是二号房,接下来的事情就比较容易推导.(3,12,10,15,13,2,6==本人按照这个顺序推导的)

 

程序推导   

1.根据题目,创建一个包含房号,国家,颜色,饮料,宠物,香烟的Person类:

2.去除所有的确定选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
int
[] indexArr = 
new 
int
[] { 1, 2, 3, 4, 5 };
         
string
[] countryArr = 
new 
string
[] { 
"瑞典"
"德国"
"英国"
"丹麦"
"挪威" 
};
         
string
[] colorArr = 
new 
string
[] { 
"黄色"
"蓝色"
"红色"
"绿色"
"白色" 
};
         
string
[] drinkArr = 
new 
string
[] { 
"水"
"茶"
"牛奶"
"咖啡"
"啤酒" 
};
         
string
[] cigareteeArr = 
new 
string
[] { 
"Pall Mall"
"Dunhill"
"Blends"
"Blue Master"
"Prince" 
};
         
string
[] animalArr = 
new 
string
[] { 
"猫"
"马"
"鸟"
"鱼"
"狗" 
};
         
Stopwatch stopWatch = 
new 
Stopwatch();
         
stopWatch.Start();
         
var 
allData = (
from 
index 
in 
indexArr
                        
from 
country 
in 
countryArr
                        
from 
color 
in 
colorArr
                        
from 
drink 
in 
drinkArr
                        
from 
cigaretee 
in 
cigareteeArr
                        
from 
animal 
in 
animalArr
                        
select 
new 
Person { Position = index, Country = country, Color = color, Drink = drink, Cigarette = cigaretee, Animal = animal }).ToList();
         
//1.英国人住红色房子
         
allData.RemoveAll(p => p.Country == 
"英国" 
&& p.Color != 
"红色"
);
         
allData.RemoveAll(p => p.Country != 
"英国" 
&& p.Color == 
"红色"
);
 
         
// 2.瑞典人养狗
         
allData.RemoveAll(p => p.Country == 
"瑞典" 
&& p.Animal != 
"狗"
);
         
allData.RemoveAll(p => p.Country != 
"瑞典" 
&& p.Animal == 
"狗"
);
 
         
// 3.丹麦人喝茶
         
allData.RemoveAll(p => p.Country == 
"丹麦" 
&& p.Drink != 
"茶"
);
         
allData.RemoveAll(p => p.Country != 
"丹麦" 
&& p.Drink == 
"茶"
);
 
         
// 5.绿色房子主人喝咖啡
         
allData.RemoveAll(p => p.Color == 
"绿色" 
&& p.Drink != 
"咖啡"
);
         
allData.RemoveAll(p => p.Color != 
"绿色" 
&& p.Drink == 
"咖啡"
);
 
         
// 6.抽Pall Mall 香烟的人养鸟
         
allData.RemoveAll(p => p.Cigarette == 
"Pall Mall" 
&& p.Animal != 
"鸟"
);
         
allData.RemoveAll(p => p.Cigarette != 
"Pall Mall" 
&& p.Animal == 
"鸟"
);
 
         
//7.黄色房子主人抽Dunhill 香烟
         
allData.RemoveAll(p => p.Color == 
"黄色" 
&& p.Cigarette != 
"Dunhill"
);
         
allData.RemoveAll(p => p.Color != 
"黄色" 
&& p.Cigarette == 
"Dunhill"
);
 
         
//8.挪威人住第一间房
         
allData.RemoveAll(p => p.Country == 
"挪威" 
&& p.Position != 1);
         
allData.RemoveAll(p => p.Country != 
"挪威" 
&& p.Position == 1);
 
         
//9.挪威人住第一间房
         
allData.RemoveAll(p => p.Drink == 
"牛奶" 
&& p.Position != 3);
         
allData.RemoveAll(p => p.Drink != 
"牛奶" 
&& p.Position == 3);
 
         
//12.抽Blue Master的人喝啤酒
         
allData.RemoveAll(p => p.Drink == 
"啤酒" 
&& p.Cigarette != 
"Blue Master"
);
         
allData.RemoveAll(p => p.Drink != 
"啤酒" 
&& p.Cigarette == 
"Blue Master"
);
         
//13.德国人抽Prince香烟
         
allData.RemoveAll(p => p.Country == 
"德国" 
&& p.Cigarette != 
"Prince"
);
         
allData.RemoveAll(p => p.Country != 
"德国" 
&& p.Cigarette == 
"Prince"
);
 
         
// 14.挪威人住蓝色房子隔壁(蓝色房子是二号房)
         
allData.RemoveAll(p => p.Color == 
"蓝色" 
&& p.Position != 2);
         
allData.RemoveAll(p => p.Color != 
"蓝色" 
&& p.Position == 2);

 3.穷举取出所有的可能的结果集(一组对象,不是一个对象)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var 
result = (
from 
r1 
in 
allData.Where(item => item.Position == 1)
              
from 
r2 
in 
allData.Where(item => item.Position == 2)
              
from 
r3 
in 
allData.Where(item => item.Position == 3)
              
from 
r4 
in 
allData.Where(item => item.Position == 4)
              
from 
r5 
in 
allData.Where(item => item.Position == 5)
              
where 
r1.Country != r2.Country && r1.Country != r3.Country && r1.Country != r4.Country && r1.Country != r5.Country &&
                    
r2.Country != r3.Country && r2.Country != r4.Country && r2.Country != r5.Country &&
                    
r3.Country != r4.Country && r3.Country != r5.Country &&
                    
r4.Country != r5.Country &&
                    
r1.Color != r2.Color && r1.Color != r3.Color && r1.Color != r4.Color && r1.Color != r5.Color &&
                    
r2.Color != r3.Color && r2.Color != r4.Color && r2.Color != r5.Color &&
                    
r3.Color != r4.Color && r3.Color != r5.Color &&
                    
r4.Color != r5.Color &&
                    
r1.Drink != r2.Drink && r1.Drink != r3.Drink && r1.Drink != r4.Drink && r1.Drink != r5.Drink &&
                    
r2.Drink != r3.Drink && r2.Drink != r4.Drink && r2.Drink != r5.Drink &&
                    
r3.Drink != r4.Drink && r3.Drink != r5.Drink &&
                    
r4.Drink != r5.Drink &&
                    
r1.Cigarette != r2.Cigarette && r1.Cigarette != r3.Cigarette && r1.Cigarette != r4.Cigarette && r1.Cigarette != r5.Cigarette &&
                    
r2.Cigarette != r3.Cigarette && r2.Cigarette != r4.Cigarette && r2.Cigarette != r5.Cigarette &&
                    
r3.Cigarette != r4.Cigarette && r3.Cigarette != r5.Cigarette &&
                    
r4.Cigarette != r5.Cigarette &&
                    
r1.Animal != r2.Animal && r1.Animal != r3.Animal && r1.Animal != r4.Animal && r1.Animal != r5.Animal &&
                    
r2.Animal != r3.Animal && r2.Animal != r4.Animal && r2.Animal != r5.Animal &&
                    
r3.Animal != r4.Animal && r3.Animal != r5.Animal &&
                    
r4.Animal != r5.Animal
              
select 
new 
List<Person> { r1, r2, r3, r4, r5 }).ToList();

4.按照剩余的条件进行删除并输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// 4.绿色房子在白色房子左面
//白色房子的房号比绿色的大1
result.RemoveAll(item => 1 != item.Single(m => m.Color == 
"白色"
).Position - item.Single(m => m.Color == 
"绿色"
).Position);
 
 
// 10.抽Blends香烟的人住在养猫的人隔壁
result.RemoveAll(item => 1 != Math.Abs(item.Single(m => m.Cigarette == 
"Blends"
).Position - item.Single(m => m.Animal == 
"猫"
).Position));
//  11.养马的人住抽Dunhill 香烟的人隔壁
result.RemoveAll(item => 1 != Math.Abs(item.Single(m => m.Animal == 
"马"
).Position - item.Single(m => m.Cigarette == 
"Dunhill"
).Position));
//14.挪威人住蓝色房子隔壁(蓝色房子是二号房)
//result.RemoveAll(item => 1 != Math.Abs(item.Single(m => m.Country == "挪威").Position - item.Single(m => m.Color == "蓝色").Position));
//15.抽Blends香烟的人有一个喝水的邻居
result.RemoveAll(item => 1 != Math.Abs(item.Single(m => m.Cigarette == 
"Blends"
).Position - item.Single(m => m.Drink == 
"水"
).Position));
 
var 
person = result.Select(item => item.Single(m => m.Animal == 
"鱼"
)).First();
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
string 
elapsedTime = String.Format(
"{0:00}:{1:00}:{2:00}.{3:00}"
,
    
ts.Hours, ts.Minutes, ts.Seconds,
    
ts.Milliseconds / 10);
Console.WriteLine(
"{0},时间:{1}"
, person.Country, elapsedTime.ToString());
Console.WriteLine(
"编号\0\0国家\0\0颜色\0\0饮料\0\0宠物\0\0香烟"
);
foreach 
(
var 
item 
in 
result)
{
    
foreach 
(Person data 
in 
item)
    
{
        
if 
(data.Position == 1 || data.Position == 2)
        
{
            
Console.WriteLine(
"\0{0}\0\0\0\0{1}\0\0{2}\0\0{3}\0\0\0\0{4}\0\0\0{5}"
, data.Position, data.Country, data.Color, data.Drink, data.Animal, data.Cigarette);
        
}
        
else
        
{
            
Console.WriteLine(
"\0{0}\0\0\0\0{1}\0\0{2}\0\0{3}\0\0{4}\0\0\0{5}"
, data.Position, data.Country, data.Color, data.Drink, data.Animal, data.Cigarette);
        
}
    
}
}
Console.Read();

  

小结

两种推导的方式思维其实还蛮不一样的,相对来说人工的需要自己的去按照自己经验,知识,去做出一些判断,在一些难点有自己的一套解决思路,比如说条件3丹麦人喝茶在自己推导的时候是一个难点,而在写程序的时候直接删除这种可能即可,写程序的时候我们需要先穷举出所有可能,就是很长的where语句那块,这一阶段弄明白了,应该都很明了。属于自己无意中看到的一个题目,属于编程的小乐趣吧,也可以算是Linq入门的一个小Demo吧~

本文转自Fly_Elephant博客园博客,原文链接:http://www.cnblogs.com/xiaofeixiang/p/3962452.html,如需转载请自行联系原作者

你可能感兴趣的文章
数据可视化:柱状图、雷达图等六种基本图表的特点和适用场合
查看>>
选择器 :gt(index)
查看>>
notes on python
查看>>
kafa
查看>>
资源 | Feature Tools:可自动构造机器学习特征的Python库
查看>>
linux Shell 中常用的条件判断
查看>>
angular 动态设置blob链接给 ng-href时遇到unsafe 解决方案
查看>>
Java与Highcharts实例(四) - Hello Highcharts (后台Java传递数
查看>>
连接数据库的操作 总结
查看>>
Android 小米手机开发APP图标更换后还显示原来的图标
查看>>
在代码中修改Shape的solid属性的color值
查看>>
MySQL字符集问题
查看>>
Java多线程总结
查看>>
iPad Mini外屏碎了 换屏幕教程
查看>>
LinkedBlockingQueue操作,线程安全问题,ConcurrentModificationException 异常分析与解决方案...
查看>>
redis3.2新功能--GEO地理位置命令介绍与实战开发
查看>>
java 通过ssh 执行命令
查看>>
算法导论——基数排序(基于计数排序)
查看>>
19.TCP的交互数据流
查看>>
字符串匹配的Boyer-Moore算法
查看>>