예제 #1
0
        public static void Sample_Einsteins_Puzzle()
        {
            //this example shows how to solve Einstein's puzzle
            //go to http://en.wikipedia.org/wiki/Einstein's_Puzzle for more information on puzzle

            var solutions = from n in ArrayExt.Enum <Nationality>().ToConstraintList(5)
                            from c in ArrayExt.Enum <HouseColor>().ToConstraintList(5)
                            from s in ArrayExt.Enum <Smoke>().ToConstraintList(5)
                            from d in ArrayExt.Enum <Drink>().ToConstraintList(5)
                            from p in ArrayExt.Enum <Pet>().ToConstraintList(5)
                            from i in 0.To(4).ToConstraintIndex()
                            where Constraint.AllDifferent(n)
                            where Constraint.AllDifferent(c)
                            where Constraint.AllDifferent(s)
                            where Constraint.AllDifferent(d)
                            where Constraint.AllDifferent(p)
                            where n[0] == Nationality.Norwegian
                            where d[2] == Drink.Milk
                            where (n[i] == Nationality.British) == (c[i] == HouseColor.Red)
                            where (n[i] == Nationality.German) == (s[i] == Smoke.Prince)
                            where (c[i] == HouseColor.Yellow) == (s[i] == Smoke.DunHill)
                            where (n[i] == Nationality.Danish) == (d[i] == Drink.Tea)
                            where (c[i] == HouseColor.Green) == (d[i] == Drink.Coffee)
                            where (s[i] == Smoke.BlueMaster) == (d[i] == Drink.Beer)
                            where (n[i] == Nationality.Swedish) == (p[i] == Pet.Dog)
                            where (s[i] == Smoke.PallMall) == (p[i] == Pet.Bird)
                            where (c[i] == HouseColor.Green) == (c[i + 1] == HouseColor.White)
                            where (p[i] == Pet.Cat) ? (s[i - 1] == Smoke.Blend || s[i + 1] == Smoke.Blend) : true
                            where ((p[i] == Pet.Horse) ? (s[i - 1] == Smoke.DunHill || s[i + 1] == Smoke.DunHill) : true)
                            where ((n[i] == Nationality.Norwegian) ? (c[i - 1] == HouseColor.Blue || c[i + 1] == HouseColor.Blue) : true)
                            where ((s[i] == Smoke.Blend) ? (d[i - 1] == Drink.Water || d[i + 1] == Drink.Water) : true)
                            select 0.To(4).Select(x =>
                                                  new
            {
                Nationality = n[x],
                HouseColor  = c[x],
                Smoke       = s[x],
                Drink       = d[x],
                Pet         = p[x]
            });

            //show results
            Console.WriteLine("\tNationality\tHouseColor\tSmoke\t\tDrink\t\tPet");
            Console.WriteLine(new string('-', 80));
            solutions.First().ForEach((man, i) =>
                                      Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}",
                                                        i + 1,
                                                        man.Nationality.ToString().PadRight(12),
                                                        man.HouseColor.ToString().PadRight(12),
                                                        man.Smoke.ToString().PadRight(12),
                                                        man.Drink.ToString().PadRight(12),
                                                        man.Pet.ToString().PadRight(12))
                                      );
        }
