“谁养鱼”的穷举解法。

 
此题源于1981年柏林的德国逻辑思考学院,要求30分钟内完成,98%的测验者无法解题。
前提:
有五间房屋排成一列;所有房屋的外表颜色都不一样;所有的屋主来自不同的国家;所有的屋主都养不同的宠物;喝不同的饮料;抽不同的香烟。
提示:
英国人住在红色房屋里;
瑞典人养了一只狗;
丹麦人喝茶
绿色的房子在白色的房子的左边;
绿色房屋的屋主喝咖啡;
抽Pall Mall香烟的屋主养鸟;
黄色屋主抽Dunhill;
位于最中间的屋主喝牛奶;
挪威人住在第一间房屋里;
Blend的人住在养猫人家的隔壁;
养马的屋主在抽Dunhill的人家的隔壁。
抽Blue Master的屋主喝啤酒;
德国人抽Prince
挪威人住在蓝色房子隔壁;
只喝开水的人家住在抽Blend的隔壁。
问:谁养鱼?
class  Program
    
{
        
/// <summary>
        
/// The solution will be used to setup a two-array.
        
/// --------------------------------------------------------
        
/// +++         Room1  Room2   Room3   Room4   Room5   +++
        
/// +++ Color                                          +++
        
/// +++ Controy                                        +++                                     
        
/// +++ Pet                                            +++
        
/// +++ Beverage                                       +++
        
/// +++ Cigarette                                      +++
        
/// --------------------------------------------------------
        
/// 
        
/// Information:
        
/// 1.  英国人住在红色房屋里 
        
/// 2.  瑞典人养了一只狗 
        
/// 3.  丹麦人喝茶 
        
/// 4.  绿色的房子在白色的房子的左边 
        
/// 5.  绿色房屋的屋主喝咖啡 
        
/// 6.  抽Pall Mall香烟的屋主养鸟 
        
/// 7.  黄色屋主抽Dunhill 
        
/// 8.  位于最中间的屋主喝牛奶 
        
/// 9.  挪威人住在第一间房屋里 
        
/// 10. 抽Blend的人住在养猫人家的隔壁 
        
/// 11. 养马的屋主在抽Dunhill的人家的隔壁 
        
/// 12. 抽Blue Master的屋主喝啤酒 
        
/// 13. 德国人抽Prince 
        
/// 14. 挪威人住在蓝色房子隔壁 
        
/// 15. 只喝开水的人家住在抽Blend的隔壁 
        
/// 
        
/// </summary>
        
/// <param name="args"></param>

        static void Main(string[] args)
        
{
            
//这一步构造问题
            Question q = new Question();

            
//本步打印结果呀
            q.CalcResult();

            Console.WriteLine(
"finished");

            Console.ReadLine();
        }


        
private static string ConvertIntString(int v)
        
{
            
return v.ToString();
        }


    }


    
public   class  ArrayGroupState < T >
    
{
        
private List<int[]> _cache = null;
        
private static Dictionary<int, List<int[]>> _cachecache = new Dictionary<int, List<int[]>>();
        
private int _currentState = 0;

        
public int[] State
        
{
            
get return _cache[this._currentState]; }
        }


        
public ArrayGroupState(T[] array)
        
{

            
this.InitCache(array.Length);

            _currentState 
= 0;

        }


        
private int[] GetNextState(int[] stateObject)
        
{
            
//产生一个新的组合
            int[] state = new int[stateObject.Length];
            stateObject.CopyTo(state, 
0);

            
for (int i = state.Length - 1; i >= 0--i)
            
{
                
if (i >= state.Length - 1)
                
{
                    
continue;
                }

                
else
                
{
                    
int[] ar = new int[state.Length - i];
                    Array.Copy(state, i, ar, 
0, ar.Length);
                    Array.Sort(ar);

                    
if (state[i] == ar[ar.Length - 1])
                    
{
                        
continue;
                    }

                    
else
                    
{
                        
int pos = Array.BinarySearch(ar, state[i]);
                        
++pos;
                        state[i] 
= ar[pos];

                        
for (int j = 0; j < ar.Length; ++j)
                        
{
                            
if (j == pos)
                            
{
                                
continue;
                            }


                            state[
++i] = ar[j];
                        }


                        
//产生一个新的组合
                        return state;
                    }

                }


            }


            
return null;
        }


        
private void InitCache(int length)
        
{
            
if (_cachecache.ContainsKey(length))
            
{
                
this._cache = _cachecache[length];
            }

            
else
            
{

                
this._cache = new List<int[]>();

                
//first state 
                int[] state = new int[length];
                
for (int i = 0; i < length; ++i)
                
{
                    state[i] 
= i;
                }



                
while (state != null)
                
{
                    
this._cache.Add(state);

                    
//下一个 state
                    state = this.GetNextState(state);
                }


                _cachecache.Add(length, 
this._cache);
            }

        }


        
public bool MoveNext()
        
{
            
++this._currentState;
            
return this._currentState < this._cache.Count;

        }

    }


    
public   class  ArrayEnum < T >
    
{
        
private ArrayGroupState<T> state = null;
        
private T[] array = null;

        
public ArrayEnum(T[] array)
        
{
            
this.array = array;
        }


        
public T[] GetGroupFirst()
        
{
            state 
= new ArrayGroupState<T>(array);

            
return (T[])this.GetGroup(array, state);
        }


        
public T[] GetGroupNext()
        
{
            
if (state.MoveNext())
            
{
                
return (T[])this.GetGroup(array, state);
            }

            
else
            
{
                
return null;
            }

        }


        
private T[] GetGroup(T[] array, ArrayGroupState<T> state)
        
{
            T[] ret 
= new T[array.Length];
            
for (int i = 0; i < array.Length; ++i)
            
{
                ret[i] 
= array[state.State[i]];
            }


            
return ret;
        }

    }



    
/**/
    
/// <summary>
    
/// 这里就是问题类的实现了
    
/// </summary>

     public   class  Question
    
{
        
public delegate bool GetResultHandler(string[] c, string[] r, string[] s, string[] p, string[] d);

        
private GetResultHandler _getResultHandler = null;

        
public GetResultHandler GetResult
        
{
            
get return _getResultHandler; }
            
set { _getResultHandler = value; }
        }



        
string[] countrys, rooms, smokes, pets, drinks;
        
int calcCount = 0;

        
public Question()
        
{
            
//这里对原始数据进行输入
            this.countrys = new string[] "挪威""英国""瑞典""丹麦""德国" };
            
this.rooms = new string[] """""绿""""" };
            
this.smokes = new string[] "Blends""Pall Mall""Dunhill""Blue Master""Prince" };
            
this.pets = new string[] """""""""" };
            
this.drinks = new string[] """咖啡""""""" };

            GetResult 
= new GetResultHandler(this.OnGetResult);
        }


        
//这里打印第个结果 
        public virtual bool OnGetResult(string[] c, string[] r, string[] s, string[] p, string[] d)
        
{
            Console.WriteLine(
"===================================================");

            Console.WriteLine(
string.Format("country:    {0}"string.Join(" ", c)));
            Console.WriteLine(
string.Format("room:       {0}"string.Join(" ", r)));
            Console.WriteLine(
string.Format("smoke:      {0}"string.Join(" ", s)));
            Console.WriteLine(
string.Format("pet:        {0}"string.Join(" ", p)));
            Console.WriteLine(
string.Format("drink:      {0}"string.Join(" ", d)));

            
return false;
        }


        
/**/
        
/*
   
*/


        
//这里判断是不是正确的解
        private bool isOK(string[] c, string[] r, string[] s, string[] p, string[] d)
        
{
            
//1、英国人住红色房子 
            if ((c != null && r != null&& (Array.IndexOf<string>(c, "英国"!= Array.IndexOf<string>(r, "")))
                
return false;

            
//2、瑞典人养狗 
            if ((c != null && p != null&& (Array.IndexOf<string>(c, "瑞典"!= Array.IndexOf<string>(p, "")))
                
return false;

            
//3、丹麦人喝茶 
            if ((c != null && d != null&& (Array.IndexOf<string>(c, "丹麦"!= Array.IndexOf<string>(d, "")))
                
return false;

            
//4、绿色房子在白色房子左面 
            if ((r != null&& (Array.IndexOf<string>(r, "绿"!= Array.IndexOf<string>(r, ""- 1))
                
return false;

            
//5、绿色房子主人喝咖啡 
            if ((r != null && d != null&& (Array.IndexOf<string>(r, "绿"!= Array.IndexOf<string>(d, "咖啡")))
                
return false;

            
//6、抽Pall Mall 香烟的人养鸟 
            if ((s != null && p != null&& (Array.IndexOf<string>(s, "Pall Mall"!= Array.IndexOf<string>(p, "")))
                
return false;

            
//7、黄色房子主人抽Dunhill 香烟 
            if ((r != null && s != null&& (Array.IndexOf<string>(r, ""!= Array.IndexOf<string>(s, "Dunhill")))
                
return false;

            
//8、住在中间房子的人喝牛奶 
            if ((d != null&& (Array.IndexOf<string>(d, ""!= d.Length / 2))
                
return false;

            
//9、 挪威人住第一间房 
            if ((c != null&& ((Array.IndexOf<string>(c, "挪威"!= 0&& (Array.IndexOf<string>(c, "挪威"!= c.Length - 1)))
                
return false;

            
//10、抽Blends香烟的人住在养猫的人隔壁 
            if ((s != null && p != null&& (Math.Abs(Array.IndexOf<string>(s, "Blends"- Array.IndexOf<string>(p, "")) != 1))
                
return false;

            
//11、养马的人住抽Dunhill 香烟的人隔壁 
            if ((s != null && p != null&& (Math.Abs(Array.IndexOf<string>(s, "Dunhill"- Array.IndexOf<string>(p, "")) != 1))
                
return false;

            
//12、抽Blue Master的人喝啤酒 
            if ((s != null && d != null&& (Array.IndexOf<string>(s, "Blue Master"!= Array.IndexOf<string>(d, "")))
                
return false;

            
//13、德国人抽Prince香烟 
            if ((c != null && s != null&& (Array.IndexOf<string>(c, "德国"!= Array.IndexOf<string>(s, "Prince")))
                
return false;

            
//14、挪威人住蓝色房子隔壁 
            if ((c != null && r != null&& (Math.Abs(Array.IndexOf<string>(c, "挪威"- Array.IndexOf<string>(r, "")) != 1))
                
return false;

            
//15、抽Blends香烟的人有一个喝水的邻居
            if ((s != null && d != null&& (Math.Abs(Array.IndexOf<string>(s, "Blends"- Array.IndexOf<string>(d, "")) != 1))
                
return false;

            
return true;
        }


        
//这里产生可能的结果 
        public void CalcResult()
        
{
            ArrayEnum
<string> ci = new ArrayEnum<string>(this.countrys);
            ArrayEnum
<string> ri = new ArrayEnum<string>(this.rooms);
            ArrayEnum
<string> si = new ArrayEnum<string>(this.smokes);
            ArrayEnum
<string> pi = new ArrayEnum<string>(this.pets);
            ArrayEnum
<string> di = new ArrayEnum<string>(this.drinks);


            
this.calcCount = 0;
            
//通过对数组进行排序来计算
            for (string[] c = ci.GetGroupFirst(); c != null; c = ci.GetGroupNext())
            
{
                
if (!this.isOK(c, nullnullnullnull))
                    
continue;

                
for (string[] r = ri.GetGroupFirst(); r != null; r = ri.GetGroupNext())
                
{
                    
if (!this.isOK(c, r, nullnullnull))
                        
continue;

                    
for (string[] s = si.GetGroupFirst(); s != null; s = si.GetGroupNext())
                    
{
                        
if (!this.isOK(c, r, s, nullnull))
                            
continue;

                        
for (string[] p = pi.GetGroupFirst(); p != null; p = pi.GetGroupNext())
                        
{
                            
if (!isOK(c, r, s, p, null))
                                
continue;

                            
for (string[] d = di.GetGroupFirst(); d != null; d = di.GetGroupNext())
                            
{
                                
//如果结果正确
                                if (isOK(c, r, s, p, d))
                                
{
                                    
//打印出来结果
                                    if (this.GetResult(c, r, s, p, d))
                                    
{
                                        
return;
                                    }

                                }


                            }

                        }

                    }

                }

            }

        }

    }
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值