zoukankan      html  css  js  c++  java
  • Kaprekar constant(卡普雷卡尔黑洞)

    昨天在朋友的微博里看到一条关于数字迭代的有趣的题目。然后正好自己刚刚放假就没事写写,正好检验下我最近算法是否提高,其中弯路很多,追求在多次实践中来锻炼自己的逻辑和编码能力。

    其中描述是:

    把一个四位数的四个数字由小至大排列,组成一个新数,又由大至小排列排列组成一个新数,这两个数相减,之后重复这个步骤,只要四位数的四个数字不重复,数字最终便会变成 6174。

    例如:
    3109,
    9310 - 0139 = 9171,
    9711 - 1179 = 8532,
    8532 - 2358 = 6174。
    而 6174 这个数也会变成 6174,7641 - 1467 = 6174。
    任取一个四位数,只要四个数字不全相同,按数字递减顺序排列,构成最大数作为被减数;按数字递增顺序排列,构成最小数作为减数,其差就会得6174;如不是6174,则按上述方法再作减法,至多不过10步就必然得到6174。
    但是其中需要8步的初始数,我还没找(我把99999个随机数所转换数据导入到txt中,大小为8M,也没找到)
    一个7步的示例:
    如取四位数5679,按以上方法作运算如下:
    9765-5679=4086 8640-4068=4572 7542-2457=5085
    8550-5058=3492 9432-2349=7083 8730-3078=5652
    6552-2556=3996 9963-3699=6264 6642-2466=4176
    7641-1467=6174
     
    其中c#实现代码如下:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    
    
    namespace ConsoleApplication3
    {
        class Program
        {
            static int[] rnd;
            static int N = 0;
            const int result = 6174;
            static Random rn = new Random();
            static StringBuilder output = new StringBuilder();
    
            static void Main(string[] args)
            {
                for (int i = 0; i < 99999; i++)
                {
                    rndArr(4);
                    output.AppendLine("初始数为:" + arrToint(rnd).ToString());
                    output.Append("差值过程数分别为:");
                    if (function(rnd))
                    {
                        output.AppendLine("执行次数为" + N.ToString() + "");
                        output.AppendLine("");
                        N = 0;
                    }
                }
                try
                {
                    string filepath = "d:/1.txt";
                    FileStream fs = new FileStream(filepath, FileMode.Create);
                    StreamWriter sw = new StreamWriter(fs);
                    sw.Write(output);
                    sw.Close();
                    Console.WriteLine("success!");
                    Console.WriteLine("已经写到" + filepath);
                }
                catch { Console.Write("0"); }
                Console.ReadKey();
            }
            /// <summary>
            /// 迭代求计算次数
            /// </summary>
            /// <param name="rTemp">差值循环</param>
            /// <returns>找到固定值返回True</returns>
            static bool function(int[] rTemp)
            {
                cba(rnd); //整理成可转换成最大值的int[]
                int newint = arrToint(rTemp) - arrTointR(rTemp);
                N++;
                output.Append(newint + ",");
                if (newint == result)
                {
                    return true;
                }
                else return function(cba(intToarr(newint)));
            }
            /// <summary>
            /// 数组转换成数值(确保参数为最大值)
            /// </summary>
            /// <param name="a"></param>
            /// <returns>最大值</returns>
            static int arrToint(int[] a)
            {
                string temp = "";
                for (int i = 0; i < a.Length; i++)
                    temp += a[i].ToString();
                return Int16.Parse(temp);
            }
            /// <summary>
            /// 将数组反向再转换成数值(确保参数为最大值)
            /// </summary>
            /// <param name="a"></param>
            /// <returns>最小值</returns>
            static int arrTointR(int[] a)
            {
                string temp = "";
                for (int i = 0; i < a.Length; i++)
                    temp += a[a.Length - i - 1].ToString();
                return Int16.Parse(temp);
            }
            /// <summary>
            /// int值转成数组
            /// </summary>
            /// <param name="a"></param>
            /// <returns></returns>
            static int[] intToarr(int a)
            {
                int length = a.ToString().Length;
                int[] re = new int[length];
                for (int i = 0; i < length; i++)
                {
                    re[i] = a / Convert.ToInt16(Math.Pow(10, length - 1 - i));
                    a = a - re[i] * Convert.ToInt16(Math.Pow(10, length - 1 - i));
                }
                return re;
            }
            /// <summary>
            /// 产生初始随机数组
            /// </summary>
            /// <param name="length"></param>
            static void rndArr(int length)
            {
                rnd = new int[length];
                int[] rndtemp = new int[rnd.Length];
                for (int i = 0; i < length; i++)
                {
                    do
                    {
                        rndtemp[i] = rn.Next(10);
                    }
                    while (validate(rndtemp, rndtemp[i], i) || rndtemp[0] == 0);
                }
                rnd = rndtemp;
            }
    
            /// <summary>
            /// Random Validate 如果存在返回true
            /// </summary>
            /// <param name="v"></param>
            /// <param name="x">当前序号标记</param>
            /// <returns></returns>
            static bool validate(int[] temp, int v, int x)
            {
                int k = 0;
                for (int i = 0; i < x; i++)
                {
                    if (temp[i] == v)
                        k++;
                }
                if (k > 0) return true;
                return false;
            }
            /// <summary>
            /// 随机数组转换成最大值数组
            /// </summary>
            /// <param name="temp"></param>
            /// <returns></returns>
            static int[] cba(int[] temp)
            {
                for (int i = 0; i < temp.Length - 1; i++)
                {
                    for (int j = 0; j < temp.Length - i - 1; j++)
                    {
                        if (temp[j] < temp[j + 1])
                        {
                            temp[j] = temp[j] + temp[j + 1];
                            temp[j + 1] = temp[j] - temp[j + 1];
                            temp[j] = temp[j] - temp[j + 1];
                        }
                    }
                }
                return temp;
            }
        }
    }

     其中用到了迭代算法,这算是第一次尝试,路漫漫,其中可能有一定多绕步,过路人可以指出,在下在这感谢各位。

    参考资料:http://en.wikipedia.org/wiki/D._R._Kaprekar#cite_note-4

    下面是网友给出的利用Linq写的算法:

            static void Main(string[] args)
            {
                Process(1234, 1);
                Console.ReadKey();
            }
            private static void Process(int number, int deep)
            {
                var numbers = new int[] { number % 10, (number % 100) / 10, (number % 1000) / 100, number / 1000 };
                var ascOrder = numbers.OrderBy(n => n).ToArray();
                var descOrder = numbers.OrderByDescending(n => n).ToArray();
                var weiQuan = 10000;
                var smaller = ascOrder.Select(a =>
                {
                    weiQuan = weiQuan / 10;
                    return a * weiQuan;
                }).Sum();
                weiQuan = 10000;
                var bigger = descOrder.Select(a =>
                {
                    weiQuan = weiQuan / 10;
                    return a * weiQuan;
                }).Sum();
                var diff = bigger - smaller;
                Console.WriteLine(string.Format("第{4}次:{0}:{1}-{2}={3}", number, bigger, smaller, diff, deep));
                if (diff == number)
                {
                    Console.WriteLine("That's just right");
                    return;
                }
                else if (deep >= 10)
                {
                    Console.WriteLine("计算次数超过10次,尚未证明结果,退出");
                    return;
                }
                else
                {
                    Process(diff, ++deep);
                }
            }

    首先我在随机4个数里面写了算法,然后在排序里面也相对写复杂了,网友这算法正是突显Linq编码优势的地方。

  • 相关阅读:
    ExquisiteWnd
    GDIPlusEncapsulation
    COleDateTimeSpan
    Create Win32 Window
    vagrant 安装配置,PhpStorm10 设置远程调试
    PHPExcel导出主要代码记录
    常用js方法集合,动态加载js方法--判断变量是否为空--截取小数点后几位--截取带中文的字条串
    最近遇到的各种坑
    控制台运行bee run project 报[ERRO] Fail to watch directory[too many open files]
    Mac 安装beego And bee工具
  • 原文地址:https://www.cnblogs.com/homchou/p/2893104.html
Copyright © 2011-2022 走看看