数学黑洞:卡普雷卡尔常数的php算法实现
首先看一篇文章:
英国广播公司报道,6174乍看没什么奇特之处,但是,自从1949年以来,它一直令数学家、数字控抓狂、痴迷。
不管你挑的四位数是什么,早早晚晚你都会遇到6174;而且,遇到6174就只能止步,否则面临的将是无休无止的无用功了。
祝贺一下,现在你总算搞懂了卡普雷卡尔常数(Kaprekar's constant,又称卡布列克常数)。
印度数学家卡普雷卡尔(1905-1986)最喜欢摆弄数字,正是他发现了6174的神奇魅力。
自认数字理论控的卡普雷卡尔1949年在印度城市马德拉斯召开的一次数学会议上向世界宣布了自己的发现。
卡普雷卡尔就读于孟买大学,毕业后在孟买北部山区小镇带奥拉利(Devlali)当老师。
印度数学家认为,卡普雷卡尔的发现很无聊,取笑一番,置之不理。不过,卡普雷卡尔是位高产作家,经常在大众科普刊物上发表文章。而且,他还常被请去参加各种会议、在学校巡回演说,介绍自己独特的方法和有趣的发现。
逐渐,卡普雷卡尔在国内外知名度、受欢迎程度越来越高。到了1970年,美国畅销书作家、数学爱好者Martin Gardner在著名科普杂志《科学美国人》上发表文章介绍卡普雷卡尔。
现在,卡普雷卡尔的名字在全世界数学爱好者——特别是数字控中——已经是如雷贯耳。
日本大阪经济大学教授西山豊(Yutaka Nishiyama)认为,6174真是个“谜一样的数字”。在一篇网上文章中,西山教授解释说,他用电脑查证是否所有的四位数都能在有限步骤内得出6174。
他的发现是,根据卡普雷卡尔的算法,所有四位数(只要四位数不重复)最多只需要7步运算就会得出6174。
“如果7步还没有得出6174,那一定是你算错了。重来一遍吧。”
把下面的代码保存为 index.php 存入服务器中,在浏览器中每刷新一次,程序会随机取出四位数进行卡普雷卡尔常数运算十步。
(一)面向过程实现:
<?php
/**
* 卡普雷卡尔常数的计算(6174的数字黑洞)
*
* 计算方法:任意四个不重复的一位数,它们组成的最大四位数减去它们组成的
* 最小四位数所得的新四位重复前面的算法,最多七次就会得到6174。
*/ // 随机数产生四位原始数字的数组
$original = array( rand(1,9), rand(1,9), rand(1,9), rand(1,9));
$orig = implode( $original );
echo "<br>原数据:{$orig}<br>"; /**
* $total[0]存放计算前的四位数
* $total[1]存放计算后的四位数
* $total[2]存放计算得到6174后的计算次数
*/
$total = array( 0, 0, 0 );
$tag = true; /**
* 整个计算就是一个 for 循环加 3 个函数完成的
* 计算 10 次数据
*/
for( $i = 0; $i < 10; $i++)
{
if( empty( $total[0] ) )
$total[1] =$total[0] = calculation( $original );
else
$total[1] = calculation( numToArr( $total[0] ) ); // *****输出计算后的数据*****
echo $total[1] . '<br>'; if( $total[1] == 6174 && $tag)
{
$tag = false;
$total[2] = $i;
}
$total[0] = $total[1];
} echo '在第<strong style="color: red">' . $total[2] . '</strong>步使数据等于6174。<br>'; /**
* 冒泡排序算法函数
* ( php有原生的排序函数 sort() 升序和 rsort() 降序排序 )
*
* @param array $arr 要排序的数组;
* @param bool $order 为 true 升序,为 false 降序。
* @return array
*/ function sortFunc($arr, $order = true)
{
$val = 0;
$count = count($arr) - 1; for($i = 0; $i < $count; $i++)
{
for($j = 0; $j < $count - $i; $j++)
{
if($order)
{
if($arr[$j] > $arr[$j + 1])
{
$tag[1]++;
$val = $arr[$j + 1];
$arr[$j + 1] = $arr[$j];
$arr[$j] = $val;
}
}
else
{
if($arr[$j] < $arr[$j + 1])
{
$val = $arr[$j + 1];
$arr[$j + 1] = $arr[$j];
$arr[$j] = $val;
}
}
}
}
return $arr;
} /**
* 卡普雷卡尔常数的计算函数
*
* 功能:任意四位数,排序后的最大数减去排序后的最小数。
* @param array $arr 输入的任意四位数。
* @return integer
*/ function calculation( $arr ){
//①用冒泡排序法实现
$big = sortFunc( $arr, false );
$small = sortFunc( $arr); //②用 php 内置函数实现
//$big = $small = $arr;
//rsort( $big, SORT_NUMERIC );
//sort( $small, SORT_NUMERIC ); $valBig = ( int )implode( $big );
$valSmall = ( int )implode( $small ); $value = $valBig - $valSmall;
return $value;
} /**
* 数字拆分成数组函数
*
* @param integer $num 四位数如:8543
* @return array 得到的数组如:array( 8, 5, 4, 3 )
* 如果用原生 php 函数是 str_split()
*/
function numToArr( $num ){
$arr = array();
$str = (string)$num; for( $i = 0; $i < strlen( $str ); $i++)
{
$arr[] = (int)substr( $str, $i, 1);
} return $arr;
}
(二)用面向对象实现上面的面向过程:
<?php
/**
* 卡普雷卡尔常数的计算(6174的数字黑洞)
*
* 计算方法:任意四个不重复的一位数,它们组成的最大四位数减去它们组成的
* 最小四位数所得的新四位重复前面的算法,最多七次就会得到6174。
*/ class KaprekarConst{ public $original = array(); /**
* $total[0]存放计算前的四位数
* $total[1]存放计算后的四位数
*/
public $total = array( 0, 0 );
public $tag = true; /**
* $val[0] 存放四位原始数据
* $val[1] 存放循环计算 10 次的数组
* $val[2] 存放计算到 6174 数据的次数
*/
public $val = array(); function __construct()
{
// 随机数产生四位原始数字的数组
$this->original = array( rand(1,9), rand(1,9), rand(1,9), rand(1,9));
} public function main()
{
$this->val[0] = implode( $this->original ); /**
* 整个计算就是一个 for 循环加 2 个方法完成的
* 计算 10 次数据
*/
for( $i = 0; $i < 10; $i++)
{
if( empty( $this->total[0] ) )
$this->total[1] = $this->total[0] = $this->calculation( $this->original );
else
$this->total[1] = $this->calculation( $this->numToArr( $this->total[0] ) ); // *****输出计算后的数据*****
$this->val[1][] = $this->total[1]; if( $this->total[1] == 6174 && $this->tag)
{
$this->tag = false;
$this->val[2] = $i;
}
$this->total[0] = $this->total[1];
}
return $this->val;
} /**
* 卡普雷卡尔常数的计算方法
*
* 功能:任意四位数,排序后的最大数减去排序后的最小数。
* @param array $arr 输入的任意四位数。
* @return integer
*/ public function calculation( $arr ){
$big = $small = $arr;
rsort( $big, SORT_NUMERIC );
sort( $small, SORT_NUMERIC ); $valBig = ( int )implode( $big );
$valSmall = ( int )implode( $small ); $value = $valBig - $valSmall;
return $value;
} /**
* 数字拆分成数组方法
*
* @param integer $num 四位数如:8543
* @return array 得到的数组如:array( 8, 5, 4, 3 )
* 如果用原生 php 函数是 str_split()
*/
public function numToArr( $num ){
$arr = array();
$str = (string)$num; for( $i = 0; $i < strlen( $str ); $i++)
{
$arr[] = (int)substr( $str, $i, 1);
} return $arr;
}
} $obj = new KaprekarConst;
$val = $obj->main(); // 显示内容:
echo '原数据:' . $val[0] . '<br>'; foreach( $val[1] as $value )
{
echo $value . '<br>';
} echo '在第<strong style="color: red">' . $val[2] . '</strong>步使数据等于6174。';
程序执行后的效果:



数学黑洞:卡普雷卡尔常数的php算法实现的更多相关文章
- 3D数学学习笔记——笛卡尔坐标系
本系列文章由birdlove1987编写.转载请注明出处. 文章链接: http://blog.csdn.net/zhurui_idea/article/details/24601215 1.3D数学 ...
- 我们数学中常用的自然常数e代表什么?看完长知识了!
我们在学习期间都接触过自然常数e,也知道e ≍ 2.718,学过极限的同学应该也知道 那么大家知道e的含义是什么吗?为啥叫“自然常数”? e的含义可以用一个计算利息的例子来解释. 假如你有1块钱,银行 ...
- 数学【p1412】 经营与开发(秦九韶算法)
顾z 你没有发现两个字里的blog都不一样嘛 qwq 题目描述-->P1412 经营与开发 分析 虽然看到\(Rank_1\)已经有了解释. 但我认为我能BB的更好 我还是决定来写一篇题解. q ...
- [bzoj4922]Karp-de-Chant Number
来自FallDream的博客,未经允许,请勿转载,谢谢. 卡常数被称为计算机算法竞赛之中最神奇的一类数字,主要特点集中于令人捉摸不透,有时候会让水平很高的选手迷之超时. 普遍认为卡常数是埃及人Qa'a ...
- 【BZOJ4922】[Lydsy六月月赛]Karp-de-Chant Number 贪心+动态规划
[BZOJ4922][Lydsy六月月赛]Karp-de-Chant Number Description 卡常数被称为计算机算法竞赛之中最神奇的一类数字,主要特点集中于令人捉摸不透,有时候会让水平很 ...
- @bzoj - 4922@ [Lydsy1706月赛]Karp-de-Chant Number
目录 @description@ @solution@ @accepted code@ @details@ @description@ 卡常数被称为计算机算法竞赛之中最神奇的一类数字,主要特点集中于令 ...
- Python标准库12 数学与随机数 (math包,random包)
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们已经在Python运算中看到Python最基本的数学运算功能.此外,math包 ...
- Python之数学(math)和随机数(random)
math包包含了最基本的数学运算函数,如果想要更加高级的数学功能,可以使用标准库外的numpy和scipy库,他们不但支持数组和矩阵运算, 还有丰富的数学和物理方程可供使用 random包可以用来生成 ...
- 七、Sql Server 基础培训《进度7-笛卡尔积(知识点+实际操作)》
知识点: 1.笛卡尔介绍 笛卡尔,近代法国著名哲学家.物理学家.数学家.神学家. 主要成就概述 笛卡尔在科学上的贡献是多方面的.笛卡尔不仅在哲学领域里开辟了一条新的道路,同时笛卡尔又是一勇于探索的科学 ...
随机推荐
- Find the median(2019年牛客多校第七场E题+左闭右开线段树)
题目链接 传送门 题意 每次往集合里面添加一段连续区间的数,然后询问当前集合内的中位数. 思路 思路很好想,但是卡内存. 当时写的动态开点线段树没卡过去,赛后机房大佬用动态开点过了,\(tql\). ...
- jmeter中设置线程数与设置集合点的区别
1.设置线程数: 表示10秒内启动50个线程, 运行结果如下:10秒内启动了50个线程 2.设置集合点: Number of Simulated Users to Group by:50,表示集合50 ...
- windows命令查看端口占用情况
打开cmd 查看端口占用情况:netstat -aon 查看PID对应的进程:tasklist /FI "PID eq 16948"
- python基础语法8 叠加装饰器,有参装饰器,wraps补充,迭代器
叠加装饰器: 叠加装饰器 - 每一个新的功能都应该写一个新的装饰器 - 否则会导致,代码冗余,结构不清晰,可扩展性差 在同一个被装饰对象中,添加多个装饰器,并执行. @装饰1 @装饰2 @装饰3 de ...
- C#中集合ArrayList与Hashtable的使用
C#中集合ArrayList与Hashtable的使用 http://blog.csdn.net/linukey/article/details/42506819 ArrayList: 一. 注意事项 ...
- 装饰器vue-property-decorator
接触到了新的vue项目,使用vue+ts+vue-property-decotator来进行项目的简化,一时间语法没有看懂,所以花时间学习这个装饰器的包. 1.装饰器 @Component(optio ...
- vue项目开发期间,配置webpack解决后台接口在不同服务器上的问题 之 二 ( node搭建服务 )
由于今天上午 后端人员把接口都整合都一个服务器了,所以就没有硬关注 上一篇文章的问题, 晚上回来,用node搭了一个简单服务器,测试了下,是没有问题的.代码如下: 一. 自己初始化项目, 1.pack ...
- 关于singer elt 的几篇很不错的文章
以下是链接来自singer 团队的实践,很不错,值得学习 参考连接 https://www.stitchdata.com/blog/100-billion-records-later-refining ...
- charles安装及使用
一.下载安装charles 1.官方网址:https://www.charlesproxy.com/ 选择自己需要的macos/windows/linux下对应的最新版本安装即可 我的是mac,下载版 ...
- js -ajax 学习
2.ajax 1)跨域 $.ajax({ type : "get", data : "data_xName=" + data_xNa ...