对比python学julia(第一章)--(第六节)数字黑洞
6.1. 问题描述
6174数字黑洞是印度数学家卡普雷卡尔于1949年发现的,又称为卡普雷卡尔黑洞,其规则描述如下。
任意取一个4位的整数(4个数字不能完全相同),把4个数字由大到小排列成一个大的数,又由小到大排列成一个小的数,再把两数相减得到一个差值。之后对这个差值重复前面的变换步骤,经过若干次重复就会得到6174。
例如,对整数8848按规则进行变换操作,其过程如下。
- 重排取大数:将8848的4个数字按从大到小排列组成一个最大数8884。
- 重排取小数:将8848的4个数字按从小到大排列组成一个最小数4888。
- 求取差值:用大数减去小数得到差值3996。
- 重复变换:之后对差值继续按上述步骤进行变换。操作的过程为:
9963-3699=6264
6642-2466=4176
7641-1467=6174。
经过4次变换之后,就将自然数8848变换为6174这个黑洞数字,并且继续变换也会一直是6174。
请编写一个程序,验证卡普雷卡尔黑洞。
6.2. 算法分析
在程序设计中,当解决复杂问题时,通常采用“自顶向下,逐步求精”的模块化设计思想,将一个复杂的任务逐层分解为若干个功能单一的子任务,如果某个子任务仍然复杂,还可以继续分解为更小的子任务,直到每个子任务简单明了。简单地说就是,化整为零,各个击破。
面对编程验证卡普雷卡尔黑洞这个任务,根据其规则描述,可分解为输入数字、检测数字合法性、黑洞变换3个子任务。其中,黑洞变换这个子任务稍显复杂,又可以划分出分解数字、取大数、取小数这3个较小的子任务。分解后的各个子任务呈现为一个树状结构,可以使用功能结构图来表示,如图14-1所示。
经过分解,各个子任务已经足够简单。每个子任务称为一个功能模块,能够单独进行设计、编码和测试。各功能模块的实现步骤描述如下。

在上图中,主程序之下有三个模块,主程序先调用输入数字模块接收用户通过键盘输入的一个整数,再调用检测数字模块检测这个整数是否合法。如果检测通过,调用黑洞变换模块进行数字变换操作;否则,提示“输入的整数不合法”,并结束程序。
主程序模块流程图如下:

至于其他子模块的流程图,这里不再给出,有兴趣的童鞋可以去原书《Python趣味编程:从入门到人工智能》查看。
6.3. 编程解题
在上述算法分析中,采用“自顶向下,逐步求精”的模块化设计思想,将验证数字黑洞的任务分解为多个小的功能模块,每个模块功能单一,易于编程实现。我们来看看python程序怎么实现:
1 '''
2 程序:卡普雷卡尔黑洞,6174数字黑洞
3 作者:苏秦@小海豚科学馆公众号
4 来源:图书《Python趣味编程:从入门到人工智能》
5 '''
6 #主程序
7 def main():
8 n = input('请输入4位数字不完全相同的整数:')
9 if check(n):
10 blackhole(n)
11 else:
12 print('输入的整数不合法')
13
14 #检测数字
15 def check(n):
16 if not n.isnumeric():
17 return False
18 elif len(n) != 4:
19 return False
20 elif n == n[0] * 4:
21 return False
22 else:
23 return True
24
25 #黑洞变换
26 def blackhole(n):
27 print('变换过程:')
28 while n != '6174':
29 a = list(n)
30 b = max_number(a)
31 c = min_number(a)
32 n = str(b - c)
33 print('%s - %s = %s' % (b, c, n))
34 print('变换结束!')
35
36 #取大数
37 def max_number(a):
38 a.sort(reverse=True)
39 num = int(''.join(a))
40 return num
41
42 #取小数
43 def min_number(a):
44 a.sort()
45 num = int(''.join(a))
46 return num
47
48 #程序入口
49 if __name__ == '__main__':
50 main()
从上面的代码可以看出,“检测数字”等模块被定义成了独立的代码块,这就是python的自定义函数,通常它是这个样子的:

其中如果不需要参数,函数名后面的括号可以留空,多个参数用逗号(,)隔开。
现在我们把上面的python代码转换成julia代码:
1 #=
2 程序:卡普雷卡尔黑洞,6174数字黑洞
3 作者:苏秦@小海豚科学馆公众号
4 来源:图书《Python趣味编程:从入门到人工智能》
5 =#
6 "主程序"
7 function main()
8 n = input("请输入4位数字不完全相同的整数:")
9 if check(n)
10 blackhole(n)
11 else
12 print("输入的整数不合法")
13 end
14 end
15
16 #检测数字
17 function check(n)
18 #=
19 julia中没有判断字符串是否为数字的内置函数
20 只能用这种方式实现了。(isnumeric,isdigit
21 函数的参数都是字符不是字符串)
22 =#
23 if tryparse(Int, n)===nothing
24 return false
25 elseif length(n) != 4
26 return false
27 elseif n == repeat(n[1],4)
28 return false
29 else
30 return true
31 end
32 end
33
34 #黑洞变换
35 function blackhole(n)
36 println("变换过程:")
37 while n != "6174"
38 a = split(n,"")
39 b = max_number(a)
40 c = min_number(a)
41 n = string(b - c)
42 #julia的参数字符串比python简洁些
43 println("$b - $c = $n")
44 end
45 print("变换结束!")
46 end
47
48 #取大数
49 function max_number(a)
50 a=sort(a,rev=true)
51 #将数组元素组合成字符串
52 num=parse.(Int,join(a,""))
53 return num
54 end
55
56 #取小数
57 function min_number(a)
58 a=sort(a)
59 num=parse.(Int,join(a,""))
60 return num
61 end
62
63 """
64 #这是重写的实现类似Python的input函数
65 参数:string类型,默认值为空
66 返回值:string类型
67 """
68 function input(prompt::String="")::String
69 print(prompt)
70 return chomp(readline())
71 end
72 main()
从上面的代码中我们可以看出,julia的自定义函数的格式是这样的:

同样的,如果不需要参数,函数名后面的括号可以留空,多个参数用逗号(,)隔开。另外参数可以定义类型和默认值,函数可以定义返回值类型等。例如:
function input(prompt::String="")::String
另外,大家可能发现上面的python和julia代码中都有一个main函数,而且python还有“if __name__ == '__main__':”这种写法。事实上,与C、C++、java等静态语言强制使用main函数作为程序入口函数不同的是,python其实是没有main函数的,这里使用main函数作为程序的起始,只是一种结构化编程的方式,同理,julia也一样。当然,python中“if __name__ == '__main__':”使得名称为main的函数体中的代码语句,只能在当前文件被单独运行的时候被执行,如果当前python文件被作为外部模块引用的时候,main还是中的代码语句不会被执行,所以,通常会把一些测试类的代码写在main函数里面。当然,作为工程化开发时,不建议这样做,测试代码应该写到单独的文件中去。
这里有必要说一下julia的代码注释,Julia自v0.4版本之后,便提供了内置的文档注释系统,可以很方便地对函数、类型、对象及语句进行描述,直接支持Markdown格式[[1]],能够生成非常实用、方便的说明文档。
最简单的注释是一句话就可说清楚的单行注释方式,以井号#作为注释内容的前缀,一般放于语句的上一行或当前行尾部。请参考上面的代码,此处不再赘述。
对于多行注释,一般在注释内容的上下行使用#=与=#两个标记符进行界定,请参考上面代码的开头的程序、作者声明。
另外,类型声明、函数与宏定义等上一行中单独出现的字符串对象都会被认为是注释内容,上面main函数的注释就是这样的。当然,多行字符串也是支持的,而且遵循Markdown语法格式。请参看上面input函数的注释。
对比python学julia(第一章)--(第六节)数字黑洞的更多相关文章
- NHibernate.3.0.Cookbook第一章第六节Handling versioning and concurrency的翻译
NHibernate.3.0.Cookbook第一章第六节Handling versioning and concurrency的翻译 第一章第二节Mapping a class with XML ...
- 路飞学城-Python爬虫集训-第一章
自学Python的时候看了不少老男孩的视频,一直欠老男孩一个会员,现在99元爬虫集训果断参与. 非常喜欢Alex和武Sir的课,技术能力超强,当然讲着讲着就开起车来也说明他俩开车的技术也超级强! 以上 ...
- Python开发【第一章】:Python简介和入门
Python简介 Python的创始人为Guido van Rossum.1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本解释程序,做为ABC 语言的一种继承. ...
- python全栈第一章
第一章 Python基础变量定义规则:1.变量名只能是字母数字或者下划线的任意组合2.变量名的第一个字符不能是数字3.关键字不能申明为变量名定义方式:1.驼峰体AgeOfSzp2.下划线隔开Age_o ...
- 《零压力学Python》 之 第一章知识点归纳
第一章(初识Python)知识点归纳 Python是从ABC语言衍生而来的 ABC语言是Guido参与设计的一种教学语言,为非专业编程人员所开发的. Python是荷兰程序员 Guido Van Ro ...
- Python开发【第一章】:简介和入门
Python简介 Python的创始人为Guido van Rossum.1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本解释程序,做为ABC 语言的一种继承. ...
- 数据结构与算法 Python语言实现 第一章练习
说明:部分代码参考了Harrytsz的文章:https://blog.csdn.net/Harrytsz/article/details/86645857 巩固 R-1.1 编写一个Python函数 ...
- 通过游戏学python 3.6 第一季 第六章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改 可复制直接使用 娱乐 可封装 函数
#猜数字--核心代码--猜测次数--随机函数和屏蔽错误代码---优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改 #猜数字--核心代码--猜测次数--随机函数和屏蔽错误代码---优 ...
- 路飞学城Python爬虫课第一章笔记
前言 原创文章,转载引用务必注明链接.水平有限,如有疏漏,欢迎指正. 之前看阮一峰的博客文章,介绍到路飞学城爬虫课程限免,看了眼内容还不错,就兴冲冲报了名,99块钱满足以下条件会返还并送书送视频. 缴 ...
- 通过游戏学python 3.6 第一季 第一章 实例项目 猜数字游戏--核心代码 可复制直接使用 娱乐 可封装 函数
本文实例讲述了python实现的简单猜数字游戏.分享给大家供大家参考.具体如下: 给定一个1-99之间的数,让用户猜数字,当用户猜错时会提示用户猜的数字是过大还是过小,知道用户猜对数字为止,猜对数字用 ...
随机推荐
- this,构造器,static,final,单例模式
this关键字 在java中this是一个引用变量,即指向当前对象地址的引用(指针),→可以把this当作当前对象,便于更好的索引. this() 实际是调用了当前对象的构造器 1. 引用当前对象的属 ...
- 8.11考试总结(NOIP模拟36)[Dove 打扑克·Cicada 与排序·Cicada 拿衣服]
我会化作人间的风雨陪在你的身边 T1 Dove 打扑克 解题思路 考场上是想了一个树状数组维护的打法,但是竟然和 \(qn^2\) 的算法一样是 65pts 暴力就是对于每一次 2 询问重新建一下树状 ...
- 基本定时器TIM6实现精确延时
1.基本定时器的特点 (1).16位自动重装载累加计数器 (2).16位可编程(可实时修改)预分频器,用于对输入的时钟按系数为1-65536之间的任意数值 !!!注意基本定时器只有向上计数模式,不要被 ...
- 算法金 | 你真的完全理解 Logistic 回归算法了吗
大侠幸会,在下全网同名「算法金」 0 基础转 AI 上岸,多个算法赛 Top 「日更万日,让更多人享受智能乐趣」 今日 178/10000 1. 引言 吴恩达:机器学习的六个核心算法!, 通透!!十大 ...
- Cygwin安装及简单说明
1 简介 官方说明:Cygwin is a Linux-like environment for Windows. It consists of a DLL (cygwin1.dll), which ...
- 《利用python进行数据分析》笔记章节索引
本文章作为我的一系列关于<利用python进行数据分析>的笔记的文章的索引.分为四部分. 第一部分:numpy基础,共六节: numpy基础--ndarray(一种多维数组对象):http ...
- 01-布局扩展-用calc来计算实现双飞翼布局
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...
- IceRPC之依赖注入>快乐的RPC
作者引言 很高兴啊,我们来到了IceRPC之依赖注入>快乐的RPC,基础引导,打好基础,才能让自已不在迷茫,快乐的畅游世界. 依赖注入和IceRPC 了解 IceRPC (C#) 如何为依赖注入 ...
- ETL工具-nifi干货系列 第九讲 处理器EvaluateJsonPath,根据JsonPath提取字段
1.其实这一节课本来按照计划一起学习RouteOnAttribute处理器(相当于java中的ifelse,switch case 控制语句),但是在学习的过程中遇到了一些问题.RouteOnAttr ...
- pytest系列之-mark功能的使用
功能使用: 标记用例,按正常.异常用例划分等级进行标记,或者按照模块进行划分. 标记后,可以执行部分用例. 例如: 你有以下用例,文件目录结构如下: testcase ----user ----man ...