public class GetHouse {
static enum Country {Norway,Sweden,German,Danmark,England};//Norway必须放在第一位
static enum Drink {Coffee,Beer,Milk,Tea,NONE};//牛奶必须放在中间
static enum Pet {Dog,Bird,Cat,Horse,NONE};
static enum Cigarrete{MIX,PRINCE,MASTER,DUNHILL,PALL};
static enum Color{Red,Blue,White,Green,Yellow};//蓝色必须在第二个位置
static int[][] a=new int[5][5];//初始数组,每行为国家,饮料,宠物,香烟,房子颜色
static int[][] all=new int[120][5];
static int[][] a1=new int[24][5];
static int[][] a2=new int[5][5];//只有四种情况并预留一个
static int[][] a3=new int[24][5];
static int A2Len=0;
// 已经包含挪威人住在第一间房子;住在中间房子的人喝牛奶;挪威人住在蓝房子旁
static void init(){
for(int i=0;i<5;i++){
for(int j=0;j<5;j++){
a[i][j]=j;
}
}
}
// 初始化5!的阶承数组
static void initAll(){
int c=0;
for(int i=0;i<5;i++){
for(int j=0;j<5;j++){
if(j==i) continue;
for(int k=0;k<5;k++){
if(k==i || k==j) continue;
for(int m=0;m<5;m++){
if(m==i || m==j || m==k) continue;
for(int n=0;n<5;n++){
if(n==i || n==j || n==k || n==m) continue;
all[c][0]=i;
all[c][1]=j;
all[c][2]=k;
all[c][3]=m;
all[c][4]=n;
c++;
}
}
}
}
}
}
// 初始化5!的阶承数组(第1个数据始终为0)
static void initA1(){
int c=0;
int i=0;
for(int j=1;j<5;j++){
for(int k=1;k<5;k++){
if(k==j) continue;
for(int m=1;m<5;m++){
if(m==j || m==k) continue;
for(int n=1;n<5;n++){
if(n==j || n==k || n==m) continue;
a1[c][0]=i;
a1[c][1]=j;
a1[c][2]=k;
a1[c][3]=m;
a1[c][4]=n;
c++;
}
}
}
}
}
// 初始化5!的阶承数组(第2个数据始终为1)
static void initA2(){
int c=0;
int j=1;
for(int i=0;i<5;i++){
if(i==j)continue;
for(int k=0;k<5;k++){
if(k==i || k==j) continue;
for(int m=0;m<5;m++){
if(m==i || m==j || m==k) continue;
for(int n=0;n<5;n++){
if(n==i || n==j || n==k || n==m) continue;
a2[c][0]=i;
a2[c][1]=j;
a2[c][2]=k;
a2[c][3]=m;
a2[c][4]=n;
int g=-1,w=-1;
for(int x=0;x<5;x++){
if(a2[c][x]==Color.Green.ordinal()){
g=x;
}
if(a2[c][x]==Color.White.ordinal()){
w=x;
}
}
if(g==w-1)c++;//绿房子在白房子左边
}
}
}
}
A2Len=c;
}
// 初始化5!的阶承数组(第3个数据始终为2)
static void initA3(){
int c=0;
int k=2;
for(int i=0;i<5;i++){
if(i==k)continue;
for(int j=0;j<5;j++){
if(j==i || j==k) continue;
for(int m=0;m<5;m++){
if(m==i || m==j || m==k) continue;
for(int n=0;n<5;n++){
if(n==i || n==j || n==k || n==m) continue;
a3[c][0]=i;
a3[c][1]=j;
a3[c][2]=k;
a3[c][3]=m;
a3[c][4]=n;
c++;
}
}
}
}
}
//到某一行查找相应的数据
static int find(int row,int data){
for(int i=0;i<5;i++){
if(a[row][i]==data){
return i;
}
}
return -1;
}
//判断是否在旁边
static boolean by(int x1,int x2){
return(x1-1==x2 || x2-1==x1);
}
//以下是11个条件(去除:挪威人住在第一间房子;住在中间房子的人喝牛奶;挪威人住在蓝房子旁)
static boolean C04(){//英国人住在红房子里
int index=find(0,Country.England.ordinal());
return index>=0 && a[4][index]==Color.Red.ordinal();
}
static boolean C02(){//瑞典人养了一条狗
int index=find(0,Country.Sweden.ordinal());
return index>=0 && a[2][index]==Pet.Dog.ordinal();
}
static boolean C01(){//丹麦人喝茶
int index=find(0,Country.Danmark.ordinal());
return index>=0 && a[1][index]==Drink.Tea.ordinal();
}
static boolean C03(){//德国人抽PRINCE烟
int index=find(0,Country.German.ordinal());
return index>=0 && a[3][index]==Cigarrete.PRINCE.ordinal();
}
static boolean C44(){//绿房子在白房子左边
int index=find(4,Color.Green.ordinal());
return index>=0 && index==find(4,Color.White.ordinal())-1;
}
static boolean C41(){//绿房子主人喝咖啡
int index=find(4,Color.Green.ordinal());
return index>=0 && a[1][index]==Drink.Coffee.ordinal();
}
static boolean C43(){//黄房子主人抽DUNHILL烟
int index=find(4,Color.Yellow.ordinal());
return index>=0 && a[3][index]==Cigarrete.DUNHILL.ordinal();
}
static boolean C31(){//抽BLUE MASTER烟的人喝啤酒
int index=find(3,Cigarrete.MASTER.ordinal());
return index>=0 && a[1][index]==Drink.Beer.ordinal();
}
static boolean C32(){//抽PALL MALL烟的人养了一只鸟
int index=find(3,Cigarrete.PALL.ordinal());
return index>=0 && a[2][index]==Pet.Bird.ordinal();
}
static boolean C32_1(){//抽混合烟的人住在养猫人的旁边
int x1=find(3,Cigarrete.MIX.ordinal());
int x2=find(2,Pet.Cat.ordinal());
return by(x1,x2);
}
static boolean C32_2(){//养马人住在抽DUNHILL烟的人旁边
int x1=find(3,Cigarrete.DUNHILL.ordinal());
int x2=find(2,Pet.Horse.ordinal());
return by(x1,x2);
}
//嵌套检测第一至第五行排列组合
static boolean swap1(){
for(int i=0;i<a1.length;i++){
for(int j=0;j<5;j++){
a[0][j]=a1[i][j];
}
if(swap2()){
return true;
}
}
return false;
}
static boolean swap2(){
for(int i=0;i<a3.length;i++){
for(int j=0;j<5;j++){
a[1][j]=a3[i][j];
}
if(C01() && swap3()){
return true;
}
}
return false;
}
static boolean swap3(){
for(int i=0;i<all.length;i++){
for(int j=0;j<5;j++){
a[2][j]=all[i][j];
}
if(C02() && swap4()){
return true;
}
}
return false;
}
static boolean swap4(){
for(int i=0;i<all.length;i++){
for(int j=0;j<5;j++){
a[3][j]=all[i][j];
}
if(C03() && C31() && C32() && C32_1() && C32_2() && swap5()){
return true;
}
}
return false;
}
static boolean swap5(){
for(int i=0;i<A2Len;i++){
for(int j=0;j<5;j++){
a[4][j]=a2[i][j];
}
if(C04() && C41() && C43()){//&& C44()***绿房子在白房子左边已经处理*****
return true;
}
}
return false;
}
//已经包含挪威人住在第一间房子;住在中间房子的人喝牛奶;挪威人住在蓝房子旁
static void search(){
long time=System.currentTimeMillis();
init();
initAll();
initA1();
initA2();
initA3();
boolean b=swap1();
time=System.currentTimeMillis()-time;
if(!b){
System.out.println("没有找到答案,下面是最终结果:(用时"+time+"毫秒)");
}else{
System.out.println("找到正确答案,下面是最终结果:(用时"+time+"毫秒)");
}
print();
}
//显示结果
static void print(){
for(int i=0;i<a.length;i++){
for(int j=0;j<5;j++){
switch(i){
case 0:System.out.print(Country.values()[a[i][j]]+"/t");break;
case 1:System.out.print(Drink.values()[a[i][j]]+"/t");break;
case 2:System.out.print(Pet.values()[a[i][j]]+"/t");break;
case 3:System.out.print(Cigarrete.values()[a[i][j]]+"/t");break;
case 4:System.out.print(Color.values()[a[i][j]]+"/t");break;
}
}
System.out.println("");
}
}
static void print(int[][] data){
for(int i=0;i<data.length;i++){
for(int j=0;j<5;j++){
System.out.print(data[i][j]+"/t");
}
System.out.println("");
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
search();
}
}