<html>

<head><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- MyFirstUnitAd -->
<ins class="adsbygoogle"
     style="display:inline-block;width:970px;height:250px"
     data-ad-client="ca-pub-5778386704669218"
     data-ad-slot="1503492166"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 6.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Zebra Puzzle</title>
</head>

<body>



<p align="left"><font size="6" color="#FF0000"><b><span lang="en-ca">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>
Z<span lang="en-ca">ebra Puzzle (again)</span></b></font></p>

<div align="left">
  <pre><b><font color="#ff0000" size="5">A.<span lang="en-ca">Second</span> Edition</font></b></pre>
</div>
<div align="left">
  <pre><b>This is <span lang="en-ca">my fourth try for this famous puzzle. </span></b><span lang="en-ca"><b> What's more, it is at least my second</b></span><b><span lang="en-ca"><a href="zebra.htm"> approach</a> for this famous puzzle given</span></b></pre>
</div>
<div align="left">
  <pre><b><span lang="en-ca">by Eistein. </span> The first solution is long time ago and it is a fake which<span lang="en-ca"> </span>I now regard as <a href="zebra.htm">a shame and lesson</a>.<span lang="en-ca">The third try is</span></b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>by &quot;scheme&quot; which is functional programming language.</b></span></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">B</span>.<span lang="en-ca"><a name="problem"></a>The problem</span></font></b></pre>
</div>
<p><font color="#0000FF">Zebra Puzzle:</font></p>    
<p><font color="#0000FF">&nbsp;&nbsp;&nbsp; Five men with different nationalities and with different    
jobs live in consecutive houses on a street. These houses are painted different    
colors. The men have different pets and have different favorite drinks.    
Determine who owns a zebra and whose favorite drinks is mineral water<span lang="en-ca">
</span>(which is    
one of the favorite drinks) given these clues: The Englishman lives in the red    
house. The Spanish owns a dog. The Japanese man is a painter. The Italian drinks    
tea. The Norwegian lives in the first house on the left. The green house is on    
the right of white one. The photographer breeds snails. The diplomat lives in    
the yellow house. Milk is drunk in the middle house. The owner of the green    
house drinks coffee. The Norwegian's house is next to the blue one. The    
violinist drinks orange juice. The fox is in a house next to that of the    
diplomat.&nbsp;</font></p> 
<div align="left">
  <b><font color="#ff0000" size="5"><span lang="en-ca">C</span>.<span lang="en-ca">The
  </span></font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>idea of 
  program</b></font></span></div>
<div align="left">
  <pre><span lang="en-ca"><b>No matter how complicated a problem may become, we can divide and conquer it by counting! And </span>depth<span lang="en-ca">-first-search</span></b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>is one of the simplest way to do it.</b></span></pre>
