Using programs to decrypt Einstein's classic puzzles (C + +)

Source: Internet
Author: User
Tags decrypt

Einstein raised a classic question in early 20th century, saying that 98% of people in the world couldn't answer
Problem: In a street, there are 5 houses, sprayed with 5 colors. There are people of different nationalities living in each house. Everyone drinks a different drink, smokes different brands of cigarettes, and raises different pets.
The question is: Who keeps fish?
Tip: 1. The British live in the Red House
2. Swedish dog keeping
3. Danish Tea
4. Green House on the left of the White House
5. Green House owner Drinks coffee
6. People who smoke pallmall cigarettes raise birds
7. The owner of the Yellow House smokes Dunhill cigarettes.
8. People who live in the Middle house drink milk
9. Norwegian people live in the first room
10. People who smoke bleeds cigarettes live next to the cat-keeping people.
11. A horse man lives next to a man who smokes Dunhill cigarettes.
12. People who smoke bluemaster drink beer
13. The Germans smoked Prince cigarettes
14. The Norwegian people live next to the Blue House
15. People who smoke bleeds cigarettes have a neighbor who drinks water.

This version of the program I will not use any reasoning, just use the program to describe these 15 conditions, and then exhaustive all combinations to meet these 15 conditions the only solution.

First of all, the "people" type, according to the topic can know everyone has color, cigarettes, drinks, pets, location, nationality of these 6 attributes. Although in reality, people smoke cigarettes, drink drinks, keep pets, have nationality, only these 4 properties, color and location is the property of the house, but people live in which house, it determines the color and location of the person, so for simplicity, these 6 attributes are all categorized into an abstract "person". To create a new Person.h file:

Class Person{public:person (Color,country, Drink, cigarette, Pet, int); ~person (void); Color color; Country Country;drink Drink; Cigarette cigarette; Pet pet;int Index;};

according to these 6 kinds of attributes, can create a 5^6 different "person". Then, observing these 15 conditions, the condition 1,2,3,5,6,7,8,9,12,13,14, all is a single person as the constraint condition, and the remaining 4 are the relationship between 2 people as a constraint. First, we can filter out those who do not meet the conditions, and then determine whether the remaining conditions are satisfied by the combination. For example 1. The British live in Red House , then the nationality is British but the color is not red people are not satisfied with the conditions, in turn, the color is red but nationality is not the British people also do not meet the conditions, the description of the program is:

BOOL Test1 (const person &p) {if (p.country==england&&p.color!=red) | | (p.country!=england&&p.color==red)) return False;return true;}

In the same vein, the remaining human-constrained conditions are described as:

BOOL Test2 (const person &p) {if (P.country==sweden&&p.pet!=dog) | | (P.country!=sweden&&p.pet==dog)) return False;return true;} BOOL Test3 (const person &p) {if (P.country==denmark&&p.drink!=tea) | | (P.country!=denmark&&p.drink==tea)) return False;return true;} BOOL Test5 (const person &p) {if (P.color==green&&p.drink!=coffee) | | (P.color!=green&&p.drink==coffee)) return False;return true;} BOOL Test6 (const person &p) {if (P.cigarette==pallmall&&p.pet!=bird) | | (P.cigarette!=pallmall&&p.pet==bird)) return False;return true;} BOOL Test7 (const person &p) {if (P.color==yellow&&p.cigarette!=dunhill) | | (P.color!=yellow&&p.cigarette==dunhill)) return False;return true;} BOOL Test8 (const person &p) {if (P.index==3&&p.drink!=milk) | | (P.index!=3&&p.drink==milk)) return False;return true;} BOOL Test9 (const person &p) {if (p.country==norway&&p.index!=1) | | (p.country!=norway&&p.index==1)) RetuRN False;return true;} BOOL Test12 (const person &p) {if (p.cigarette==bluemaster&&p.drink!=bear) | | (P.cigarette!=bluemaster&&p.drink==bear)) return False;return true;} BOOL Test13 (const person &p) {if (p.country==germany&&p.cigarette!=prince) | | (p.country!=germany&&p.cigarette==prince)) return False;return true;} Condition 14 can be directly expressed as the Blue House is the second room bool test14 (const person &p) {if ((p.color==blue&&p.index!=2) | | (p.color!=blue&&p.index==2)) return False;return true;}
Filter out the effective "people" and then put these "people" into different "houses"

vector<person> v1;vector<person> v2;vector<person> v3;vector<person> V4;vector<Person > v5;for (int color=0;color<5;++color) for (int. country=0;country<5;++country) for (int drink=0;drink<5;++ drink) for (int cigarette=0;cigarette<5;++cigarette) for (int. Pet=0;pet<5;++pet) for (int index=1;index<=5;++ index) {person P ((color) color, (country) country, (Drink) Drink, (cigarette) cigarette, (Pet) pet,index); if (Test1 (p) &&test2 (P) &&test3 (P) &&test5 (P) &&test6 (P) &&test7 (P) &&test8 (p) &&test9 (P) &&test12 (P) &&test13 (P) &&test14 (p)) {switch (p.index) {case 1:v1.push_ Back (p); break;case 2:v2.push_back (P); break;case 3:v3.push_back (P); break;case 4:v4.push_back (P); Break;case 5: V5.push_back (P); break;}}}

