首先看一篇文章:

英国广播公司报道,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算法实现的更多相关文章

  1. 3D数学学习笔记——笛卡尔坐标系

    本系列文章由birdlove1987编写.转载请注明出处. 文章链接: http://blog.csdn.net/zhurui_idea/article/details/24601215 1.3D数学 ...

  2. 我们数学中常用的自然常数e代表什么?看完长知识了!

    我们在学习期间都接触过自然常数e,也知道e ≍ 2.718,学过极限的同学应该也知道 那么大家知道e的含义是什么吗?为啥叫“自然常数”? e的含义可以用一个计算利息的例子来解释. 假如你有1块钱,银行 ...

  3. 数学【p1412】 经营与开发(秦九韶算法)

    顾z 你没有发现两个字里的blog都不一样嘛 qwq 题目描述-->P1412 经营与开发 分析 虽然看到\(Rank_1\)已经有了解释. 但我认为我能BB的更好 我还是决定来写一篇题解. q ...

  4. [bzoj4922]Karp-de-Chant Number

    来自FallDream的博客,未经允许,请勿转载,谢谢. 卡常数被称为计算机算法竞赛之中最神奇的一类数字,主要特点集中于令人捉摸不透,有时候会让水平很高的选手迷之超时. 普遍认为卡常数是埃及人Qa'a ...

  5. 【BZOJ4922】[Lydsy六月月赛]Karp-de-Chant Number 贪心+动态规划

    [BZOJ4922][Lydsy六月月赛]Karp-de-Chant Number Description 卡常数被称为计算机算法竞赛之中最神奇的一类数字,主要特点集中于令人捉摸不透,有时候会让水平很 ...

  6. @bzoj - 4922@ [Lydsy1706月赛]Karp-de-Chant Number

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 卡常数被称为计算机算法竞赛之中最神奇的一类数字,主要特点集中于令 ...

  7. Python标准库12 数学与随机数 (math包,random包)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们已经在Python运算中看到Python最基本的数学运算功能.此外,math包 ...

  8. Python之数学(math)和随机数(random)

    math包包含了最基本的数学运算函数,如果想要更加高级的数学功能,可以使用标准库外的numpy和scipy库,他们不但支持数组和矩阵运算, 还有丰富的数学和物理方程可供使用 random包可以用来生成 ...

  9. 七、Sql Server 基础培训《进度7-笛卡尔积(知识点+实际操作)》

    知识点: 1.笛卡尔介绍 笛卡尔,近代法国著名哲学家.物理学家.数学家.神学家. 主要成就概述 笛卡尔在科学上的贡献是多方面的.笛卡尔不仅在哲学领域里开辟了一条新的道路,同时笛卡尔又是一勇于探索的科学 ...

随机推荐

  1. Vuex状态数据源state

    (1)单一状态树 Vuex 使用单一状态,用一个对象就包含了全部的应用层级状态.至此它便作为一个“唯一数据源 (SSOT)”而存在.这也意味着,每个应用将仅仅包含一个 store 实例. 单一状态树让 ...

  2. flex布局--小实例

    圣杯布局(Holy Grail Layout)指的是一种最常见的网站布局.页面从上到下,分成三个部分:头部(header),躯干(body),尾部(footer).其中躯干又水平分成三栏,从左到右为: ...

  3. param动作

    param动作通常与forword一起使用 <jsp:forword page="目标页面" > <jsp:param value="参数值" ...

  4. The difference between Virtual DOM and DOM

    dom是结构化的文本信息的抽象,是结构化的文本信息在内存中的表示 是操作结构化文本信息的api. Follow: Follow React attacks us with the virtual DO ...

  5. RxSwift 在本质上简化了开发异步程序

    RxSwift 是一个组合异步和事件驱动编程的库,通过使用可观察序列和功能样式运算符来,从而允许通过调度程序进行参数化执行. RxSwift 在本质上简化了开发异步程序,允许代码对新数据作出反应,并以 ...

  6. 强制结束虚拟机 centos home 卷丢失导致无法挂载进入 emergency mode 紧急模式

    参考文章: https://blog.51cto.com/13059784/2054378 xfs文件修复参考1:https://codeday.me/bug/20181112/367781.html ...

  7. WinDbg常用命令系列---!uniqstack

    简介 这个!uniqstack扩展扩展显示的所有线程的堆栈的所有当前进程,不包括显示为具有重复项的堆栈中. 使用形式 !uniqstack [ -b | -v | -p ] [ -n ] 参数 -b将 ...

  8. Python 10 训练模型

    原文:https://www.cnblogs.com/denny402/p/7520063.html 原文:https://www.jianshu.com/p/84f72791806f 原文:http ...

  9. smartnic

    19年趋势: Intel® 2019网络技术研讨会圆满落幕 SANTOS: Flow and HQoS Acceleration Over DPDK Using Intel Programmable ...

  10. js 队列

    js 中的异步队列(micro & macro) js都是靠事件驱动的, js中的事件循环机制是什么呢? 只是简单写一下自己的理解, 所以不是很全面; js 程序执行有 主队列 以及 异步队列 ...