</div>
<div align="left">
  <pre><b><span lang="en-ca">1. I defined a series of enumerates for better readability.</span></b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>2. The question is considered to a 25 level of searching problem. Each level is an option, say color white, red...</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>It is reasonable since that the five category property is like five functions with same range---The Nationality.</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>(Understand? No matter what property is says, dog as pet, red for house, diplomat as occupation, it all mean a </b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>same person or represented by the nationality. So only after 25 different properties are all assigned to five</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>nationalities, the problem is then solved.</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>3. Most constrains can be enforced at stage of &quot;validateOption&quot; except those involved with position of houses </b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>which I place them at last stage--&quot;evaluate&quot;. Because positions of houses involves more than two categories,</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>like &quot;<font color="#0000FF">t</font></b></span><b><font color="#0000FF">he fox is in a house next to that of the diplomat</font><span lang="en-ca">&quot; --- it uses pet, occupation and position three </span></b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>categories. </b></span></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5">D.<span lang="en-ca"><a name="Method"></a>The </span>major functions</font></b></pre>
</div>
<div align="left">
	<pre><span lang="en-ca"><b>This is just an improved edition of brute-force search. </b></span></pre>
</div>
<div align="left">
	<pre><span lang="en-ca"><b>1. Using lots of enum.</b></span></pre>
</div>
<div align="left">
	<pre><span lang="en-ca"><b>2. Using STL &quot;algorithm&quot; &quot;next_permutation&quot; because I am lazy to write permutation.</b></span></pre>
</div>
<div align="left">
	<pre><span lang="en-ca"><b>3. Using function pointer array.</b></span></pre>
</div>
<div align="left">
	<pre><span lang="en-ca"><b>4. Improved search by reducing &quot;nationality&quot; from permutation. </b></span></pre>
</div>
<div align="left">
  <pre><font size="5" color="#FF0000"><b>E</b></font><b><font color="#ff0000" size="5">.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>Further improvement</b></font></span></pre>
</div>
<div align="left">
  <pre>　</pre>
</div>
<pre>　</pre>
<pre>　</pre>
<pre>/**********************************************************************
1. The Englishmean lives in the red house.
2. The Spanish owns a dog. 
3. The Japanese man is a painter. 
4. The Italian drinks tea. 
5. The Norwegian lives in the first house on the left. 
6. The green house is on the right of white one. 
7. The photographer breeds snails. 
8. The diplomat lives in the yellow house. 
9. Milk is drunk in the middle house. 
10. The owner of the green house drinks coffee. 
11. The Norwegian's house is next to the blue one. 
12. The violinist drinks orange juice. 
13. The fox is in a house next to that of the diplomat. 

***********************************************************************/

#include &lt;iostream&gt;
#include &lt;iomanip&gt;
#include &lt;cmath&gt;
#include &lt;algorithm&gt;
#include &lt;vector&gt;

using namespace std;



const int ItemNumber=5;

const int CategoryNumber=5;



char *occupationStr[ItemNumber] = 
{
	&quot;Diplomat&quot;, &quot;Photogra&quot;, &quot;Painter&quot;, &quot;Violinist&quot;,	 &quot;Physician&quot;
};

char* colorStr[ItemNumber]=
{
	&quot;Red    &quot;, &quot;Yellow &quot;, &quot;White  &quot;, &quot;Green &quot;, &quot;Blue   &quot;
};

char* petStr[ItemNumber]=
{
	 &quot;Dog     &quot;, &quot;Snail  &quot;, &quot;Horse   &quot;, &quot;Zebra   &quot;, &quot;Fox     &quot;
};
char* drinkStr[ItemNumber]=
{
	&quot;Coffee  &quot;, &quot;Juice   &quot;, &quot;Tea     &quot;, &quot;Milk    &quot;, &quot;Water   &quot;
};

char *nationalStr[ItemNumber] = 
{
	&quot;English&quot;, &quot;Spanish &quot;, &quot;Japanese&quot;, &quot;Norwegian&quot;, &quot;Italian &quot;
};

char* positionStr[ItemNumber]=
{
	&quot;First  &quot;, &quot;Second  &quot;, &quot;Third  &quot;, &quot;Fourth  &quot;, &quot;Fifth  &quot;
};

char* categoryName[CategoryNumber]=
{
	 &quot;occupati&quot;, &quot;drink &quot;, &quot;pet &quot;, &quot;color &quot;, &quot;national&quot;
};


enum Category
{
	OccupationCat, DrinkCat, PetCat, ColorCat,NationalCat
};

char** categoryStr[CategoryNumber]=
{
	occupationStr, drinkStr, petStr, colorStr, nationalStr
};


enum National 
{
	English, Spanish, Japanese, Norwegian, Italian
};
enum Occupation
{
	Diplomat, Photographer, Painter, Violinist, Physician
};
enum Color
{
	Red , Yellow , White, Green, Blue
};

enum Pet
{
	Dog, Snail, Horse, Zebra, Fox
};

enum Drink
{
	Coffee, Juice, Tea, Milk, Water
};

enum Position 
{
	First, Second, Third, Fourth, Fifth
};


//typedef vector&lt;int*, IntPtrPred&gt; PermVector;
typedef vector&lt;int&gt; PermVector;

/*
	National national;
	Occupation occupation;
	Color color;
	Pet pet;
	Drink drink;
	Position position;
	*/

struct Person
{
	int values[CategoryNumber];
};

Person persons[ItemNumber];

PermVector permVector[CategoryNumber];

void display();

bool check0();
bool check1();
bool check2();
bool check3();
bool check4();
bool check5();
bool check6();
bool check7();
bool check8();
bool check9();
bool check10();
bool check11();
bool check12();
bool check13();



const int CheckFuncNumber=9;

bool (*pfun[CheckFuncNumber])() = 
{
	check0, check11, check9, check6,check7,check8, check10,  check12, check13
};

bool next();

void initialize();

int main()
{
	bool noError;
	initialize();
	display();
	int i=0, counter=0;
	while (next())
	{
		noError=true;
		for (i=0; i&lt;CheckFuncNumber; i++)
		{
			if (!pfun[i]())
			{
				noError=false;
				break;
			}
		}
		if (noError)
		{
			printf(&quot;find it!!\n&quot;);
			display();			
		}
		//printf(&quot;permutation %d\n&quot;, i++);
		counter++;
		if (counter%20000==0)
		{
			//display();
			printf(&quot;\n===============%d======================\n&quot;, counter);
		}
	}

	printf(&quot;no solution\n&quot;);


 	return 0;
}



bool next()
{
	int category=0, i;
	bool result;
	while (category&lt;CategoryNumber-1)
	{
		result=next_permutation(permVector[category].begin(), permVector[category].end());
		for (i=0; i&lt;ItemNumber; i++)
		{
			persons[i].values[category]=permVector[category][i];
		}
		if (result)
		{
			return true;
		}
		else
		{
			category++;
		}
	}
	return false;
}


void display()
{
	int i, j;
	for (i=0; i&lt;CategoryNumber; i++)
	{
		printf(&quot;%12d&quot;, i+1);
	}
	printf(&quot;\n==============================================================\n&quot;);
	for (i=0; i&lt;CategoryNumber; i++)
	{
		printf(&quot;%9s:&quot;, categoryName[i]);
		for (j=0; j&lt;ItemNumber; j++)
		{
			printf(&quot;%12s&quot;, categoryStr[i][persons[j].values[i]]);
		}
		printf(&quot;\n&quot;);
	}
	printf(&quot;\n&quot;);
	
}

void initialize()
{
	for (int i=0; i&lt;CategoryNumber; i++)
	{
		for (int j=0; j&lt;ItemNumber; j++)
		{
			//they are synchronized at beginning.
			if (i==NationalCat)
			{
				continue;
			}
			permVector[i].push_back(j);
			persons[j].values[i]=j;
		}
	}
}

bool check0()
{
	bool filled[ItemNumber]={false, false, false, false, false};
	filled[0]=true;
	persons[0].values[NationalCat]=Norwegian;
	for (int i=0; i&lt;CategoryNumber-1; i++)
	{
		for (int j=0; j&lt;ItemNumber; j++)
		{
			switch(i)
			{
			case ColorCat:
				if (permVector[i][j]==Red)
				{
					if (filled[j])
					{
						return false;
					}
					persons[j].values[NationalCat]=English;
					filled[j]=true;
				}
				break;
			case PetCat:
				if (permVector[i][j]==Dog)
				{
					if (filled[j])
					{
						return false;
					}
					persons[j].values[NationalCat]=Spanish;
					filled[j]=true;
				}
				break;
			case OccupationCat:
				if (permVector[i][j]==Painter)
				{
					if (filled[j])
					{
						return false;
					}
					persons[j].values[NationalCat]=Japanese;
					filled[j]=true;
				}
				break;
			case DrinkCat:
				if (permVector[i][j]==Tea)
				{
					if (filled[j])
					{
						return false;
					}
					persons[j].values[NationalCat]=Italian;
					filled[j]=true;
				}
				break;
			}
		}
	}
	return true;
}



//The Englishman lives in the red house.
bool check1()
{
	for (int i=0; i&lt;ItemNumber; i++)
	{
		if (persons[i].values[NationalCat]==English)
		{
			return persons[i].values[ColorCat]==Red;
		}
	}
	return false;
}


//The Spanish owns a dog.
bool check2()
{
	for (int i=0; i&lt;ItemNumber; i++)
	{
		if (persons[i].values[NationalCat]==Spanish)
		{
			return persons[i].values[PetCat]==Dog;
		}
	}
	return false;
}


//The Japanese man is a painter.
bool check3()
{
	for (int i=0; i&lt;ItemNumber; i++)
	{
		if (persons[i].values[NationalCat]==Japanese)
		{
			return persons[i].values[OccupationCat]==Painter;
		}
	}
	return false;
}

// The Italian drinks tea.
bool check4()
{
	for (int i=0; i&lt;ItemNumber; i++)
	{
		if (persons[i].values[NationalCat]==Italian)
		{
			return persons[i].values[DrinkCat]==Tea;
		}
	}
	return false;
}

//The Norwegian lives in the first house on the left. 
bool check5()
{
	return persons[0].values[NationalCat]==Norwegian;
}

//The green house is on the right of white one.
bool check6()
{
	int greenIndex=-1, whiteIndex=-1;
	for (int i=0; i&lt;ItemNumber; i++)
	{
		if (persons[i].values[ColorCat]==Green)
		{
			greenIndex=i;
		}
		if (persons[i].values[ColorCat]==White)
		{
			whiteIndex=i;
		}
	}
	return greenIndex==whiteIndex+1;
}

//The photographer breeds snails.
bool check7()
{
	for (int i=0; i&lt;ItemNumber; i++)
	{
		if (persons[i].values[OccupationCat]==Photographer)
		{
			return persons[i].values[PetCat]==Snail;
		}
	}
	return false;
}

//The diplomat lives in the yellow house. 
bool check8()
{
	for (int i=0; i&lt;ItemNumber; i++)
	{
		if (persons[i].values[OccupationCat]==Diplomat)
		{
			return persons[i].values[ColorCat]==Yellow;
		}
	}
	return false;
}

//Milk is drunk in the middle house.
bool check9()
{
	return persons[2].values[DrinkCat]==Milk;
}

//The owner of the green house drinks coffee. 
bool check10()
{
	for (int i=0; i&lt;ItemNumber; i++)
	{
		if (persons[i].values[ColorCat]==Green)
		{
			return persons[i].values[DrinkCat]==Coffee;
		}
	}
	return false;
}

//The Norwegian's house is next to the blue one.
bool check11()
{
	return persons[1].values[ColorCat]==Blue;
}


//The violinist drinks orange juice.
bool check12()
{
	int violinistIndex=-1, orangeIndex=-1;
	for (int i=0; i&lt;ItemNumber; i++)
	{
		if (persons[i].values[OccupationCat]==Violinist)
		{
			return persons[i].values[DrinkCat]==Juice;
		}
	}
	return false;
}


//The fox is in a house next to that of the diplomat. 
bool check13()
{
	int foxIndex=-1, diplomatIndex=-1;
	for (int i=0; i&lt;ItemNumber; i++)
	{
		if (persons[i].values[OccupationCat]==Diplomat)
		{
			diplomatIndex=i;
		}
		if (persons[i].values[PetCat]==Fox)
		{
			foxIndex=i;
		}
	}
	return foxIndex==diplomatIndex+1||foxIndex==diplomatIndex-1;
}

</pre>
<pre>
</pre>
<pre>
</pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre><b><font color="#FF0000"><a name="result"></a><span lang="en-ca"> And here is the result:</span></font></b></pre>
<pre><span lang="en-ca">...</span></pre>

<pre>===============73560000======================
find it
           1           2           3           4           5
==============================================================
 occupati:    Diplomat   Physician    Photogra   Violinist     Painter
   drink :    Water       Tea         Milk        Juice       Coffee  
     pet :    Horse       Fox          Snail      Dog         Zebra   
   color :     Yellow      Blue        Red         White        Green 
 national:   Norwegian    Italian      English    Spanish     Japanese</pre>
<pre><span lang="en-ca">...</span></pre>
<pre>===============73900000======================
find it!!
           1           2           3           4           5
==============================================================
 occupati:    Diplomat   Physician    Photogra   Violinist     Painter
   drink :    Water       Tea         Milk        Juice       Coffee  
     pet :    Zebra       Fox          Snail      Dog         Horse   
   color :     Yellow      Blue        Red         White        Green 
 national:   Norwegian    Italian      English    Spanish     Japanese</pre>
<pre>　</pre>

<pre>
</pre>
<pre></pre>

<p>　</p>

<pre></pre>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                                   
&nbsp;&nbsp;&nbsp; <a href="WhoAmI.htm">                  







                       <img src="picture/back.gif" style="border: medium none" alt="back.gif (341 bytes)" width="32" height="35"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<a href="index.htm"><img src="picture/up.gif" style="border: medium none" alt="up.gif (335 bytes)" width="35" height="32"></a>       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                         
<img src="picture/next.gif" style="border: medium none" alt="next.gif (337 bytes)" width="32" height="35">          


</p>

</body>

</html>