예제 #2
0
        public static void Sample_River_Crossing()
        {
            //this example shows how to solve river crossing puzzle
            //go to http://en.wikipedia.org/wiki/River_IQ_Test for more information on puzzle
            //go to http://freeweb.siol.net/danej/riverIQGame.swf for the game

            //create some variables
            var allPeople = Cross.Thief | Cross.Police | Cross.Father | Cross.Mother | Cross.Son | Cross.Son2 | Cross.Daughter | Cross.Daughter2;

            //STEP 1 - create combination of crossing
            var crossing = ArrayExt.Enum <Cross>().Backtrack(
                //Seed - number of people, and people
                new { Length = 0, Value = (Cross)0 },

                //Func - add number of people, add people
                (current, item, i) => new { Length = current.Length + 1, Value = current.Value | item },

                //Yield - must contains police, father, or mother
                current => (current.Value & (Cross.Police | Cross.Father | Cross.Mother)) > 0
                );

            //thief-police is the same as police-thief, therefore skip police-thief
            crossing.BacktrackingModel = BacktrackingModel.Combination;

            //Answer can be 1 or 2 people on boat
            crossing.ContinueOnYielded = true;

            //Stop backtracking when there are more than 2 people
            crossing.AppendBreak(current => current.Length > 2);

            //Thief must be with police
            crossing.AppendConstraint(current => current.Value == Cross.Thief,
                                      current => item => item == Cross.Police);

            //Father cannot be with daughter
            crossing.AppendConstraint(current => current.Value == Cross.Father,
                                      current => item => item != Cross.Daughter && item != Cross.Daughter2);

            //Mother cannot be with son
            crossing.AppendConstraint(current => current.Value == Cross.Mother,
                                      current => item => item != Cross.Son && item != Cross.Son2);

            //shows result
            Console.WriteLine("below is combination of crossing");
            crossing.SelectResults(c => c.Value).ForEach(c => Console.WriteLine(c));
            Console.WriteLine();

            //----------------------------------------------------------------------
            //STEP 2 - create solutions based on combination of crossing
            var solutions = crossing.SelectResults(c => c.Value).Backtrack(
                //Seed - list of people on landA and landB
                new
            {
                LandA       = allPeople,
                LandB       = (Cross)0,
                BoatOnLandA = true,
                History     = new[] { new { LandA = allPeople, BoatOnLandA = true } }
            },

                //Func - add/subtract crossing people to/from LandA, LandB
                (last, item, i) => new
            {
                LandA       = last.LandA ^ item,
                LandB       = last.LandB ^ item,
                BoatOnLandA = !last.BoatOnLandA,
                History     = last.History.Append(new { LandA = last.LandA ^ item, BoatOnLandA = !last.BoatOnLandA })
            },

                //Yield - all people on LandB
                last => last.LandB == allPeople
                );

            //Thief cannot be with others without police
            solutions.AppendBreak(last =>
                                  ((last.LandA & (Cross.Thief | Cross.Police)) == Cross.Thief) && //no police
                                  (last.LandA != Cross.Thief)                                     //has others
                                  );
            solutions.AppendBreak(last =>
                                  ((last.LandB & (Cross.Thief | Cross.Police)) == Cross.Thief) && //no police
                                  (last.LandB != Cross.Thief)                                     //has others
                                  );

            //Son cannot be with mother without father
            solutions.AppendBreak(last =>
                                  ((last.LandA & (Cross.Father | Cross.Mother)) == Cross.Mother) && //no father
                                  ((last.LandA & (Cross.Son | Cross.Son2)) > 0)                     //has sons
                                  );
            solutions.AppendBreak(last =>
                                  ((last.LandB & (Cross.Father | Cross.Mother)) == Cross.Mother) && //no father
                                  ((last.LandB & (Cross.Son | Cross.Son2)) > 0)                     //has sons
                                  );

            //Daughter cannot be with father without mother
            solutions.AppendBreak(last =>
                                  ((last.LandA & (Cross.Father | Cross.Mother)) == Cross.Father) && //no mother
                                  ((last.LandA & (Cross.Daughter | Cross.Daughter2)) > 0)           //has daugthers
                                  );
            solutions.AppendBreak(last =>
                                  ((last.LandB & (Cross.Father | Cross.Mother)) == Cross.Father) && //no mother
                                  ((last.LandB & (Cross.Daughter | Cross.Daughter2)) > 0)           //has daugthers
                                  );

            //Must have people to cross
            solutions.AppendConstraint(last => last.BoatOnLandA,
                                       last => item => (last.LandA & item) == item);
            solutions.AppendConstraint(last => !last.BoatOnLandA,
                                       last => item => (last.LandB & item) == item);

            //Check history
            solutions.AppendConstraint(last => item => !last.History.Contains(new { LandA = last.LandA ^ item, BoatOnLandA = !last.BoatOnLandA }));

            //show result
            Console.WriteLine("Now start crossing");
            solutions.SelectResults().First().History.ForEach(x =>
            {
                Console.WriteLine(x.LandA);
                Console.WriteLine(allPeople ^ x.LandA);
                Console.WriteLine("=============================================================");
            });
        }
