Arduino的24分计算器

儿子小学三年级,经常要做24分计算,于是动手用Arduino nano 做了一个24分计算器,把开发过程记录下来,备忘。

准备物料:我的抽屉里就有现货,都是以前淘宝上卖的:

就三个东西,十分简单。

 

开始设计了,因为Arduino开发用的是C语言,所以网上找了一个计算24分的C语言源代码,比较简单,稍微看了一下,使用穷举法把4个数字、加减乘除运算符交换位置计算一番,等于24分就返回。网上代码有些小错,稍微修改了一下编译、测试都通过了,代码在Centos6.5下测试通过:

  https://yunpan.cn/cSEdbXVcsshr2 访问密码 0125

 

然而在百度的时候,发现了一个计算24分的网站:http://www.4shu.net/

里面列出了1~13(K)计算24分的全部1362个题目,列出了每个题目的全部独立解法。找到这个以后,我想可以把这些信息都存在Arduino里,然后通过题目就可以查找的该题目的24分解法,虽然这个方法比上面的穷举法计算更复杂,我却对这个方法很感兴趣,尝试实现它。

 

思路:做一个题目结构数组,一个解法字符串。

题目结构数组按题目小到大的顺序排列。

题目结构 

struct tm {
  unsigned char tm[2];  // 题目4个数字,1个字节放2个数字
  unsigned int offset;  // 一个24分题目解法中的偏移位置 (半个字节长度1)  
  unsigned char cd;    // 一个24分题目解法的长度(半个字节长度1)
} ;

题目因为是顺序排列的,所以可以通过折中查找法来快速查找。

 

全部1362个题目的所有解法,我保存到一个文本文件里,我发现它有33,450个字节,而Arduino的程序空间只有30,720 字节,就是不写程序,都给它存,也存不下这些解法的信息,还不包括题目的信息呢!

经过分析:解法的文件的字符就只有17个(所有回车的0x0D0x0A都删除):“0 - 9”,“+”,“-”,“*”,“/”,“,”,“(”,“)”
一个字节8位二进制数据,原来只放1个字符,如果放2个字符,就可以压缩一半。
然而半个字节4位二进制数,只有16种编码,解法的字符一共有17个,怎么办呢?

“,”是一个24分题目的不同解法的分隔符,也是不能省的。统计发现运算符中的“/”相对较少,而且一个计算式里不可能同时出现2个“/”,所有就用2个除号“//”表示“,”

最后编码如下(半个字节):
“0” :0x0H
“1” :0x1H
“2” :0x2H
“3” :0x3H
“4” :0x4H
“5” :0x5H
“6” :0x6H
“7” :0x7H
“8” :0x8H
“9” :0x9H
“(” :0xAH
“)” :0xBH
“+” :0xCH
“-” :0xDH
“*” :0xEH
“/” :0xFH
连续的2个“/”表示“,”,用来分隔一个24分题目的不同解法。

这些压缩了查不到一半空间,可以放下了,题目信息本来用一个结构表示(5个字节):
struct tm {
  unsigned char tm[2];  // 题目4个数字,1个字节放2个数字
  unsigned int offset;  // 一个24分题目解法中的偏移位置 (半个字节长度1)  
  unsigned char cd;    // 一个24分题目解法的长度(半个字节长度1)
} ;

然而,1362个题目需要1362个这样的结构一共需要6810个字节,加上前面的解法信息,和本身程序代码
编译发现超出了Arduino nano的30,720 字节的程序存储空间。
Arduino nano的单片机是ATMEGA 328芯片,是哈佛结构的,程序空间和数据空间是分离的,
程序空间32KByte,数据空间2KByte。
把题目的6810个字节放在数据空间里也太大,而且题目的的4个数字已经压缩放到2个字节了。

经过考虑,发现题目结构中的unsigned int offset;可以省略,用牺牲速度来换空间!
列如:我要第100题在解法字符串里的偏移,就它之前99题的解法长度加起来,不就是第100题的偏移位置。
所以题目信息的结构表示(3个字节)::
struct tm {
  unsigned char tm[2];  // 题目4个数字,1个字节放2个数字
  unsigned char cd;    // 一个24分题目解法的长度(半个字节长度1)
} ;

这样编译一下发现可以装入到Arduino nano的30,720 字节的程序存储空间里。
好在显示用的是串口屏,使用代码十分简单,花不了多少程序存储空间。

最后写好了所有代码,一共用了29,866 bytes (已经使用了程序空间的97%!)

 

 

 

 





 

如果不能计算出24分,显示:

 

源代码下载:https://download.csdn.net/download/sheik888/12893877
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值