此题源于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, null, null, null, null))
continue;
for (string[] r = ri.GetGroupFirst(); r != null; r = ri.GetGroupNext())
...{
if (!this.isOK(c, r, null, null, null))
continue;
for (string[] s = si.GetGroupFirst(); s != null; s = si.GetGroupNext())
...{
if (!this.isOK(c, r, s, null, null))
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;
}
}
}
}
}
}
}
}
}
... {
/**//// <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, null, null, null, null))
continue;
for (string[] r = ri.GetGroupFirst(); r != null; r = ri.GetGroupNext())
...{
if (!this.isOK(c, r, null, null, null))
continue;
for (string[] s = si.GetGroupFirst(); s != null; s = si.GetGroupNext())
...{
if (!this.isOK(c, r, s, null, null))
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;
}
}
}
}
}
}
}
}
}