1

基本上,我想编写一个算法来找出哪个数字需要 500 次迭代才能达到 1。我尝试了一些变体,但无法做到正确。

到目前为止,这是我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace sequence4
{
    class Program
    {
        static void Main(string[] args)
        {
            long startingNumber = 1;
            long count = 0;

            while (count != 500)
            {
                startingNumber = startingNumber * 2;
                count++;

                startingNumber = startingNumber / 3 - 1;
                count++;
            }
            Console.WriteLine(count);
            Console.WriteLine(startingNumber);
        }
    }
}

编辑:代码的更新版本

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace sequence4
{
    class Program
    {
        static void Main(string[] args)
        {
            int number = 2;
            int count = 0;

            while (count != 500)
            {
                if (number % 2 == 0)
                {
                    number = 2 * number;
                    count++;
                }

                if (number % 2 != 0)
                {
                    number = (number / 3) - 1;
                    count++;
                }
            }
            Console.WriteLine(number);
            Console.WriteLine(count);
        }
    }
}
4

1 回答 1

2

Collat​​z猜想的例子是:

考虑一下,我们有一个数字7 ,我们需要使用Collat​​z 猜想达到1

  1. 7 是奇数,所以我们使用算法 3(7) + 1 = 22
  2. 22 是偶数所以我们使用 22/2 = 11
  3. 11 是奇数,所以我们使用算法 3(11) + 1 = 34
  4. 34 是偶数所以我们使用算法 34/2 = 17
  5. 17 是奇数,所以我们使用算法 3(17) + 1 = 52
  6. 52 是偶数所以我们使用算法 52/2 = 26
  7. 26 是偶数所以我们使用算法 26/2 = 13
  8. 13 是奇数,所以我们使用算法 13(3) + 1 = 40
  9. 40 是偶数所以我们使用算法 40/2 = 20
  10. 20 是偶数所以我们使用算法 20/2 = 10
  11. 10 是偶数所以我们使用算法 10/2 = 5
  12. 5 是奇数,所以我们使用算法 5(3) + 1 = 16
  13. 16 是偶数所以我们使用算法 16/2 = 8
  14. 8 是偶数所以我们使用算法 8/2 = 4
  15. 4 是偶数所以我们使用算法 4/2 = 2
  16. 2 是偶数所以我们使用算法 2/2 = 1

奇数:x = 3n + 1
偶数:x = n / 2

我们已经为数字7应用了16次算法,我们得到了1。因此,16是循环长度。

现在,如果我们以上面的例子为例,我们需要从底线向上移动 500 倍。对于反向迭代,我们使用:

奇数:x = (n - 1) / 3
偶数:x = n * 2

现在,以编程方式实现为:

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            double output = 1;
            const int iterations = 500;
            for (var i = 1; i <= iterations; i++)
            {
                output = GetOutput(output);
                Console.WriteLine("Number after {0} iterations is: {1}", i, output);
            }
            Console.WriteLine("Required Number is: {0}", output);
            VerifyResult(output, iterations);
            Console.ReadKey();
        }

        private static double GetOutput(double input)
        {
            if (input == 1)
            {
                return 2;
            }
            var output = (input - 1) / 3;
            return output % 1 == 0 && output % 2 != 0 && output > 3 ? output : input * 2;
        }

        //To verify the above results we need this method
        private static void VerifyResult(double output, int iterations)
        {
            //-------------------------VERIFICATION-----------------------
            Console.WriteLine("Press any key to check iterations in reverse");
            Console.ReadKey();
            Console.WriteLine("Running validation process ...");
            var n = output;
            var max = n;
            var count = 0;
            Console.WriteLine("{0} (starting number in Collatz Sequence)", n);
            while (n > 1)
            {
                n = n % 2 == 0 ? n / 2 : 3 * n + 1;
                count++;
                if (n > max) max = n;
                Console.WriteLine(n);
            }
            if (count == iterations) //match here iterations and outputs
            {
                Console.WriteLine("\n\nCONGRATULATION! Verification results matched. :-)\n\n");
                Console.WriteLine("There are {0} cycle length in the sequence", count);
                Console.WriteLine("The largest number in the sequence is {0}", output);
                Console.WriteLine("\n\n-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-");
                Console.WriteLine("\n\nREQUIRED NUMBER: {0}\n\n", output);
                Console.WriteLine("-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-\n");
                Console.WriteLine("\nPress any key to exit");
            }
            else
            {
                Console.WriteLine("Oops... Verification results are not matching. :-(");
            }
        }
    }
}

示例来源:3n+1 猜想的算法指导

于 2015-08-19T15:22:25.413 回答