Linq编程小趣味爱因斯坦谜题

简介:

最近看到一个比较老的题目,题目----在一条街上,有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,如需转载请自行联系原作者

相关文章
|
18天前
|
设计模式 算法 程序员
探索编程之美:从代码中寻找艺术
【9月更文挑战第16天】在数字的世界中,编程不仅仅是冷冰冰的逻辑与算法。它如同绘画、雕塑或音乐一样,拥有其独特的美学。本文将带你领略编程的艺术性,从简单的代码示例出发,深入探讨代码结构、设计模式以及编程思维中的美。通过这些视角,我们不仅能够提升代码的效率和可读性,还能在日常的编程实践中发现更多的乐趣和创造性。
|
24天前
|
JavaScript 前端开发 程序员
探索编程之美:从代码中寻找艺术与哲学
【8月更文挑战第42天】在数字世界的构建中,代码不仅仅是冷冰冰的指令集合。它蕴含着创造者的智慧、情感与哲理。本文将带你走进编程语言的世界,通过实际代码示例,揭示编写优雅、高效代码的内在逻辑和美学原则,同时探讨如何通过技术实现个人成长和对世界的贡献。
39 11
|
17天前
|
前端开发 算法 JavaScript
编程之美:从代码到艺术的转变
【9月更文挑战第17天】在技术的世界里,代码不仅仅是冷冰冰的指令序列,它同样可以是流动的艺术。本文将带你走进编程的内在世界,探索如何通过代码实现功能与美学的完美结合。我们将一起见证一个简单功能的实现,是如何一步步转化为令人赏心悦目的艺术作品,同时不忘提升其背后的技术深度和实用性。
|
2月前
|
算法 程序员 Python
探索编程之美:从代码到艺术的转变
在数字化时代的浪潮中,编程已经不仅仅是一种技术操作,它逐渐演变成一种艺术形式。本文将探讨编程如何从简单的代码编写转变为创造性的艺术实践,揭示编程背后的美学原则和创新思维。通过分析编程语言的设计、算法的优雅性以及编程社区的文化,我们将看到编程如何激发创造力,促进个人成长,并对社会产生深远影响。
32 2
|
2月前
|
算法 搜索推荐 程序员
从代码到宇宙:探索编程中的哲学和人生意义
【8月更文挑战第31天】在编程的世界里,我们不仅仅是在编写代码,更是在编织命运的纹理。本文通过技术感悟探讨如何将编程实践与人生的深刻哲理相结合,从而发现代码背后的更广阔天地。我们将一起走进编程语言的核心,解锁那些隐藏在算法和数据结构中的秘密,同时反思技术如何影响我们的生活和思维方式。
|
5月前
|
程序员 Python
Python编程中的陷阱与救赎
【2月更文挑战第4天】在Python编程的过程中,我们常常会遇到各种各样的错误。这些错误可能是由于语法问题、逻辑错误或者是运行时错误所导致的。本文将介绍一些常见的Python编程错误,以及如何通过调试和测试来解决这些问题。
|
存储 C++
魔幻而精妙:探秘杨辉三角的奥秘
在这篇文章中,我们将深入研究题目 杨辉三角的内涵与解决方法。杨辉三角是数学领域的一颗璀璨明珠,通过对该问题的解析,笔者将揭示它独特的规律与生成方式。
113 0
|
算法
谈一谈|编程中的数学思维
谈一谈|编程中的数学思维
136 0
|
数据可视化 Python
一个关于 += 的谜题
一个关于 += 的谜题
142 0
一个关于 += 的谜题