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. C#笔记 窗体练习:海康相机SDK二次开发

    第一次写窗体应用程序,太闲了,给自己找点事情做... 1. 最基本的打开关闭 代码:https://gitee.com/yurj0403/hik-camera 强行练习一下用git 2. 加了状态栏 ...

  2. NaN数值类型

    <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8 ...

  3. vue devtools工具安装 Vue实现数据绑定的原理

    通过chrome中的谷歌插件商店安装Vue Devtools工具,此工具帮助我们进行vue数据调试所用,一定要安装. https://chrome.google.com/webstore?utm_so ...

  4. work11

    1,简述String类中的equals方法与Object类中的equals方法的不同点. /* Object 类 1,它是所有类的一个根类 2,其他类默认继承Object类 常用方法: 1,toStr ...

  5. Mysql中innodb的B+tree能存储多少数据?

    引言 InnoDB一棵3层B+树可以存放多少行数据?这个问题的简单回答是:约2千万.为什么是这么多呢?因为这是可以算出来的,要搞清楚这个问题,我们先从InnoDB索引数据结构.数据组织方式说起. 在计 ...

  6. Css var 简述

    Css var 语法 var(custom-property-name, value) - custom-property-name 必须 变量必须以 --开头 后面可以是英文.数字连接符,区分大小写 ...

  7. Java编码规范-字符串与Integer的比较,BigDecimal非空参数

    Java编码规范-字符串与Integer的比较,BigDecimal非空参数 package com.example.core.mydemo; import java.math.BigDecimal; ...

  8. ESP8266串口WiFi模块 - WiFi杀手

    Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` ESP8266串口WiFi模块 - WiFi杀手 日期:2 ...

  9. 《Programming from the Ground Up》阅读笔记:p1-p18

    <Programming from the Ground Up>学习第1天,p1-18总结,总计18页. 一.技术总结 1.fetch-execute cycle p9, The CPU ...

  10. NXP i.MX 8M Plus工业核心板硬件说明书( 四核ARM Cortex-A53 + 单核ARM Cortex-M7,主频1.6GHz)

    1          硬件资源 创龙科技SOM-TLIMX8MP是一款基于NXP i.MX 8M Plus的四核ARM Cortex-A53 + 单核ARM Cortex-M7异构多核处理器设计的高端 ...