Zebra Game Kata Part 5 - Nationalities

The third part of the first statement in the Zebra Problem says, "inhabited by people of different nationalities".

This will be just like the Doors.

Let's select the house ID of the homes with the same nationality using LINQ.

ZebraGameTest/ZebraProblemTest.cs
[Test]
public void Unique_Nationalities()
{
    zebraProblem.Houses.ForEach( house =>
        Assert.That( 
            zebraProblem.Houses.Count(h => h.Nationality == house.Nationality),
            Is.EqualTo( 1 ),
            "A house was found with the same nationality as house {0}.",
            house.Id ) );
}

Let's talk about this LINQ statement.

For each house in the Zebra Problem, grab a house and assert that all the other houses in the Zebra Problem don't have the same nationality.

If you find a house with the same nationality, stop, and write out a helpful message with the ID.

We can't compile because our House object does not have a nationality. Let's add it.

ZebraGameProblem/House.cs
namespace ZebraGameProblem
{
    public class House
    {
        public int Id { get; set; }

        public DoorColor DoorColor { get; set; }

        public Nationality Nationality { get; set; }
    }
}

Now we add the Nationality enumeration.

ZebraGameProblem/Nationality.cs
namespace ZebraGameProblem
{
    public enum Nationality
    {
    }
}

We can compile, let's run the test.

1 test failed "A house was found with the same nationality as house 1. Expected: 1 But was: 5"

There's a house with the same nationality as house 1. We have not assigned nationalities to the homes yet. The first house is ID 1, and all 5 homes have the same nationality (none).

Let's read ahead in the problem and identify all the possible nationalities. Then we can add them to our enumeration.

ZebraGameProblem/Nationality.cs
namespace ZebraGameProblem
{
    public enum Nationality
    {
        Australian,
        Italian,
        Japanese,
        Norwegian,
        Ukrainian
    }
}

To get the test to pass we need to assign each house a unique nationality.

ZebraGameProblem/ZebraProblem.cs
Houses = new List<House>(houseMax)
{
    new House
    {
        Id = 1,
        DoorColor = DoorColor.Blue,
        Nationality = Nationality.Australian,
    },
    new House
    {
        Id = 2,
        DoorColor = DoorColor.Green,
        Nationality = Nationality.Italian,
    },
    new House
    {
        Id = 3,
        DoorColor = DoorColor.Ivory,
        Nationality = Nationality.Japanese,
    },
    new House
    {
        Id = 4,
        DoorColor = DoorColor.Red,
        Nationality = Nationality.Norwegian,
    },
    new House
    {
        Id = 5,
        DoorColor = DoorColor.Yellow,
        Nationality = Nationality.Ukrainian,
    },
};

Let's run the tests again.

4 tests passed

Now, we need to do the same thing for:

Pets Drinks Food
Dog Coffee Apple
Fox Milk Banana
Horse OrangeJuice Mushroom
Snails Tea Onion
Zebra Water Cake

At the end of adding all of these, our solution looks like this.

ZebraGameProblem/DoorColor.cs
namespace ZebraGameProblem
{
    public enum DoorColor
    {
        Blue,
        Green,
        Ivory,
        Red,
        Yellow
    }
}
ZebraGameProblem/Drink.cs
namespace ZebraGameProblem
{
    public enum Drink
    {
        Coffee,
        Milk,
        OrangeJuice,
        Tea,
        Water
    }
}
ZebraGameProblem/Food.cs
namespace ZebraGameProblem
{
    public enum Food
    {
        Apple,
        Banana,
        Mushroom,
        Onion,
        Cake
    }
}
ZebraGameProblem/House.cs
namespace ZebraGameProblem
{
    public class House
    {
        public int Id { get; set; }

        public DoorColor DoorColor { get; set; }

        public Nationality Nationality { get; set; }
        
        public Pet Pet { get; set; }
        
        public Drink Drink { get; set; }
        
        public Food Food { get; set; }
    }
}
ZebraGameProblem/Nationality.cs
namespace ZebraGameProblem
{
    public enum Nationality
    {
        Australian,
        Italian,
        Japanese,
        Norwegian,
        Ukrainian
    }
}
ZebraGameProblem/Pet.cs
namespace ZebraGameProblem
{
    public enum Pet
    {
        Dog,
        Fox,
        Horse,
        Snails,
        Zebra
    }
}
ZebraGameProblem/ZebraProblem.cs
using System.Collections.Generic;

