24点运算2

这是本人2年前业余时间写的application版本的24点游戏的简单实现。共享出来,希望能起到抛砖引玉的作用,一起探讨24点的实现。

1、计算方式的改变——引入分数计算概念

求24点涉及到除法,所以必须转变直接计算的思路。经过一段时间的摸索,本人发现可以采用分数计算。任何两个数的计算都可以转换成对应的分数计算形式。

 例如:3 / 8 可以转换成 (3/1) / (8/1)

1.1 待计算数字的初始化

于是待计算的4个值必须先转换成分数:

Java代码  收藏代码
  1. private int[] aArray = new int[2];  
  2. private int[] bArray = new int[2];  
  3. private int[] cArray = new int[2];  
  4. private int[] dArray = new int[2];  

当然,我们得初始化它们: 效果就是2->2/ 1

Java代码  收藏代码
  1. aArray[0] = a;  
  2. aArray[1] = 1;  
  3. bArray[0] = b;  
  4. bArray[1] = 1;  
  5. cArray[0] = c;  
  6. cArray[1] = 1;  
  7. dArray[0] = d;  
  8. dArray[1] = 1;  

 1.2 分数的计算

小学的时候就学过,分数的加减法用到最小公倍数和最大公约数。

Java代码  收藏代码
  1. /** 
  2.  * 求最小公倍数 
  3.  *  
  4.  * @param a 
  5.  * @param b 
  6.  * @return 
  7.  */  
  8. public int leaseCommonMultiple(int a, int b) {  
  9.     return a * b / greatestCommonDivisor(a, b);  
  10. }  
  11.   
  12. /** 
  13.  * 求最大公约数 
  14.  *  
  15.  * @param a 
  16.  * @param b 
  17.  * @return 
  18.  */  
  19. public int greatestCommonDivisor(int a, int b) {  
  20.     if (0 == a && 0 == b) {  
  21.         return 1;  
  22.     }  
  23.     if (0 == a) {  
  24.         return b;  
  25.     }  
  26.     if (0 == b) {  
  27.         return a;  
  28.     }  
  29.     if (a > b) {  
  30.         int c = a;  
  31.         a = b;  
  32.         b = c;  
  33.     }  
  34.     for (int c = a % b; c > 0; c = a % b) {  
  35.         a = b;  
  36.         b = c;  
  37.     }  
  38.     return b;  
  39. }  

 对应的加减方法如下:

Java代码  收藏代码
  1. /** 
  2.  * 加 
  3.  */  
  4. public int[] plus(int[] a, int[] b) {  
  5.   
  6.     if (0 == a[1]) {  
  7.         return new int[] { 00 };  
  8.     }  
  9.     if (0 == b[1]) {  
  10.         return new int[] { 00 };  
  11.     }  
  12.     int denominator = leaseCommonMultiple(a[1], b[1]);  
  13.   
  14.     return new int[] {  
  15.             denominator / a[1] * a[0] + denominator / b[1] * b[0],  
  16.             denominator };  
  17. }  
  18.   
  19. /** 
  20.  * 减 
  21.  *  
  22.  * @param a 
  23.  * @param b 
  24.  * @return 
  25.  */  
  26. public int[] reduce(int[] a, int[] b) {  
  27.     if (0 == a[1]) {  
  28.         return new int[] { 00 };  
  29.     }  
  30.     if (0 == b[1]) {  
  31.         return new int[] { 00 };  
  32.     }  
  33.     int denominator = leaseCommonMultiple(a[1], b[1]);  
  34.   
  35.     return new int[] {  
  36.             denominator / a[1] * a[0] - denominator / b[1] * b[0],  
  37.             denominator };  
  38. }  

 相对来说,乘除方法就简单多了:

Java代码  收藏代码
  1. /** 
  2.  * 乘 
  3.  *  
  4.  * @param a 
  5.  * @param b 
  6.  * @return 
  7.  */  
  8. public int[] multiply(int[] a, int[] b) {  
  9.     return new int[] { a[0] * b[0], a[1] * b[1] };  
  10. }  
  11.   
  12. /** 
  13.  * 除 
  14.  *  
  15.  * @param a 
  16.  * @param b 
  17.  * @return 
  18.  */  
  19. public int[] divide(int[] a, int[] b) {  
  20.     return new int[] { a[0] * b[1], a[1] * b[0] };  
  21. }  

 

 

2、计算规则

2.1 算法——穷举法

24点的计算涉及到以下三种元素:

 待计算的4个数、三个计算符号(加减乘除)、括号

 本人采用的是穷举法,进行一个一个数值和符号的尝试——这样的话,在循环中数值和符号都必须是动态的。