예제 #3
0
        public static void Sample_Einsteins_Puzzle()
        {
            //this example shows how to solve Einstein's puzzle
            //go to http://en.wikipedia.org/wiki/Einstein's_Puzzle for more information on puzzle

            //select combination of each person
            var men = from n in ArrayExt.Enum <Nationality>()
                      from c in ArrayExt.Enum <HouseColor>()
                      where (n == Nationality.British) == (c == HouseColor.Red)
                      from s in ArrayExt.Enum <Smoke>()
                      where (n == Nationality.German) == (s == Smoke.Prince)
                      where (c == HouseColor.Yellow) == (s == Smoke.DunHill)
                      from d in ArrayExt.Enum <Drink>()
                      where (n == Nationality.Danish) == (d == Drink.Tea)
                      where (c == HouseColor.Green) == (d == Drink.Coffee)
                      where (s == Smoke.BlueMaster) == (d == Drink.Beer)
                      from p in ArrayExt.Enum <Pet>()
                      where (n == Nationality.Swedish) == (p == Pet.Dog)
                      where (s == Smoke.PallMall) == (p == Pet.Bird)
                      select new
            {
                Nationality = n,
                HouseColor  = c,
                Smoke       = s,
                Drink       = d,
                Pet         = p
            };

            //Generate solution
            var solutions = men.Backtrack(5);

            //New guy must not has same properties as persons in sequence
            solutions.AppendConstraint(seq => seq.Any(),
                                       seq => man => seq.All(x =>
                                                             x.Nationality != man.Nationality &&
                                                             x.HouseColor != man.HouseColor &&
                                                             x.Smoke != man.Smoke &&
                                                             x.Drink != man.Drink &&
                                                             x.Pet != man.Pet
                                                             )
                                       );

            //Norwegian lives in the first house.
            solutions.AppendConstraint(seq => seq.Length == 0,
                                       seq => man => man.Nationality == Nationality.Norwegian
                                       );

            //Guy who drinks milk lives in the third house
            solutions.AppendConstraint(seq => seq.Length <= 2,
                                       seq => man => (seq.Length == 2) == (man.Drink == Drink.Milk)
                                       );

            //White house is next to green house
            solutions.AppendConstraint(seq => seq.Any(),
                                       seq => man => (seq.Last().HouseColor == HouseColor.Green) == (man.HouseColor == HouseColor.White)
                                       );

            //Guy who pets cat is neighbor with guy who smokes Blend
            solutions.AppendConstraint(seq => seq.Count(x => x.Pet == Pet.Cat || x.Smoke == Smoke.Blend) == 1,
                                       seq => man => (man.Pet == Pet.Cat) || (man.Smoke == Smoke.Blend)
                                       );

            //Guy who pets horse is neighbor with guy who smokes DunHill
            solutions.AppendConstraint(seq => seq.Count(x => x.Pet == Pet.Horse || x.Smoke == Smoke.DunHill) == 1,
                                       seq => man => (man.Pet == Pet.Horse) || (man.Smoke == Smoke.DunHill)
                                       );

            //Norwegian is neighbor with guy lives in blue house
            solutions.AppendConstraint(seq => seq.Count(x => x.Nationality == Nationality.Norwegian || x.HouseColor == HouseColor.Blue) == 1,
                                       seq => man => (man.Nationality == Nationality.Norwegian) || (man.HouseColor == HouseColor.Blue)
                                       );

            //Guy who drinks water is neighbor with guy who smokes Blend
            solutions.AppendConstraint(seq => seq.Count(x => x.Drink == Drink.Water || x.Smoke == Smoke.Blend) == 1,
                                       seq => man => (man.Drink == Drink.Water) || (man.Smoke == Smoke.Blend)
                                       );

            //show results
            Console.WriteLine("\tNationality\tHouseColor\tSmoke\t\tDrink\t\tPet");
            Console.WriteLine(new string('-', 80));
            solutions.First().ForEach((man, i) =>
                                      Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}",
                                                        i + 1,
                                                        man.Nationality.ToString().PadRight(12),
                                                        man.HouseColor.ToString().PadRight(12),
                                                        man.Smoke.ToString().PadRight(12),
                                                        man.Drink.ToString().PadRight(12),
                                                        man.Pet.ToString().PadRight(12))
                                      );
        }