namespace ZebraGameProblem
{
    public class ZebraProblem
    {
        public ZebraProblem()
        {
            const int houseMax = 5;

            Houses = new List<House>( houseMax )
             {
                 new House
                     {
                         Id = 1,
                         DoorColor = DoorColor.Blue,
                         Nationality = Nationality.Australian,
                         Pet = Pet.Dog,
                         Drink = Drink.Coffee,
                         Food = Food.Apple
                     },
                 new House
                     {
                         Id = 2,
                         DoorColor = DoorColor.Green,
                         Nationality = Nationality.Italian,
                         Pet = Pet.Fox,
                         Drink = Drink.Milk,
                         Food = Food.Banana
                     },
                 new House
                     {
                         Id = 3,
                         DoorColor = DoorColor.Ivory,
                         Nationality = Nationality.Japanese,
                         Pet = Pet.Horse,
                         Drink = Drink.OrangeJuice,
                         Food = Food.Cake
                     },
                 new House
                     {
                         Id = 4,
                         DoorColor = DoorColor.Red,
                         Nationality = Nationality.Norwegian,
                         Pet = Pet.Snails,
                         Drink = Drink.Tea,
                         Food = Food.Mushroom
                     },
                 new House
                     {
                         Id = 5,
                         DoorColor = DoorColor.Yellow,
                         Nationality = Nationality.Ukrainian,
                         Pet = Pet.Zebra,
                         Drink = Drink.Water,
                         Food = Food.Onion
                     },
             };
        }

        public List<House> Houses { get; }
    }
}
ZebraGameTest/ZebraProblemTest.cs
using System.Linq;

using NUnit.Framework;

namespace ZebraGameProblemTests
{
    [TestFixture]
    public class ZebraProblemTest
    {
        [SetUp]
        public void Setup()
        {
            zebraProblem = new ZebraProblem();
        }

        private ZebraProblem zebraProblem;

        [Test]
        public void There_Are_Five_Houses()
        {
            Assert.That( zebraProblem.Houses.Count, 
                Is.EqualTo( 5 ),
                "There must be five houses." );
        }

        [Test]
        public void Unique_Drinks()
        {
            zebraProblem.Houses.ForEach( house =>
                Assert.That( zebraProblem.Houses
                        .Count( h => h.Drink == house.Drink ),
                    Is.EqualTo( 1 ),
                    "A house was found with the same drink as house {0}.",
                    house.Id ) );
        }

        [Test]
        public void Unique_Foods()
        {
            zebraProblem.Houses.ForEach( house =>
                Assert.That( zebraProblem.Houses
                        .Count( h => h.Food == house.Food ),
                    Is.EqualTo( 1 ),
                    "A house was found with the same food as house {0}.",
                    house.Id ) );
        }

        [Test]
        public void Unique_Front_Doors()
        {
            zebraProblem.Houses.ForEach( house =>
                Assert.That( zebraProblem.Houses
                        .Count( h => h.DoorColor == house.DoorColor ),
                    Is.EqualTo( 1 ),
                    "A house was found with the same color door as house {0}.",
                    house.Id ) );
        }

        [Test]
        public void Unique_House_Id()
        {
            zebraProblem.Houses.ForEach( house => 
                Assert.That( zebraProblem.Houses
                        .Count( h => h.Id == house.Id ),
                    Is.EqualTo( 1 ),
                    "A house was found with the same ID as house {0}.",
                    house.Id ) );
        }

        [Test]
        public void Unique_Nationalities()
        {
            zebraProblem.Houses.ForEach( house =>
                Assert.That( zebraProblem.Houses
                        .Count( h => h.Nationality == house.Nationality ),
                    Is.EqualTo( 1 ),
                    "A house was found with the same nationality as house {0}.",
                    house.Id ) );
        }

        [Test]
        public void Unique_Pets()
        {
            zebraProblem.Houses.ForEach( house =>
                Assert.That( zebraProblem.Houses
                        .Count( h => h.Pet == house.Pet ),
                    Is.EqualTo( 1 ),
                    "A house was found with the same pet as house {0}.",
                    house.Id ) );
        }
    }
}

Let's run the tests again.

7 tests passed