Java代码  收藏代码
  1. /** 
  2.  * 动态加载符号数 
  3.  * @param i 
  4.  * @param a 
  5.  * @param b 
  6.  * @return 
  7.  */  
  8. public  int[] dispose(int i, int a[], int[] b){  
  9.     if(i == 0){  
  10.         return plus(a, b);  
  11.     }else if(i == 1){  
  12.         return reduce(a, b);  
  13.     }else if(i == 2){  
  14.         return multiply(a, b);  
  15.     }else{  
  16.         return divide(a, b);  
  17.     }  
  18. }  
  19.   
  20. /** 
  21.  * 动态加载计算数 
  22.  * @param i 
  23.  * @param a 
  24.  * @param b 
  25.  * @param c 
  26.  * @param d 
  27.  * @return 
  28.  */  
  29. public int[] number(int i, int[] a, int[] b, int[] c, int[] d){  
  30.     if(i == 0){  
  31.         return a;  
  32.     }else if(i == 1){  
  33.         return b;  
  34.     }else if(i == 2){  
  35.         return c;  
  36.     }else if(i == 3){  
  37.         return d;  
  38.     }else{  
  39.         return new int[]{0,1};  
  40.     }  
  41. }  

 

2.2 括号规则:

类型1:A(A(A(a,b),c),d)

类型2:A(A(a,A(b,c)),d)

类型3:A(a,A(b,A(c,d)))

类型4:A(a,A(A(b,c),d))

类型5:A(A(a,b),A(c,d))

注:A就是1个符号,A(a,b)就是指:a+b, a-b, a*b, a/b四种情况

 

2.3 数值与符号的穷举

把每个数值和符号一个进行尝试:

i,j,k        :符号

m,n,o,p  :数值

Java代码  收藏代码
  1. for(int i = 0; i < 4; i++){  
  2.     for(int j = 0; j < 4; j++){  
  3.         for(int k = 0; k < 4; k++){  
  4.             for(int m = 0; m < 4; m++){  
  5.                 for(int n = 0; n < 4; n++){  
  6.                     if(n == m)  
  7.                         continue;  
  8.                     for(int o = 0; o < 4; o++){  
  9.                         if(o == m || o == n)  
  10.                             continue;  
  11.                         for(int p = 0; p < 4; p++){  
  12.                             if(p == m || p == n || p == o)  
  13.                                 continue;  
  14.                                                                                                                                      。。。 计算方法。。。  
  15.                               
  16.                         }  
  17.                     }  
  18.                 }  
  19.             }  
  20.         }  
  21.     }  
  22. }  

 

计算方法:

Java代码  收藏代码
  1. //类型1:A(A(A(a,b),c),d)  
  2. int[] result1 = dispose(k,dispose(j,dispose(i,number(m,a,b,c,d),number(n,a,b,c,d)),number(o,a,b,c,d)),number(p,a,b,c,d));  
  3. //类型2:A(A(a,A(b,c)),d)  
  4. int[] result2 = dispose(k,dispose(i,number(m,a,b,c,d),dispose(j,number(n,a,b,c,d),number(o,a,b,c,d))),number(p,a,b,c,d));  
  5. //类型3:A(a,A(b,A(c,d)))  
  6. int[] result3 = dispose(i,number(m,a,b,c,d),dispose(j,number(n,a,b,c,d),dispose(k,number(o,a,b,c,d),number(p,a,b,c,d))));  
  7. //类型4:A(a,A(A(b,c),d))  
  8. int[] result4 = dispose(i,number(m,a,b,c,d),dispose(k,dispose(j,number(n,a,b,c,d),number(o,a,b,c,d)),number(p,a,b,c,d)));                                     
  9. //类型5:A(A(a,b),A(c,d))  
  10. int[] result5 = dispose(j,dispose(i,number(m,a,b,c,d),number(n,a,b,c,d)),dispose(k,number(o,a,b,c,d),number(p,a,b,c,d)));  
  11. if (0 != result1[1]) {  
  12.     if (result1[0] % result1[1] == 0) {  
  13.         if (result1[0] / result1[1] == 24) {  
  14.             if ((!map.containsKey(new Integer(i)))|| (!map.containsKey(new Integer(j)))|| (!map.containsKey(new Integer(k)))) {  
  15.                 map.put(new Integer(i),new Integer(i));  
  16.                 map.put(new Integer(j),new Integer(j));  
  17.                 map.put(new Integer(k),new Integer(k));  
  18.                 count += 1;  
  19.                 System.out.println("((" + printNumber(m) + printSymbol(i) + printNumber(n) + ")" + printSymbol(j) + printNumber(o) + ")" + printSymbol(k) + printNumber(p));  
  20.             }  
  21.         }  
  22.     }  
  23. }  
  24. if (0 != result2[1]) {  
  25.     if (result2[0] % result2[1] == 0) {  
  26.         if (result2[0] / result2[1] == 24) {  
  27.             if ((!map.containsKey(new Integer(i)))|| (!map.containsKey(new Integer(j)))|| (!map.containsKey(new Integer(k)))) {  
  28.                 map.put(new Integer(i),new Integer(i));  
  29.                 map.put(new Integer(j),new Integer(j));  
  30.                 map.put(new Integer(k),new Integer(k));  
  31.                 count += 1;  
  32.                 System.out.println("(" + printNumber(m) + printSymbol(i) +"(" + printNumber(n) + printSymbol(j) + printNumber(o) + "))" + printSymbol(k) + printNumber(p));  
  33.             }  
  34.         }  
  35.     }  
  36. }  
  37. if (0 != result3[1]) {  
  38.     if (result3[0] % result3[1] == 0) {  
  39.         if (result3[0] / result3[1] == 24) {  
  40.             if ((!map.containsKey(new Integer(i))) || (!map.containsKey(new Integer(j)))|| (!map.containsKey(new Integer(k)))) {  
  41.                 map.put(new Integer(i),new Integer(i));  
  42.                 map.put(new Integer(j),new Integer(j));  
  43.                 map.put(new Integer(k),new Integer(k));  
  44.                 count += 1;  
  45.                 System.out.println(printNumber(m) + printSymbol(i) +"(" + printNumber(n) + printSymbol(j) + "(" + printNumber(o) +  printSymbol(k) + printNumber(p) + "))");  
  46.             }  
  47.         }  
  48.     }  
  49. }  
  50. if (0 != result4[1]) {  
  51.     if (result4[0] % result4[1] == 0) {  
  52.         if (result4[0] / result4[1] == 24) {  
  53.             if ((!map  
  54.                     .containsKey(new Integer(i)))|| (!map.containsKey(new Integer(j)))|| (!map.containsKey(new Integer(k)))) {  
  55.                 map.put(new Integer(i),new Integer(i));  
  56.                 map.put(new Integer(j),new Integer(j));  
  57.                 map.put(new Integer(k),new Integer(k));  
  58.                 count += 1;  
  59.                 System.out.println(printNumber(m) + printSymbol(i) +"((" + printNumber(n) + printSymbol(j) + printNumber(o) + ")" +  printSymbol(k) + printNumber(p) + ")");  
  60.             }  
  61.         }  
  62.     }  
  63. }  
  64. if (0 != result5[1]) {  
  65.     if (result5[0] % result5[1] == 0) {  
  66.         if (result5[0] / result5[1] == 24) {  
  67.             if ((!map.containsKey(new Integer(i)))|| (!map.containsKey(new Integer(j)))|| (!map.containsKey(new Integer(k)))) {  
  68.                 map.put(new Integer(i),new Integer(i));  
  69.                 map.put(new Integer(j),new Integer(j));  
  70.                 map.put(new Integer(k),new Integer(k));  
  71.                 count += 1;  
  72.                 System.out.println("(" + printNumber(m) + printSymbol(i) + printNumber(n) + ")" + printSymbol(j) + "(" + printNumber(o) + printSymbol(k) + printNumber(p) + ")");  
  73.             }  
  74.         }  
  75.     }  
  76. }  

 该程序目前存在的一些问题:

1)、存在括号多余的情况——如:1 + (2 + (3 * 7))和((2 + 7) - 1) * 3

2)、结果打印耦合在核心计算方法中

 

具体代码:

复制代码
package com.chanson;
/*
 * @date   Aug 3, 2006
 * @project 学习
 * @company 个人
 * @author  chanson
 * @version 1.0
 */
import java.util.HashMap;

public class TwentyFour {
    
    private int[] aArray = new int[2];
    private int[] bArray = new int[2];
    private int[] cArray = new int[2];
    private int[] dArray = new int[2];
    
    /**
     * main方法
     * 
     * @param args
     */
    public static void main(String[] args) {
        new TwentyFour().dispose(3, 3, 8, 8);
    }
    

    public void dispose(int a, int b, int c, int d){
        aArray[0] = a;
        aArray[1] = 1;
        bArray[0] = b;
        bArray[1] = 1;
        cArray[0] = c;
        cArray[1] = 1;
        dArray[0] = d;
        dArray[1] = 1;
        core(aArray, bArray, cArray, dArray);
    }
    
