数学黑洞:卡普雷卡尔常数的php算法实现

首先看一篇文章:

 

  英国广播公司报道,6174乍看没什么奇特之处,但是,自从1949年以来,它一直令数学家、数字控抓狂、痴迷。

  不管你挑的四位数是什么,早早晚晚你都会遇到6174;而且,遇到6174就只能止步,否则面临的将是无休无止的无用功了。

  祝贺一下,现在你总算搞懂了卡普雷卡尔常数(Kaprekar's constant,又称卡布列克常数)。

  印度数学家卡普雷卡尔(1905-1986)最喜欢摆弄数字,正是他发现了6174的神奇魅力。

  自认数字理论控的卡普雷卡尔1949年在印度城市马德拉斯召开的一次数学会议上向世界宣布了自己的发现。

卡普雷卡尔就读于孟买大学,毕业后在孟买北部山区小镇带奥拉利(Devlali)当老师。

  印度数学家认为,卡普雷卡尔的发现很无聊,取笑一番,置之不理。不过,卡普雷卡尔是位高产作家,经常在大众科普刊物上发表文章。而且,他还常被请去参加各种会议、在学校巡回演说,介绍自己独特的方法和有趣的发现。

  逐渐,卡普雷卡尔在国内外知名度、受欢迎程度越来越高。到了1970年,美国畅销书作家、数学爱好者Martin Gardner在著名科普杂志《科学美国人》上发表文章介绍卡普雷卡尔。

现在,卡普雷卡尔的名字在全世界数学爱好者——特别是数字控中——已经是如雷贯耳。

  日本大阪经济大学教授西山豊(Yutaka Nishiyama)认为,6174真是个“谜一样的数字”。在一篇网上文章中,西山教授解释说,他用电脑查证是否所有的四位数都能在有限步骤内得出6174。

  他的发现是,根据卡普雷卡尔的算法,所有四位数(只要四位数不重复)最多只需要7步运算就会得出6174。

  “如果7步还没有得出6174,那一定是你算错了。重来一遍吧。”

<?php
/**
  *  卡普雷卡尔常数的计算(6174的数字黑洞)
  *
  * 计算方法:任意四个不重复的一位数,它们组成的最大四位数减去它们组成的
  *                     最小四位数所得的新四位重复前面的算法,最多七次就会得到6174。
  */
  
// 随机数产生四位原始数字的数组
$original = array( rand(1,9), rand(1,9), rand(1,9), rand(1,9));

echo "<br>原数据:{$original[0]}{$original[1]}{$original[2]}{$original[3]}<br>";

$total = array( 0, 0, 0 );
$total[0] = calculation( $original );
echo $total[0] . '<br>';
$tag = true;

// 计算 9 次数据,加上面1 次,共计算 10 次数据
for( $i = 0; $i < 9; $i++)
{
    $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] + 2 ) . '</strong>步使数据等于6174。<br>';

/**
  * 冒泡排序算法函数
  *
  * @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 ){
    $a = sortFunc( $arr, false );
    $b = sortFunc( $arr);

    $valA = ( int ) ( $a[0] . $a[1] . $a[2] . $a[3] );
    $valB = ( int ) ( $b[0] . $b[1] . $b[2] . $b[3] );

    $valC = $valA - $valB;
    return $valC;
}

/**
  * 四位数转数组函数
  * 
  * @param integer $num 四位数
  * @return array
  */
function numToArr( $num ){
    $arr = [];
    
    $one = $num % 10;
    $arr[] = $one;
    
    $ten = $num % 100;
    $ten1 = ( $ten - $one ) / 10;
    $arr[] = $ten1;
    
    $hundred = $num % 1000;
    $hundred_a = ( int )( $ten1 . '0' );
    $hundred_b = ( $hundred  - $hundred_a - $one) / 100;
    $arr[] = $hundred_b;
    
    $thousand = $num % 10000;
    $thousand_1 = ( int )( $hundred_b . '0' . '0');
    $thousand_2 = ( $thousand - $thousand_1  - $hundred_a - $one ) / 1000;
    $arr[] = $thousand_2;
    return $arr;
}

程序执行后的效果:

猜你喜欢

转载自www.cnblogs.com/qingsong/p/12061673.html