class Fish {
    public static final int nofHouses     = 5;
    public static final int nofProperties = 5;
        
    public static final int NATIONALITY = 0;
    public static final int COLORS      = 1;
    public static final int CIGAR       = 2;
    public static final int PET         = 3;
    public static final int DRINK       = 4;


    static class State {
        String[][] houses = new String[nofHouses][nofProperties];

        State (String[][] houses) {
            for (int i=0; i<nofHouses; i++) {
                for (int j=0; j<nofProperties; j++) {
                    this.houses[i][j] = houses[i][j];
                }
            }
        }
    }


    public static void main (String args[]) throws Exception {
        String[][] houses = {
            {"Norwegian", "Yellow", "Dunhill",    "Cat",   "Water" },
            {"Dane",      "Blue",   "Blend",      "Horse", "Tea"   },
            {"Brit",      "Red",    "PallMall",   "Bird",  "Milk"  },
            {"German",    "Green",  "Prince",     "Fish",  "Coffee"},
            {"Swede",     "White",  "BlueMaster", "Dog",   "Beer"  }
        };
        checkAndPrint (houses);
    }

    public static void checkAndPrint(String[][] houses1) throws Exception {
        String[][] houses = new String[nofHouses][nofProperties];
        for (int i=0; i<nofHouses; i++) {
            for (int j=0; j<nofProperties; j++) {
                houses[i][j] = houses1[i][j];
            }
        }  

        State s = new State (houses);

        condition9(s);
        condition13(s);
        condition4(s);
        condition7(s);
        condition1(s);
        condition2(s);
        condition3(s);
        condition5(s);
        condition6(s);
        condition8(s);
        condition14(s);
        condition12(s);
        condition10(s);
        condition11(s);
        condition15(s);
        
        int iHouse = iFish(s);
        System.out.println("the owner of a fish = " + owner(s, iHouse) );
        System.out.println("");

        for (int i=0; i<nofHouses; i++) {
            String out = "house " + (i+1) + ": ";
            for (int j=0; j<nofProperties; j++) {
                out+=(s.houses[i][j]+" ");
            }
            System.out.println(out);
        }
    }


    public static String owner(State s, int iHouse) {
        return s.houses[iHouse][0];
    }

    public static int iFish(State s) throws Exception {
        for (int i=0; i<nofHouses; i++) {
            if (s.houses[i][3]=="Fish")
            {   s.houses[i][3]= "Fish";
                return i;
            }
        }
        throw new Exception();
    }


    // 1. The Brit lives in a red house. 

    public static void condition1(State s) throws Exception {
        inOneHouse(s, "Brit", "Red");
    }

    // 2. The Swede keeps dogs as pets.

    public static void condition2(State s) throws Exception {
        inOneHouse(s, "Swede", "Dog");
    }

    // 3. The Dane drinks tea. 

    public static void condition3(State s) throws Exception {
        inOneHouse(s, "Dane", "Tea");
    }

    // 4. The green house is on the left of the white house. 

    public static void condition4(State s) throws Exception {
        for (int i=0; i<nofHouses-1; i++) {
            if (s.houses[i]  [COLORS]=="Green" &&
                s.houses[i+1][COLORS]=="White")
            {   s.houses[i]  [COLORS]= "Green";
                s.houses[i+1][COLORS]= "White";
                return;
            }
        }
        throw new Exception();
    }

    // 5. The green house owner drinks coffee. 

    public static void condition5(State s) throws Exception {
        inOneHouse(s, "Green", "Coffee");
    }

    // 6. The person who smokes Pall Mall rears birds. 

    public static void condition6(State s) throws Exception {
        inOneHouse(s, "PallMall", "Bird");
    }

    // 7. The man living in the house right in the centre drinks milk. 

    public static void condition7(State s) throws Exception {
        if (s.houses[(nofHouses-1)/2][DRINK]=="Milk")
        {   s.houses[(nofHouses-1)/2][DRINK]= "Milk";
            return;
        }
        throw new Exception();
    }

    // 8. The owner of the yellow house smokes Dunhill.

    public static void condition8(State s) throws Exception {
        inOneHouse(s, "Yellow", "Dunhill");
    }

    // 9. The Norwegian lives in the first house. 

    public static void condition9(State s) throws Exception {
        if (s.houses[0][NATIONALITY]=="Norwegian")
        {   s.houses[0][NATIONALITY]= "Norwegian";
            return;
        }
        throw new Exception();
    }

    // 10. The man who smokes Blend lives next to the one who keeps cats. 

    public static void condition10(State s) throws Exception {
        inNextHouse(s, "Blend", "Cat");
    }

    // 11. The man who keeps horses lives next to the man who smokes Dunhill. 

    public static void condition11(State s) throws Exception {
        inNextHouse(s, "Dunhill", "Horse");
    }

    // 12. The owner who smokes Blue Master drinks beer. 

    public static void condition12(State s) throws Exception {
        inOneHouse(s, "BlueMaster", "Beer");
    }

    // 13. The Norwegian lives next to the blue house. 

    public static void condition13(State s) throws Exception {
        inNextHouse(s, "Norwegian", "Blue");
    }

    // 14. The German smokes Prince.

    public static void condition14(State s) throws Exception {
        inOneHouse(s, "German", "Prince");
    }

    // 15. The man who smokes Blend has a neighbour who drinks water

    public static void condition15(State s) throws Exception {
        inNextHouse(s, "Blend", "Water");
    }


    public static void inOneHouse(State s, String str1, String str2) throws Exception {
        for (int i=0; i<nofHouses; i++) {
            if (s.houses[i][index(str1)]==str1 &&
                s.houses[i][index(str2)]==str2)
            {   s.houses[i][index(str1)]=str1;
                s.houses[i][index(str2)]=str2;
                return;
            }
        }
        throw new Exception();
    }


    public static void inNextHouse(State s, String str1, String str2) throws Exception {
        for (int i=0; i<nofHouses-1; i++) {
            if (s.houses[i]  [index(str1)]==str1 &&
                s.houses[i+1][index(str2)]==str2)
            {   s.houses[i]  [index(str1)]=str1;
                s.houses[i+1][index(str2)]=str2;
                return;
            }
            if (s.houses[i+1][index(str1)]==str1 &&
                s.houses[i]  [index(str2)]==str2)
            {   s.houses[i+1][index(str1)]=str1;
                s.houses[i]  [index(str2)]=str2;
                return;
            }
        }
        throw new Exception();
    }

    
    public static int index(String str) throws Exception {
        if(str=="Norwegian" || 
           str=="Dane"      ||      
           str=="Brit"      ||      
           str=="German"    ||    
           str=="Swede"     ) return NATIONALITY;     

        if(str=="Yellow" || 
           str=="Blue"   ||   
           str=="Red"    ||    
           str=="Green"  ||  
           str=="White"  ) return COLORS;

        if(str=="Dunhill"    ||    
           str=="Blend"      ||      
           str=="PallMall"   ||   
           str=="Prince"     ||     
           str=="BlueMaster" ) return CIGAR;

        if(str=="Cat"    ||   
           str== "Horse" || 
           str== "Bird"  ||  
           str== "Fish"  ||  
           str== "Dog"   ) return PET;   

        if(str== "Water" ||
           str== "Tea"   ||
           str== "Milk"  ||
           str== "Coffee"||
           str== "Beer"  ) return DRINK;

        throw new Exception();
    }

}