    /**
     * 加
     */
    public  int[] plus(int[] a, int[] b){
        
        if(0 == a[1]){
            return new int[]{0,0};
        }
        if(0 == b[1]){
            return new int[]{0,0};
        }
        int denominator = leaseCommonMultiple(a[1],b[1]);
        
        return new int[]{denominator/a[1]*a[0] + denominator/b[1]*b[0] ,denominator};
    }
    
    /**
     * 减
     * @param a
     * @param b
     * @return
     */
    public  int[] reduce(int[] a, int[] b){
        if(0 == a[1]){
            return new int[]{0,0};
        }
        if(0 == b[1]){
            return new int[]{0,0};
        }
        int denominator = leaseCommonMultiple(a[1],b[1]);
        
        return new int[]{denominator/a[1]*a[0] - denominator/b[1]*b[0] ,denominator};
    }
    
    /**
     * 乘
     * @param a
     * @param b
     * @return
     */
    public  int[] multiply(int[] a, int[] b){
        return new int[]{a[0] * b[0], a[1] * b[1]};
    }
    
    /**
     * 除
     * @param a
     * @param b
     * @return
     */
    public  int[] divide(int[] a, int[] b){
        return new int[]{a[0] * b[1], a[1] * b[0]};
    }
    
    /**
     * 求最小公倍数
     * @param a
     * @param b
     * @return
     */
    public  int leaseCommonMultiple(int a, int b){
        return a*b/greatestCommonDivisor(a,b);
    }
    
    /**
     * 求最大公约数
     * @param a
     * @param b
     * @return
     */
    public  int greatestCommonDivisor(int a, int b) {
        if(0 == a && 0 == b){
            return 1;
        }
        if (0 == a) {
            return b;
        }
        if (0 == b) {
            return a;
        }
        if (a > b) {
            int c = a;
            a = b;
            b = c;
        }
        for (int c = a % b; c > 0; c = a % b) {
            a = b;
            b = c;
        }
        return b;
    }
    
    /**
     * 动态加载符号数
     * @param i
     * @param a
     * @param b
     * @return
     */
    public  int[] dispose(int i, int a[], int[] b){
        if(i == 0){
            return plus(a, b);
        }else if(i == 1){
            return reduce(a, b);
        }else if(i == 2){
            return multiply(a, b);
        }else{
            return divide(a, b);
        }
    }
    
    /**
     * 动态加载计算数
     * @param i
     * @param a
     * @param b
     * @param c
     * @param d
     * @return
     */
    public int[] number(int i, int[] a, int[] b, int[] c, int[] d){
        if(i == 0){
            return a;
        }else if(i == 1){
            return b;
        }else if(i == 2){
            return c;
        }else if(i == 3){
            return d;
        }else{
            return new int[]{0,1};
        }
    }