The 5 sets represent 5 houses numbered 1-5, which are constructed through a cycle of "people" and throw the eligible people into different houses. In this way, got 5 houses, each house has some people, these people have met all the conditions before, then each house sent a person, judge whether the 5 people can meet the remaining conditions, if satisfied, then these 5 people are the answer, not satisfied, then the substitution, It's over until all the people have been combined.

size_t s1=v1.size (); size_t s2=v2.size (); size_t s3=v3.size (); size_t s4=v4.size (); size_t s5=v5.size (); int count=0;string countryname[5]={"Englishman", "Swede", "Danish", "Norwegian", "German"};string colorname[5]={"Blue", "green", "white", "red", "Yellow"}; String drinkname[5]={"Tea", "milk", "coffee", "beer", "Water"};string cigarettename[5]={"Pallmall", "Dunhill", "bleeds", "Bluemaster" , "Prince"};string petname[5]={"fish", "dog", "Bird", "cat", "Horse"};for (int i1=0;i1<s1;++i1) for (int. I2=0;I2&LT;S2;++I2) for (int I3=0;I3&LT;S3;++I3) for (int i4=0;i4<s4;++i4) for (int. i5=0;i5<s5;++i5) {person pp[5]={v1[i1],v2[i2],v3[i3],v4[ I4],v5[i5]};if (testdistinct (PP) &&test4 (pp) &&test10 (pp) &&test11 (pp) &&test15 (PP) ) {cout<< "Answer" <<++count<< ":" <<endl;for (int i=0;i<5;++i) {cout<< "section" <<i+1< < "room is" <<colorName[pp[i].color]<< ", Live" <<countryName[pp[i].country]<< ", Drink" << drinkname[pp[i].drink]<< ", pumping" <<cigaretteName[pp[i].cigarette]<< ", Raising" <<petname[pp[i].pet " <<Endl;}}} 

In addition to the remaining 4 conditions there is a hidden condition, that is, the nature of human beings can not be repeated, for example, the 5 people can not have 2 Britons, can not have 2 people or 3 people at the same time to raise fish.

Go to heavy verification, here's a little bit of a trick:

BOOL Testdistinct (person *pp) {int state[25]={0};for (int. i=0;i<5;++i) {for (int j=0;j<5;++j) {state[j]+=pp[i]. color== (Color) j;state[j+5]+=pp[i].drink== (drink) j;state[j+10]+=pp[i].cigarette== (cigarette) j;state[j+15]+=pp[i ].pet== (PET) j;state[j+20]+=pp[i].country== (country) J;} for (int i=0;i<25;i++) {if (state[i]!=1) return false;} return true;}
People have been divided into different houses, so the index of these 5 people will certainly not repeat, just to determine whether the remaining 5 properties are duplicated. Each property is 5 states, 5 properties are 25 states, and then a one-dimensional array of length 25 is represented, such as state[0] for the number of blue attributes, state[1] for the number of green attributes, State[5] for the number of tea people, Then 5 people loop to determine if these states exist, and if so, add 1 to the State array count. If the combination is not duplicated, it means that each item of the state array is exactly 1, and if one of the items is not equal to 1, there must be a repetition.

The remaining 4 conditions are judged:

BOOL Test4 (person *pp) {person *p1,*p2;for (int i=0;i<5;++i) {if (pp[i].color==green) p1=&pp[i];    if (pp[i].color==white) p2=&pp[i];} return p1->index==p2->index-1;} BOOL Test10 (person *pp) {person *p1,*p2;for (int i=0;i<5;++i) {if (pp[i].cigarette==bleeds) p1=&pp[i];    if (Pp[i].pet==cat) p2=&pp[i];} return p1->index==p2->index-1| | p1->index==p2->index+1;} BOOL Test11 (person *pp) {person *p1,*p2;for (int i=0;i<5;++i) {if (pp[i].pet==horse) p1=&pp[i];    if (Pp[i].cigarette==dunhill) p2=&pp[i];} return p1->index==p2->index-1| | p1->index==p2->index+1;} BOOL Test15 (person *pp) {person *p1,*p2;for (int i=0;i<5;++i) {if (pp[i].drink==water) p1=&pp[i];    if (pp[i].cigarette==bleeds) p2=&pp[i];} return p1->index==p2->index-1| | p1->index==p2->index+1;}

The principle is to find 2 of the conditions from 5 people, and then judge their index attributes, so-called neighbors, next door is to indicate that their index is connected.

Here the code is finished, and the final result is:



Finally summed up: why some problems can not be solved by the computer to solve, although the problem with the method of drawing a table to infer the answer is not too difficult, but compared to the computer program is more simple and rough, and people can not use this way to think about problems. If you want to calculate 987*512, and you don't multiply the formula, how do you get the result? At this time gave you a huge piece of grass paper, and the above writing speed will be very fast, fortunately, your addition is good, so you continue to calculate 987+987=1974,1974+987=2961 ... until you add 512 987, and finally you get the right answer, Because the writing speed is very fast, or even faster than you use multiplication formula to get the answer, this is the computer solves the problem of people can not solve the principle, the computer is like such a grass manuscript. As for how to describe the problem to computer computing (turning multiplication problems into additive problems) and making the computer run faster (you can accumulate 512 times, you can just add 9 times), which involves a major course in computer science-data structures and algorithms.


This article original address: http://blog.csdn.net/maidou0921/article/details/51910075

Using programs to decrypt Einstein's classic puzzles (C + +)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.