6.1. 问题描述

6174数字黑洞是印度数学家卡普雷卡尔于1949年发现的,又称为卡普雷卡尔黑洞,其规则描述如下。

任意取一个4位的整数(4个数字不能完全相同),把4个数字由大到小排列成一个大的数,又由小到大排列成一个小的数,再把两数相减得到一个差值。之后对这个差值重复前面的变换步骤,经过若干次重复就会得到6174。

例如,对整数8848按规则进行变换操作,其过程如下。

  1. 重排取大数:将8848的4个数字按从大到小排列组成一个最大数8884。
  2. 重排取小数:将8848的4个数字按从小到大排列组成一个最小数4888。
  3. 求取差值:用大数减去小数得到差值3996。
  4. 重复变换:之后对差值继续按上述步骤进行变换。操作的过程为:

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(第一章)--(第六节)数字黑洞的更多相关文章

  1. NHibernate.3.0.Cookbook第一章第六节Handling versioning and concurrency的翻译

    NHibernate.3.0.Cookbook第一章第六节Handling versioning and concurrency的翻译   第一章第二节Mapping a class with XML ...

  2. 路飞学城-Python爬虫集训-第一章

    自学Python的时候看了不少老男孩的视频,一直欠老男孩一个会员,现在99元爬虫集训果断参与. 非常喜欢Alex和武Sir的课,技术能力超强,当然讲着讲着就开起车来也说明他俩开车的技术也超级强! 以上 ...

  3. Python开发【第一章】:Python简介和入门

    Python简介 Python的创始人为Guido van Rossum.1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本解释程序,做为ABC 语言的一种继承. ...

  4. python全栈第一章

    第一章 Python基础变量定义规则:1.变量名只能是字母数字或者下划线的任意组合2.变量名的第一个字符不能是数字3.关键字不能申明为变量名定义方式:1.驼峰体AgeOfSzp2.下划线隔开Age_o ...

  5. 《零压力学Python》 之 第一章知识点归纳

    第一章(初识Python)知识点归纳 Python是从ABC语言衍生而来的 ABC语言是Guido参与设计的一种教学语言,为非专业编程人员所开发的. Python是荷兰程序员 Guido Van Ro ...

  6. Python开发【第一章】:简介和入门

    Python简介 Python的创始人为Guido van Rossum.1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本解释程序,做为ABC 语言的一种继承. ...

  7. 数据结构与算法 Python语言实现 第一章练习

    说明:部分代码参考了Harrytsz的文章:https://blog.csdn.net/Harrytsz/article/details/86645857 巩固 R-1.1 编写一个Python函数 ...

  8. 通过游戏学python 3.6 第一季 第六章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改 可复制直接使用 娱乐 可封装 函数

    #猜数字--核心代码--猜测次数--随机函数和屏蔽错误代码---优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改 #猜数字--核心代码--猜测次数--随机函数和屏蔽错误代码---优 ...

  9. 路飞学城Python爬虫课第一章笔记

    前言 原创文章,转载引用务必注明链接.水平有限,如有疏漏,欢迎指正. 之前看阮一峰的博客文章,介绍到路飞学城爬虫课程限免,看了眼内容还不错,就兴冲冲报了名,99块钱满足以下条件会返还并送书送视频. 缴 ...

  10. 通过游戏学python 3.6 第一季 第一章 实例项目 猜数字游戏--核心代码 可复制直接使用 娱乐 可封装 函数

    本文实例讲述了python实现的简单猜数字游戏.分享给大家供大家参考.具体如下: 给定一个1-99之间的数,让用户猜数字,当用户猜错时会提示用户猜的数字是过大还是过小,知道用户猜对数字为止,猜对数字用 ...

随机推荐

  1. VS2019编译Opencv4.6.0GPU版本(支持40系显卡)

    1 准备工具 CMake CUDA Toolkit + CUDNN VIstual Studio 2019 OpenCV + OpenCV_contrib 点击上面链接跳转,我使用的是CMake3.2 ...

  2. xhs全参xs,xt,xscommon逆向分析

    声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 目标网站 aHR0cHM6 ...

  3. 使用nvm安装以及管理多版本node教程

    安装nvm.node.npm 下载nvm安装包,推荐使用1.1.7,我个人使用1.1.8会有中文乱码的报错 点击exe文件,注意修改nvm的安装根目录以及node的安装根目录,后者是以后管理多版本no ...

  4. redis数据类型篇

    redis数据类型官网资料,https://redis.io/docs/manual/data-types/ 生产环境下的redis实况图 超哥这个redis实例里,db0库有140万个key. 1. ...

  5. mysql中常用的三种插入数据的语句

    mysql中常用的三种插入数据的语句: insert into表示插入数据,数据库会检查主键(PrimaryKey),如果出现重复会报错: replace into表示插入替换数据,需求表中有Prim ...

  6. Next.js 13 如何使用loading.js

    要在next.js 13中使用loading.js,我们需要先在对应的文件目录下创建loading.js文件 文件结构如下: app test1 loading.tsx page.tsx 如上面的目录 ...

  7. 燕千云 YQCloud 数智化业务服务管理平台发布1.11版本

    2022年3月25日,燕千云 YQCloud 数智化业务服务管理平台发布1.11版本.新增客户服务管理模块.优化IT服务管理功能.增强燕千云与其他平台的集成能力.支持更多的业务服务场景.全面提升企业数 ...

  8. 高德解析城市的分析,根据高德的经纬度获取城市cityCode

    高德解析城市的分析,根据高德的经纬度获取城市cityCode http://restapi.amap.com/v3/geocode/regeo?output=json&location=110 ...

  9. 【已结束】阿珏Blog三周年特别纪念活动

    Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` [已结束]阿珏Blog三周年特别纪念活动 日期:2019- ...

  10. 苹果应用商店上传应用卡在了“Authenticating with the iTunes Store”

    在终端中依次运行下面代码 cd ~ mv .itmstransporter/ .old_itmstransporter/ "/Applications/Xcode.app/Contents/ ...