欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MATLAB实践 - 让计算机去玩24点

程序员文章站 2024-03-24 22:57:04
...

这篇文章是从我的订阅号从copy来的。欢迎关注哈:学术学习小助手。刚开始玩订阅号,请多指教

  • 概述

可能很多人小时候都玩过24点这个游戏,游戏的规则是从纸牌(除去小丑派)中抽四张,每张派只能用一次,通过+、-、x、÷最终得到24的值。

最近想到了这个问题,出现了灵感,决定把它记录下来。

 

  • 原理

首先是24点的计算过程,取两张牌,计算,得到一个数,接着重复两次。最终得到一个数。。。

如果用球形表示数,用方形表示运算符,那么我们可以这样表示:

MATLAB实践 - 让计算机去玩24点

每次取两个球,一个方块,计算得到一个新的球,并放到回这个新的球。

MATLAB实践 - 让计算机去玩24点

MATLAB实践 - 让计算机去玩24点

重复这个操作三次,就能够将四个球消去成一个球:

MATLAB实践 - 让计算机去玩24点

MATLAB实践 - 让计算机去玩24点

MATLAB实践 - 让计算机去玩24点

此时,只需要判断最终剩下的球是不是等于24呢?如果答案是肯定的,那么这个过程就是求解24点的过程MATLAB实践 - 让计算机去玩24点。如果答案是否定的,则需要进行循环MATLAB实践 - 让计算机去玩24点,包括运算符和两个球的的选择,需要注意,两个球的顺序是有影响的(也就是说可以把球认为是排列)。这样循环下去,最终如果所有情况全部遍历完还没有解,这时就说明真的没有解了MATLAB实践 - 让计算机去玩24点

MATLAB实践 - 让计算机去玩24点

这个时候我们需要估计一下,这个循环次数有多少,如果最大的循环次数过大,就不能直接解出来。这个问题不就类似于高中的排列组合问题嘛MATLAB实践 - 让计算机去玩24点

 

所有的可能性N为:

MATLAB实践 - 让计算机去玩24点

最多循环9216次就能够得到24点。

 

分析到这我认为这个问题就可以交给计算机了。

这时用任何编程语言都能够实现上述的方法(当然,如果逻辑有问题也请各位批评指正)

 

  • 实现

我选择使用MATLAB的函数来实现上述的方法。

逻辑和原理是一致的,只不过增加了一些判断防止运算出错,再次特别说明一下。

  1. 输入必须为正整数,如果不是,那么会报错。

  2. 运算过程中取出的数也都应当是非零的,如果不是,则会跳过当前循环。

  3. 如果遍历完还没有出现解,那么说明无解;当最终的数与24点差距在0.01以内认为已经求出解(由于运算过程中可能出现小数,因此需要容错区间)。

下面分享我的代码:

function point_24(a,b,c,d)
if a<=0||b<=0||c<=0||d<=0
    error('输入应为正整数')
end
xulie=[a b c d];
fuhao=['+-*/'];
temp_0=xulie;
log=[];
​
for i=1:4
    %读取第1步序列,选择第1个数
    temp_1_1=temp_0;
    num_1=temp_1_1(i);    
    temp_1_1(i)=[];
    for j=1:3
        %选择第2个数
        temp_1_2=temp_1_1;
        num_2=temp_1_2(j);
        temp_1_2(j)=[];
        for k=1:4
            %选择第1次运算,并结果保存到temp_1_C。
            if num_1<=0||num_2<=0
                continue
            end
            temp_cacu=[num2str(num_1),fuhao(k),num2str(num_2)];
            log={log;temp_cacu};
            temp_1_C=[temp_1_2,eval(temp_cacu)];
            for l=1:3
                %读取第2步序列,选择第三个数
                temp_2_1=temp_1_C;
                num_3=temp_2_1(l);
                temp_2_1(l)=[];
                for m=1:2
                    %选择第四个数
                    temp_2_2=temp_2_1;
                    num_4=temp_2_2(m);
                    temp_2_2(m)=[];
                    for n=1:4
                        %选择第二次运算,并结果保存到temp_2_C。
                        if num_3<=0||num_4<=0
                            continue
                        end
                        temp_cacu=[num2str(num_3),fuhao(n),num2str(num_4)];
                        log={log;temp_cacu};
                        temp_2_C=[temp_2_2,eval(temp_cacu)];
                        for o=1:2
                            %读取第3步序列,选择第五个数
                            temp_3_1=temp_2_C;
                            num_5=temp_3_1(o);
                            temp_3_1(o)=[];
                            %选择第六个数
                            temp_3_2=temp_3_1;
                            num_6=temp_3_2;
                            temp_3_2=[];
                            for p=1:4
                                %选择第三次运算,并结果保存到temp_3_1。
                                if num_5<=0||num_6<=0
                                    continue
                                end
                                temp_cacu=[num2str(num_5),fuhao(p),num2str(num_6)];
                                log={log;temp_cacu};
                                temp_3_C=[temp_3_2,eval(temp_cacu)];
                                
                                temp_4=temp_3_C;
                                if abs(temp_4-24)<=1e-3
                                    temp_a=[num2str(num_1),fuhao(k),num2str(num_2)];
                                    temp_b=[num2str(num_3),fuhao(n),num2str(num_4)];
                                    temp_c=[num2str(num_5),fuhao(p),num2str(num_6)];
                                    
                                    disp([temp_a,'=',num2str(eval(temp_a))]);
                                    disp([temp_b,'=',num2str(eval(temp_b))]);
                                    disp([temp_c,'=',num2str(eval(temp_c))]);
                                    return 
                                end
                            end
                        end
                    end
                end
            end
        end
    end
end
disp('算不出来')
end

这段代码保存为'point_24.m' 放置在MATLAB的工作文件夹就行了。

 

  • 测试

  • 大家可以按照下面的代码进行测试:

  • A=[4,7,2,12;9,11,5,3;9,3,4,10;8,6,7,7;13,5,8,6;1,9,5,12];
    for e=1:6
      a=A(e,1);
      b=A(e,2);
      c=A(e,3);
      d=A(e,4);
      point_24(a,b,c,d);
      disp(['↑第',num2str(e),'个答案'])
    end

    测试的结果如下:

MATLAB实践 - 让计算机去玩24点

 

转载请注明出处

相关标签: MATLAB 数学