    /**
     * 核心算法部分
     * @param a
     * @param b
     * @param c
     * @param d
     */
    private  void core(int[] a, int[] b, int[] c, int[] d) {
        HashMap map = new HashMap();
        
        int count = 0;
        
        for(int i = 0; i < 4; i++){
            for(int j = 0; j < 4; j++){
                for(int k = 0; k < 4; k++){
                    for(int m = 0; m < 4; m++){
                        for(int n = 0; n < 4; n++){
                            if(n == m)
                                continue;
                            for(int o = 0; o < 4; o++){
                                if(o == m || o == n)
                                    continue;
                                for(int p = 0; p < 4; p++){
                                    if(p == m || p == n || p == o)
                                        continue;
                                    //类型1:A(A(A(a,b),c),d)
                                    int[] result1 = dispose(k,dispose(j,dispose(i,number(m,a,b,c,d),number(n,a,b,c,d)),number(o,a,b,c,d)),number(p,a,b,c,d));
                                    //类型2:A(A(a,A(b,c)),d)
                                    int[] result2 = dispose(k,dispose(i,number(m,a,b,c,d),dispose(j,number(n,a,b,c,d),number(o,a,b,c,d))),number(p,a,b,c,d));
                                    //类型3:A(a,A(b,A(c,d)))
                                    int[] result3 = dispose(i,number(m,a,b,c,d),dispose(j,number(n,a,b,c,d),dispose(k,number(o,a,b,c,d),number(p,a,b,c,d))));
                                    //类型4:A(a,A(A(b,c),d))
                                    int[] result4 = dispose(i,number(m,a,b,c,d),dispose(k,dispose(j,number(n,a,b,c,d),number(o,a,b,c,d)),number(p,a,b,c,d)));                                    
                                    //类型5:A(A(a,b),A(c,d))
                                    int[] result5 = dispose(j,dispose(i,number(m,a,b,c,d),number(n,a,b,c,d)),dispose(k,number(o,a,b,c,d),number(p,a,b,c,d)));
                                    if (0 != result1[1]) {
                                        if (result1[0] % result1[1] == 0) {
                                            if (result1[0] / result1[1] == 24) {
                                                if ((!map.containsKey(new Integer(i)))|| (!map.containsKey(new Integer(j)))|| (!map.containsKey(new Integer(k)))) {
                                                    map.put(new Integer(i),new Integer(i));
                                                    map.put(new Integer(j),new Integer(j));
                                                    map.put(new Integer(k),new Integer(k));
                                                    count += 1;
                                                    System.out.println("((" + printNumber(m) + printSymbol(i) + printNumber(n) + ")" + printSymbol(j) + printNumber(o) + ")" + printSymbol(k) + printNumber(p));
                                                }
                                            }
                                        }
                                    }
                                    if (0 != result2[1]) {
                                        if (result2[0] % result2[1] == 0) {
                                            if (result2[0] / result2[1] == 24) {
                                                if ((!map.containsKey(new Integer(i)))|| (!map.containsKey(new Integer(j)))|| (!map.containsKey(new Integer(k)))) {
                                                    map.put(new Integer(i),new Integer(i));
                                                    map.put(new Integer(j),new Integer(j));
                                                    map.put(new Integer(k),new Integer(k));
                                                    count += 1;
                                                    System.out.println("(" + printNumber(m) + printSymbol(i) +"(" + printNumber(n) + printSymbol(j) + printNumber(o) + "))" + printSymbol(k) + printNumber(p));
                                                }
                                            }
                                        }
                                    }
                                    if (0 != result3[1]) {
                                        if (result3[0] % result3[1] == 0) {
                                            if (result3[0] / result3[1] == 24) {
                                                if ((!map.containsKey(new Integer(i))) || (!map.containsKey(new Integer(j)))|| (!map.containsKey(new Integer(k)))) {
                                                    map.put(new Integer(i),new Integer(i));
                                                    map.put(new Integer(j),new Integer(j));
                                                    map.put(new Integer(k),new Integer(k));
                                                    count += 1;
                                                    System.out.println(printNumber(m) + printSymbol(i) +"(" + printNumber(n) + printSymbol(j) + "(" + printNumber(o) +  printSymbol(k) + printNumber(p) + "))");
                                                }
                                            }
                                        }
                                    }
                                    if (0 != result4[1]) {
                                        if (result4[0] % result4[1] == 0) {
                                            if (result4[0] / result4[1] == 24) {
                                                if ((!map
                                                        .containsKey(new Integer(i)))|| (!map.containsKey(new Integer(j)))|| (!map.containsKey(new Integer(k)))) {
                                                    map.put(new Integer(i),new Integer(i));
                                                    map.put(new Integer(j),new Integer(j));
                                                    map.put(new Integer(k),new Integer(k));
                                                    count += 1;
                                                    System.out.println(printNumber(m) + printSymbol(i) +"((" + printNumber(n) + printSymbol(j) + printNumber(o) + ")" +  printSymbol(k) + printNumber(p) + ")");
                                                }
                                            }
                                        }
                                    }
                                    if (0 != result5[1]) {
                                        if (result5[0] % result5[1] == 0) {
                                            if (result5[0] / result5[1] == 24) {
                                                if ((!map.containsKey(new Integer(i)))|| (!map.containsKey(new Integer(j)))|| (!map.containsKey(new Integer(k)))) {
                                                    map.put(new Integer(i),new Integer(i));
                                                    map.put(new Integer(j),new Integer(j));
                                                    map.put(new Integer(k),new Integer(k));
                                                    count += 1;
                                                    System.out.println("(" + printNumber(m) + printSymbol(i) + printNumber(n) + ")" + printSymbol(j) + "(" + printNumber(o) + printSymbol(k) + printNumber(p) + ")");
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        //总共几种答案,过滤了类似的答案 
        System.out.println("count: " + count);
    }
    
    public int printNumber(int i){
        if(i == 0){
            return aArray[0];
        }
        if(i == 1){
            return bArray[0];
        }
        if(i == 2){
            return cArray[0];
        }
        if(i == 3){
            return dArray[0];
        }
        return 0;
    }
    
    public String printSymbol(int i){
        
        if(i == 0){
            return " + ";
        }
        if(i == 1){
            return " - ";
        }
        if(i == 2){
            return " * ";
        }
        if(i == 3){
            return " / ";
        }
        return "";
    }
}
复制代码

 

posted on   pony1223  阅读(233)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示