记第一次 Linux Shell 编程:Android 数鸡蛋

亲人微信群中,家父抛出了这样一个问题:

一筐鸡蛋:
1个1个拿正好拿完,
2个2个拿还剩1个,
3个3个拿正好拿完,
4个4个拿还剩1个,
5个5个拿还剩4个,
6个6个拿还剩3个,

7个7个拿还剩5个,
8个8个拿还剩1个,
9个9个拿正好拿完。

问筐里有多少鸡蛋。

看到后我立马想到,2个2个拿剩1个,转换成数学语言,不就是除以2余1么?同样地,鸡蛋数除以3余0,除以4余1……除以1余0肯定没意思。值得注意的是,鸡蛋数能整除9,说明是9的倍数。既然是9的倍数了,肯定能整除3了,于是又可以划去一个“没意思”的条件。那么现在设筐里鸡蛋数为 n,定义取余运算为 %,用数学语言整理一下题设条件:

  • n % 2 = 1
  • n % 4 = 1
  • n % 5 = 4
  • n % 6 = 3
  • n % 7 = 5
  • n % 8 = 1

根据小学学过的除法性质,又可整理为

  • (n - 1) % 2 = 0
  • (n - 1) % 4 = 0
  • (n - 4) % 5 = 0
  • (n - 3) % 6 = 0
  • (n - 5) % 7 = 0
  • (n - 1) % 8 = 0

呃,这是后面计算时才想到的。这会儿我发现的是,n 必须以9结尾。因为要想 n % 5 = 4 成立,n 必须以4或9结尾,而以4结尾的情况不会满足 n % 2 = 1,所以 n 只能以9结尾。结合其他条件,检验通过。

综上所述,n 必定是以9结尾的9的倍数。

于是我开始用 n = 9,99,189 等数代入检验,也就是 9×1,9×11,9×21 等数。当算完 n = 369 时,发现它符合题意!但我感觉到,应该还有别的解,这只是最小解。于是我又使 n = 549,639,729,却有些力不从心了。我必须正视心中几番涌起的念头:这样重复繁杂的过程要交给计算机程序去做!顺便给家人亲戚展示一下我的能力。

我首先想到的工具是 Visual Basic,然后是 aardio,但由于晚自习又开始了,不好使用电脑。怎么办?难道用手机吗?对,就用手机!那怎么编程呢?刚巧不久前装了“终端模拟器”(Android Terminal Emulator)(没有装 PHP 环境哟),也有几行可以执行的代码,觉得可以利用!我知道,Android 核心基本上就是 Linux。在 Android 终端模拟器中使用的的命令跟管理 Linux VPS 时使用的基本相似(何况我还装有 BusyBox)。但对于编程我还是不熟悉。虽然有一本《Linux 从入门到精通》(清华大学出版社),我却只看到大约一半,还没有到编程一块来——但我当时忘了有这本书了,就去求助于搜索引擎了。

鉴于我摘录的那几行代码(见于这儿已经有循环结构了,我只需了解一下算术运算符就差不多了,于是我搜“ssh 编程 数学”,才发现自己蠢掉了。我机智地将“ssh”改成“shell”,搜到了《Shell脚本编程中常用的数学运算实例》,里面的“判断奇偶数”对我最重要,还包括有条件(判断)结构哩:

#!/bin/bash
echo "Enter The Number"
read n
num=$(expr $n % 2)
if [ $num -eq 0 ]
then
echo "is a Even Number"
else
echo "is a Odd Number"
fi

然后我打开 DroidEdit Free,开始写自己的程序了。过程并不顺利,我屡次感受到其代码风格的诡异,不,是迥异。

而在第一个版本写好后,保存在内置 SD 卡(在我的 MIUI 中也就是内部存储空间)根目录。尝试在终端模拟器运行时,被拒绝了!看到“can't execute: Permission denied”的提示,我以为需要 Root 身份,就 su 了一下,问题依旧。设置这个 .sh 为 755 甚至 777 权限,也没解决问题。网上说要修改所在目录的权限,我就干脆将脚本文件扔到 /system/xbin/ 了。

最终脚本执行完好,代码如下:

 a=1
 n=9
 while true
 do
    si=$(expr $(expr $n - 1) % 4)
    wu=$(expr $(expr $n - 4) % 5)
    liu=$(expr $(expr $n - 3) % 6)
    qi=$(expr $(expr $n - 5) % 7)
    ba=$(expr $(expr $n - 1) % 8)
    sum=$(expr $si + $wu + $liu + $qi + $ba)
    if [ $sum -eq 0 ]
    then
        echo "$n is."
    #else
        #echo "$n isn't."
    fi
    sleep .01
    a=$(expr $a + 10)
    n=$(expr 9 \* $a)
 done

执行结果(部分):

u0_a404@dior:/ $ szhaojie.sh
369 is.
2889 is.
5409 is.
7929 is.
10449 is.
12969 is.
15489 is.
18009 is.
20529 is.
23049 is.
25569 is.
28089 is.
30609 is.
33129 is.
35649 is.
38169 is.
40689 is.
43209 is.
45729 is.
48249 is.
50769 is.
53289 is.
55809 is.
58329 is.
60849 is.
63369 is.
65889 is.
68409 is.
70929 is.
73449 is.
75969 is.
78489 is.
81009 is.
83529 is.
86049 is.
88569 is.
91089 is.
93609 is.
96129 is.
98649 is.
101169 is.
103689 is.

100 000 以内的 n 的解都列出来了,我想一筐鸡蛋不会超过这个数了。家父十分同意我的看法,并对我的能力表示了赞赏;当我要他算一两个看对不对时,他爽朗地回复——

不算了。

2016-1-20 P.S.纠正 n 为9的倍数就会满足 n % 2 = 1 的错误。
2016-2-2 P.S.这类问题有更高级更直接的解法,参考中国剩余定理(孙子定理)。

若无特别说明,本文系原创,遵循 署名-非商业性使用 3.0 (CC BY-NC 3.0) 协议,转载文章请注明来自【闪星空间】,或链接上原文地址:http://shansing.com/read/429/

发表评论»

NO SPAMS! 不要发垃圾评论哦!

表情