数字黑洞
数字黑洞,又称指的是某种运算,这种运算一般限定从某些整数出发,反复迭代后结果必然落入一个点或若干点的情况叫数字黑洞。
黑洞原是天文学中的概念,表示这样一种天体:它的引力场是如此之强,就连光也不能逃脱出来。
黑洞数又称陷阱数,类具有奇特转换特性,任何数字不全相同的整数,经有限重排求差操作,总会得某或些数,这些数即黑洞数重排求差操作即把组成该数数字重排得大数减去重排得小数。
西绪福斯黑洞(123数字黑洞)
数学中的123就跟英语中的ABC一样平凡和简单。然而,按以下运算顺序,就可以观察到这个最简单的数字。
黑洞的值:
设定一个任意数字串,数出这个数中的偶数个数,奇数个数,及这个数中所包含的所有位数的总数,
例如:1234567890,
1.偶:数出该数数字中的偶数个数,在本例中为2,4,6,8,0,总共有 5 个。
2.奇:数出该数数字中的奇数个数,在本例中为1,3,5,7,9,总共有 5 个。
3.总:数出该数数字的总个数,本例中为 10 个。
4.新数:将答案按 “偶-奇-总” 的位序,排出得到新数为:5510。
5.重复:将新数5510按以上算法重复运算,可得到新数:134。
6.重复:将新数134按以上算法重复运算,可得到新数:123。
结论:对数1234567890,按上述算法,最后必得出123的结果,我们可以用计算机写出程序,测试出对任意一个数经有限次重复后都会是123。换言之,任何数的最终结果都无法逃逸123黑洞……
新建VS2017控制台程序DigitalBlackHoleDemo
源程序如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DigitalBlackHoleDemo
{
class Program
{
static void Main(string[] args)
{
Console.SetWindowSize(140, 60);
for (int i = 0; i < 2; i++)
{
SisyphusBlackHole(new Random(Guid.NewGuid().GetHashCode()).Next(1, int.MaxValue) + (long)1.5E16);
Console.WriteLine();
}
for (int i = 0; i < 3; i++)
{
ThreeDigitBlackHole(new Random(Guid.NewGuid().GetHashCode()).Next(100, 999));
Console.WriteLine();
}
for (int i = 0; i < 5; i++)
{
FourDigitBlackHole(new Random(Guid.NewGuid().GetHashCode()).Next(1000, 9999));
Console.WriteLine();
}
Console.ReadLine();
}
/// <summary>
/// 西西弗斯黑洞【123数字黑洞】
/// 设定一个任意数字串,数出这个数中的偶数个数,奇数个数,及这个数中所包含的所有位数的总数
/// 比如86420135799,按照偶数个数5,奇数个数6,数字总个数11,拼接成一个新的整数 5611
/// 然后依次转化为134,然后转化为123结束
/// </summary>
/// <param name="digit"></param>
static void SisyphusBlackHole(long digit)
{
Console.WriteLine($"开始计算数字【{digit}】的西西弗斯黑洞数...");
if (digit == 0)
{
digit = 101;
}
int index = 0;
while (true)
{
index++;
long initialNumber = digit;
int evenCount = 0;//偶数个数
int oddCount = 0;//奇数个数
Stack<long> stack = new Stack<long>();
while (digit != 0)
{
long currentNumber = digit % 10;
if ((currentNumber & 1) == 0)
{
evenCount++;//偶数
}
else
{
oddCount++;//奇数
}
stack.Push(currentNumber);
digit = digit / 10;
}
long nextNumber = long.Parse(string.Concat(evenCount, oddCount, evenCount + oddCount));
Console.WriteLine($"第【{index}】次运算:数字【{initialNumber}】的偶数个数【{evenCount}】,奇数个数【{oddCount}】,按照 偶-奇-总 组合而成的数字为【{nextNumber}】");
if (nextNumber == initialNumber)
{
Console.WriteLine($"已获得最终西西弗斯黑洞数结果:【{nextNumber}】,共运算【{index}】次");
break;
}
digit = nextNumber;
}
}
/// <summary>
/// 卡普雷卡尔黑洞(重排求差黑洞):三位数黑洞495
/// </summary>
/// <param name="threeDigit">任何一个不能被111整除的三位数</param>
static void ThreeDigitBlackHole(int threeDigit)
{
Console.WriteLine($"开始计算三位数【{threeDigit}】的卡普雷卡尔黑洞数...");
if (threeDigit < 100 || threeDigit > 999)
{
Console.WriteLine($"卡普雷卡尔黑洞三位数必须在100~999之间,当前数组【{threeDigit}】非法");
return;
}
if (threeDigit % 111 == 0)
{
Console.WriteLine($"卡普雷卡尔黑洞三位数字不能完全一致,当前数组【{threeDigit}】非法");
return;
}
int index = 1;
//CalculateProcedure计算过程,使用三个数组成的最大数 减去 最小数
while (true)
{
int[] descendingArray = GetdescendingNumber(threeDigit, 3);
int maxNumber = int.Parse(string.Join("", descendingArray));
int minNumber = int.Parse(string.Join("", descendingArray.Reverse()));
int differenceNumber = maxNumber - minNumber;
Console.WriteLine($"第【{index}】次运算:三位数【{threeDigit}】排列后的最大值【{maxNumber}】,最小值【{minNumber}】,差值【{differenceNumber}】");
if (differenceNumber == threeDigit)
{
Console.WriteLine($"已获得最终数字黑洞结果:【{differenceNumber}】,共运算【{index}】次");
break;
}
//使用差值重新运算
threeDigit = differenceNumber;
index++;
}
}
/// <summary>
/// 卡普雷卡尔黑洞(重排求差黑洞):四位数黑洞6174
/// </summary>
/// <param name="fourDigit">任何一个不能被1111整除的四位数</param>
static void FourDigitBlackHole(int fourDigit)
{
Console.WriteLine($"开始计算四位数【{fourDigit}】的卡普雷卡尔黑洞数...");
if (fourDigit < 1000 || fourDigit > 9999)
{
Console.WriteLine($"卡普雷卡尔黑洞四位数必须在1000~9999之间,当前数组【{fourDigit}】非法");
return;
}
if (fourDigit % 1111 == 0)
{
Console.WriteLine($"卡普雷卡尔黑洞四位数字不能完全一致,当前数组【{fourDigit}】非法");
return;
}
int index = 1;
//CalculateProcedure计算过程,使用三个数组成的最大数 减去 最小数
while (true)
{
//唯一不同的就是参数不同
int[] descendingArray = GetdescendingNumber(fourDigit, 4);
int maxNumber = int.Parse(string.Join("", descendingArray));
int minNumber = int.Parse(string.Join("", descendingArray.Reverse()));
int differenceNumber = maxNumber - minNumber;
Console.WriteLine($"第【{index}】次运算:四位数【{fourDigit}】排列后的最大值【{maxNumber}】,最小值【{minNumber}】,差值【{differenceNumber}】");
if (differenceNumber == fourDigit)
{
Console.WriteLine($"已获得最终数字黑洞结果:【{differenceNumber}】,共运算【{index}】次");
break;
}
//使用差值重新运算
fourDigit = differenceNumber;
index++;
}
}
/// <summary>
/// 返回逆序排序的三个数字 或 四个数字,如果返回数字低于digitCount个,那么尾巴按0处理
/// 返回的数组的每一个元素都在0~9之间
/// </summary>
/// <param name="digit">源数,可能三位数,也可能是四位数,也可能是小于100的数</param>
/// <param name="digitCount">返回的数字个数</param>
/// <returns></returns>
static int[] GetdescendingNumber(int digit, int digitCount)
{
int index = 0;
Stack<int> stack = new Stack<int>();
while (digit != 0)
{
stack.Push(digit % 10);
digit = digit / 10;
index++;
}
//Console.WriteLine(string.Join(",", stack));
int[] descendingArray = stack.ToArray();
//对数字进行逆序排序
Array.Sort(descendingArray, (x, y) => y - x);
int[] destArray = new int[digitCount];
Array.Copy(descendingArray, destArray, descendingArray.Length);
return destArray;
}
}
}
程序运行结果如图: