LINQ解 爱因斯坦迷题

时间:2021-09-13 11:10:43

据说是爱因斯坦迷题,不知是真是假,不过这道集合运算的题还是挺有意思的,比一般的[谁是凶手]的题多了集合项之间的关系
用linq的集合运算符,不用if、for等控制流语句解一下这道题.

本题的解题方式用的是工作流处理问题的方式
将事项分为阶段(也叫状态),每个阶段按一定顺连接,每个阶段内由处理该阶段问题的一组业务结点组成,业务结点的添加或移除不影响处理问题的架构
还有,业务结点最好是真正真实业务的映射,最好不要出现
 [ 8、挪威人住第一间房 ]+   [14、挪威人住蓝色房子隔壁],推出[第2间房子是蓝色]的业务结点,要推也得由系统推(这叫反映链),而不能由开发人员推,这样就可以在架构完成后随意修改业务结点,本例用的就是这种方式,由于没有人工推理加入,执行效率有些低,
在Core2 Duo CPU 7300上,用 System.Diagnostics.Stopwatch
Debug   模式下用时:06.5122712
Release 模式下用时:05.2872722

问题:
在一条街上,有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香烟的人有一个喝水的邻居


代码

LINQ解 爱因斯坦迷题using  System;
LINQ解 爱因斯坦迷题
using  System.Collections.Generic;
LINQ解 爱因斯坦迷题
using  System.Linq;
LINQ解 爱因斯坦迷题
using  System.Text;
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题
namespace  ConsoleApplication2
LINQ解 爱因斯坦迷题LINQ解 爱因斯坦迷题
{
LINQ解 爱因斯坦迷题    
class Program
LINQ解 爱因斯坦迷题LINQ解 爱因斯坦迷题    
{
LINQ解 爱因斯坦迷题        
static void Main(string[] args)
LINQ解 爱因斯坦迷题LINQ解 爱因斯坦迷题        
{
LINQ解 爱因斯坦迷题            
//--------------------------1阶段----------------------------------------------
LINQ解 爱因斯坦迷题LINQ解 爱因斯坦迷题
            int[] 房子位置 = new int[] 12345 };
LINQ解 爱因斯坦迷题LINQ解 爱因斯坦迷题            
string[] 房子颜色 = new string[] """""""绿""" };
LINQ解 爱因斯坦迷题LINQ解 爱因斯坦迷题            
string[] 国籍 = new string[] "挪威""丹麦""英国""德国""瑞典" };
LINQ解 爱因斯坦迷题LINQ解 爱因斯坦迷题            
string[] 宠物 = new string[] """""""""" };
LINQ解 爱因斯坦迷题LINQ解 爱因斯坦迷题            
string[] 饮品 = new string[] """""牛奶""咖啡""啤酒" };
LINQ解 爱因斯坦迷题LINQ解 爱因斯坦迷题            
string[] 香烟 = new string[] "Dunhill""Blends""Pall Mall""Prince""Blue Master" };
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            var v 
= (from t1 in 房子位置
LINQ解 爱因斯坦迷题                     from t2 
in 房子颜色
LINQ解 爱因斯坦迷题                     from t3 
in 国籍
LINQ解 爱因斯坦迷题                     from t4 
in 宠物
LINQ解 爱因斯坦迷题                     from t5 
in 饮品
LINQ解 爱因斯坦迷题                     from t6 
in 香烟
LINQ解 爱因斯坦迷题LINQ解 爱因斯坦迷题                     select 
new a { 房子位置 = t1, 房子颜色 = t2, 国籍 = t3, 宠物 = t4, 饮品 = t5, 香烟 = t6 }).ToList();
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            
//------------------------2阶段-------------------------------------------------
LINQ解 爱因斯坦迷题            
//1、英国人住红色房子
LINQ解 爱因斯坦迷题
            v.RemoveAll(p => p.国籍 == "英国" && p.房子颜色 != "");
LINQ解 爱因斯坦迷题            v.RemoveAll(p 
=> p.国籍 != "英国" && p.房子颜色 == "");
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            
//2、瑞典人养狗
LINQ解 爱因斯坦迷题
            v.RemoveAll(p => p.国籍 == "瑞典" && p.宠物 != "");
LINQ解 爱因斯坦迷题            v.RemoveAll(p 
=> p.国籍 != "瑞典" && p.宠物 == "");
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            
//3、丹麦人喝茶
LINQ解 爱因斯坦迷题
            v.RemoveAll(p => p.国籍 == "丹麦" && p.饮品 != "");
LINQ解 爱因斯坦迷题            v.RemoveAll(p 
=> p.国籍 != "丹麦" && p.饮品 == "");
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            
//5、绿色房子主人喝咖啡
LINQ解 爱因斯坦迷题
            v.RemoveAll(p => p.房子颜色 == "绿" && p.饮品 != "咖啡");
LINQ解 爱因斯坦迷题            v.RemoveAll(p 
=> p.房子颜色 != "绿" && p.饮品 == "咖啡");
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            
//6、抽Pall Mall 香烟的人养鸟
LINQ解 爱因斯坦迷题
            v.RemoveAll(p => p.香烟 == "Pall Mall" && p.宠物 != "");
LINQ解 爱因斯坦迷题            v.RemoveAll(p 
=> p.香烟 != "Pall Mall" && p.宠物 == "");
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            
//7、黄色房子主人抽Dunhill 香烟
LINQ解 爱因斯坦迷题
            v.RemoveAll(p => p.房子颜色 == "" && p.香烟 != "Dunhill");
LINQ解 爱因斯坦迷题            v.RemoveAll(p 
=> p.房子颜色 != "" && p.香烟 == "Dunhill");
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            
//8、挪威人住第一间房
LINQ解 爱因斯坦迷题
            v.RemoveAll(p => p.国籍 == "挪威" && p.房子位置 != 1);
LINQ解 爱因斯坦迷题            v.RemoveAll(p 
=> p.国籍 != "挪威" && p.房子位置 == 1);
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            
//9、住在中间房子的人喝牛奶 
LINQ解 爱因斯坦迷题
            v.RemoveAll(p => p.房子位置 == 3 && p.饮品 != "牛奶");
LINQ解 爱因斯坦迷题            v.RemoveAll(p 
=> p.房子位置 != 3 && p.饮品 == "牛奶");
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            
//12、抽Blue Master的人喝啤酒
LINQ解 爱因斯坦迷题
            v.RemoveAll(p => p.香烟 == "Blue Master" && p.饮品 != "啤酒");
LINQ解 爱因斯坦迷题            v.RemoveAll(p 
=> p.香烟 != "Blue Master" && p.饮品 == "啤酒");
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            
//13、德国人抽Prince香烟
LINQ解 爱因斯坦迷题
            v.RemoveAll(p => p.国籍 == "德国" && p.香烟 != "Prince");
LINQ解 爱因斯坦迷题            v.RemoveAll(p 
=> p.国籍 != "德国" && p.香烟 == "Prince");
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            
//-------------------------3阶段------------------------------------------------
LINQ解 爱因斯坦迷题            
//喷不同颜色,住不同国籍的人,喝不同的饮料,抽不同品牌的香烟,养不同的宠物
LINQ解 爱因斯坦迷题
            var vv = (from g1 in v.Where(p => p.房子位置 == 1)
LINQ解 爱因斯坦迷题                     from g2 
in v.Where(p => p.房子位置 == 2)
LINQ解 爱因斯坦迷题                     from g3 
in v.Where(p => p.房子位置 == 3)
LINQ解 爱因斯坦迷题                     from g4 
in v.Where(p => p.房子位置 == 4)
LINQ解 爱因斯坦迷题                     from g5 
in v.Where(p => p.房子位置 == 5)
LINQ解 爱因斯坦迷题                     
where g1.饮品 != g2.饮品 && g1.饮品 != g3.饮品 && g1.饮品 != g4.饮品 && g1.饮品 != g5.饮品 &&
LINQ解 爱因斯坦迷题                            g2.饮品 
!= g3.饮品 && g2.饮品 != g4.饮品 && g2.饮品 != g5.饮品 &&
LINQ解 爱因斯坦迷题                            g3.饮品 
!= g4.饮品 && g3.饮品 != g5.饮品 &&
LINQ解 爱因斯坦迷题                            g4.饮品 
!= g5.饮品 &&
LINQ解 爱因斯坦迷题                            g1.宠物 
!= g2.宠物 && g1.宠物 != g3.宠物 && g1.宠物 != g4.宠物 && g1.宠物 != g5.宠物 &&
LINQ解 爱因斯坦迷题                            g2.宠物 
!= g3.宠物 && g2.宠物 != g4.宠物 && g2.宠物 != g5.宠物 &&
LINQ解 爱因斯坦迷题                            g3.宠物 
!= g4.宠物 && g3.宠物 != g5.宠物 &&
LINQ解 爱因斯坦迷题                            g4.宠物 
!= g5.宠物 &&
LINQ解 爱因斯坦迷题                            g1.国籍 
!= g2.国籍 && g1.国籍 != g3.国籍 && g1.国籍 != g4.国籍 && g1.国籍 != g5.国籍 &&
LINQ解 爱因斯坦迷题                            g2.国籍 
!= g3.国籍 && g2.国籍 != g4.国籍 && g2.国籍 != g5.国籍 &&
LINQ解 爱因斯坦迷题                            g3.国籍 
!= g4.国籍 && g3.国籍 != g5.国籍 &&
LINQ解 爱因斯坦迷题                            g4.国籍 
!= g5.国籍 &&
LINQ解 爱因斯坦迷题                            g1.香烟 
!= g2.香烟 && g1.香烟 != g3.香烟 && g1.香烟 != g4.香烟 && g1.香烟 != g5.香烟 &&
LINQ解 爱因斯坦迷题                            g2.香烟 
!= g3.香烟 && g2.香烟 != g4.香烟 && g2.香烟 != g5.香烟 &&
LINQ解 爱因斯坦迷题                            g3.香烟 
!= g4.香烟 && g3.香烟 != g5.香烟 &&
LINQ解 爱因斯坦迷题                            g4.香烟 
!= g5.香烟 &&
LINQ解 爱因斯坦迷题                            g1.房子颜色 
!= g2.房子颜色 && g1.房子颜色 != g3.房子颜色 && g1.房子颜色 != g4.房子颜色 && g1.房子颜色 != g5.房子颜色 &&
LINQ解 爱因斯坦迷题                            g2.房子颜色 
!= g3.房子颜色 && g2.房子颜色 != g4.房子颜色 && g2.房子颜色 != g5.房子颜色 &&
LINQ解 爱因斯坦迷题                            g3.房子颜色 
!= g4.房子颜色 && g3.房子颜色 != g5.房子颜色 &&
LINQ解 爱因斯坦迷题                            g4.房子颜色 
!= g5.房子颜色 &&
LINQ解 爱因斯坦迷题                            g1.房子位置 
!= g2.房子位置 && g1.房子位置 != g3.房子位置 && g1.房子位置 != g4.房子位置 && g1.房子位置 != g5.房子位置 &&
LINQ解 爱因斯坦迷题                            g2.房子位置 
!= g3.房子位置 && g2.房子位置 != g4.房子位置 && g2.房子位置 != g5.房子位置 &&
LINQ解 爱因斯坦迷题                            g3.房子位置 
!= g4.房子位置 && g3.房子位置 != g5.房子位置 &&
LINQ解 爱因斯坦迷题                            g4.房子位置 
!= g5.房子位置
LINQ解 爱因斯坦迷题LINQ解 爱因斯坦迷题                      select 
new List<a> { g1, g2, g3, g4, g5 }).ToList();
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            
//------------------------4阶段-------------------------------------------------
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            
// 4、绿色房子在白色房子左面
LINQ解 爱因斯坦迷题            
//(绿房子.房子位置房子 - 白.房子位置) == -1 表示左面
LINQ解 爱因斯坦迷题
            vv.RemoveAll(pp => -1 != pp.Single(p => p.房子颜色 == "绿").房子位置 - pp.Single(p => p.房子颜色 == "").房子位置);
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            
//10、抽Blends香烟的人住在养猫的人隔壁
LINQ解 爱因斯坦迷题            
// Abc(Blends香烟的人.房子位置 - 养猫.房子位置) == 1 表示是隔壁
LINQ解 爱因斯坦迷题
            vv.RemoveAll(pp => 1 != System.Math.Abs(pp.Single(p => p.宠物 == "").房子位置 - pp.Single(p => p.香烟 == "Blends").房子位置));
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题          
//11、养马的人住抽Dunhill 香烟的人隔壁
LINQ解 爱因斯坦迷题
            vv.RemoveAll(pp => 1 != System.Math.Abs(pp.Single(p => p.宠物 == "").房子位置 - pp.Single(p => p.香烟 == "Dunhill").房子位置));
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            
//14、挪威人住蓝色房子隔壁
LINQ解 爱因斯坦迷题
            vv.RemoveAll(pp => 1 != System.Math.Abs(pp.Single(p => p.国籍 == "挪威").房子位置 - pp.Single(p => p.房子颜色 == "").房子位置));
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            
//15、抽Blends香烟的人有一个喝水的邻居
LINQ解 爱因斯坦迷题
            vv.RemoveAll(pp => 1 != System.Math.Abs(pp.Single(p => p.香烟 == "Blends").房子位置 - pp.Single(p => p.饮品 == "").房子位置));
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            
//--------------------------5阶段-----------------------------------------------
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            
//问题是:谁养鱼?
LINQ解 爱因斯坦迷题
            var who= vv.Select(pp => pp.Single(p => p.宠物 == ""));
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            who.ToList().ForEach(p 
=> System.Console.WriteLine("养鱼:{0}",p));
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            System.Console.WriteLine(
"结构:");
LINQ解 爱因斯坦迷题          
LINQ解 爱因斯坦迷题            vv.ForEach(p
=>p.ForEach(pp=>System.Console.WriteLine(pp)));
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            
//------------------------------------------------------------------------
LINQ解 爱因斯坦迷题
            System.Console.Read();
LINQ解 爱因斯坦迷题        }

LINQ解 爱因斯坦迷题    }

LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题    
class a
LINQ解 爱因斯坦迷题LINQ解 爱因斯坦迷题    
{
LINQ解 爱因斯坦迷题        
public int 房子位置;
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题        
public string 房子颜色;
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题        
public string 国籍;
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题        
public string 宠物;
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题        
public string 饮品;
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题        
public string 香烟;
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题        
public override string ToString()
LINQ解 爱因斯坦迷题LINQ解 爱因斯坦迷题        
{
LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题            
return string.Format("{0},{1},{2},{3},{4},{5}", 房子位置, 房子颜色, 国籍, 宠物, 饮品, 香烟);
LINQ解 爱因斯坦迷题        }

LINQ解 爱因斯坦迷题
LINQ解 爱因斯坦迷题    }

LINQ解 爱因斯坦迷题}

LINQ解 爱因斯坦迷题

结果
LINQ解 爱因斯坦迷题