Мд-а-а-а, в интерес на истината, отговора и аз не го измислих сам ...
... ами по стар навик си написах програма
. И моля, без заяждания какво можело да се направи по-добре
.
[code]
#include <stdio.h>
enum nat { Brit = 1, Swede, Dane, Norw, German };
static const char *nat[] = { 0, "Brit", "Swede", "Dane", "Norw", "German" };
static unsigned int nat_set;
enum color { red = 1, green, yellow, white, blue };
static const char *color[] = { 0, "red", "green", "yellow", "white", "blue" };
static unsigned int color_set;
enum pet { dogs = 1, birds, cats, horses, fish };
static const char *pet[] = { 0, "dogs", "birds", "cats", "horses", "fish" };
static unsigned int pet_set;
enum drink { tea = 1, coffee, milk, beer, water };
static const char *drink[] = { 0, "tea", "coffee", "milk", "beer", "water" };
static unsigned int drink_set;
enum smoke { PallMal = 1, Dunhill, Blends, BlueMaster, Prince };
static const char *smoke[] = { 0, "PallMal", "Dunhill", "Blends", "BlueMaster", "Prince" };
static unsigned int smoke_set;
struct house
{
enum nat nat;
enum color color;
enum pet pet;
enum drink drink;
enum smoke smoke;
};
#define N 5
static struct house house [N];
#define CHECK(a,b) ((a) && !(b) || !(a) && (b))
static int
feasibility_check ()
{
unsigned int i;
/* the Norwegian lives in the first house */
if (house [0].nat && house [0].nat != Norw)
return -1;
/* the man living in the house right in the center drinks milk */
if (house [N / 2].drink && house [N / 2].drink != milk)
return -1;
/* the Norwegian lives next to the blue house */
if (house [1].color && house [1].color != blue)
return -1;
for (i = 0; i < N; ++i)
{
/* the Brit lives in the red house */
if (house [i].nat && house [i].color
&& CHECK (house [i].nat == Brit, house [i].color == red))
return -1;
/* the Swede keeps dogs as pets */
if (house [i].nat && house [i].pet
&& CHECK (house [i].nat == Swede, house [i].pet == dogs))
return -1;
/* the Dane drinks tea */
if (house [i].nat && house [i].drink
&& CHECK (house [i].nat == Dane, house [i].drink == tea))
return -1;
/* the green house is on the left of the white house */
if (i < N - 1 && house [i].color && house [i + 1].color
&& CHECK (house [i].color == green, house [i + 1].color == white))
return -1;
/* the green house owner drinks coffee */
if (house [i].color && house [i].drink
&& CHECK (house [i].color == green, house [i].drink == coffee))
return -1;
/* the person who smokes Pall Mal rears birds */
if (house [i].smoke && house [i].pet
&& CHECK (house [i].smoke == PallMal, house [i].pet == birds))
return -1;
/* the owner of the yellow house smokes Dunhill */
if (house [i].color && house [i].smoke
&& CHECK (house [i].color == yellow, house [i].smoke == Dunhill))
return -1;
/* the man who smokes Blends lives next to the one who keeps cats */
if (house [i].smoke == Blends
&& (i == 0 && house [1].pet && house [1].pet != cats
|| i == N - 1 && house [N - 2].pet && house [N - 2].pet != cats
|| (house [i - 1].pet && house [i + 1].pet
&& house [i - 1].pet != cats && house [i + 1].pet != cats)))
return -1;
/* the man who keeps horses lives next to the one who smokes Dunhill */
if (house [i].pet == horses
&& (i == 0 && house [1].smoke && house [1].smoke != Dunhill
|| i == N - 1 && house [N - 2].smoke && house [N - 2].smoke != Dunhill
|| (house [i - 1].smoke && house [i + 1].smoke
&& house [i - 1].smoke != Dunhill && house [i + 1].smoke != Dunhill)))
return -1;
/* the owner who smokes Blue Master drinks beer */
if (house [i].smoke && house [i].drink
&& CHECK (house [i].smoke == BlueMaster, house [i].drink == beer))
return -1;
/* the German smokes Prince */
if (house [i].nat && house [i].smoke
&& CHECK (house [i].nat == German, house [i].smoke == Prince))
return -1;
/* the man who smokes Blend has a neighbor who drinks water */
if (house [i].smoke == Blends
&& (i == 0 && house [1].drink && house [1].drink != water
|| i == N - 1 && house [N - 2].drink && house [N - 2].drink != water
|| (house [i - 1].drink && house [i + 1].drink
&& house [i - 1].drink != water && house [i + 1].drink != water)))
return -1;
}
return 0;
}
static int try_house (unsigned int);
static int try_nat (unsigned int);
static int try_color (unsigned int);
static int try_pet (unsigned int);
static int try_drink (unsigned int);
static int try_smoke (unsigned int);
static int
print_solution ()
{
unsigned int i;
for (i = 0; i < N; ++i)
printf ("House %d - nat: %s\tcolor: %s\tpet: %s\tdrink: %s\tsmoke: %s\n",
i,
nat [house [i].nat],
color [house [i].color],
pet [house [i].pet],
drink [house [i].drink],
smoke [house [i].smoke]);
puts ("===");
}
static int
try_house (unsigned int i)
{
if (i == N)
{
print_solution ();
return 0;
}
else
return try_nat (i);
}
static int
try_nat (unsigned int i)
{
enum nat nat;
for (nat = Brit; nat <= German; ++nat)
{
if ((nat_set & (1 << nat)) == 0)
{
nat_set |= 1 << nat;
house [i].nat = nat;
if (feasibility_check () == 0 && try_color (i) == 0)
return 0;
nat_set &= ~ (1 << nat);
}
}
house [i].nat = 0;
return -1;
}
static int
try_color (unsigned int i)
{
enum color color;
for (color = red; color <= blue; ++color)
{
if ((color_set & (1 << color)) == 0)
{
color_set |= 1 << color;
house [i].color = color;
if (feasibility_check () == 0 && try_pet (i) == 0)
return 0;
color_set &= ~ (1 << color);
}
}
house [i].color = 0;
return -1;
}
static int
try_pet (unsigned int i)
{
enum pet pet;
for (pet = dogs; pet <= fish; ++pet)
{
if ((pet_set & (1 << pet)) == 0)
{
pet_set |= 1 << pet;
house [i].pet = pet;
if (feasibility_check () == 0 && try_drink (i) == 0)
return 0;
pet_set &= ~ (1 << pet);
}
}
house [i].pet = 0;
return -1;
}
static int
try_drink (unsigned int i)
{
enum drink drink;
for (drink = tea; drink <= water; ++drink)
{
if ((drink_set & (1 << drink)) == 0)
{
drink_set |= 1 << drink;
house [i].drink = drink;
if (feasibility_check () == 0 && try_smoke (i) == 0)
return 0;
drink_set &= ~ (1 << drink);
}
}
house [i].drink = 0;
return -1;
}
static int
try_smoke (unsigned int i)
{
enum smoke smoke;
for (smoke = PallMal; smoke <= Prince; ++smoke)
{
if ((smoke_set & (1 << smoke)) == 0)
{
smoke_set |= 1 << smoke;
house [i].smoke = smoke;
if (feasibility_check () == 0 && try_house (i + 1) == 0)
return 0;
smoke_set &= ~ (1 << smoke);
}
}
house [i].smoke = 0;
return -1;
}
int
main ()
{
try_house (0);
return 0;
}
[/code]