素数探索

ulong(符号なし64bit整数)をバイト列としてファイルに読み書きすることで、中断継続できる素数探索を実装してみた。結構処理が速くて最初「ほんとかっ?」って疑ってしまった;

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Threading;

namespace Prime
{
    class Prime
    {
        static List<ulong> primes = new List<ulong>();
        static ulong index = 0;
        static FileStream stream;
        static bool exit = false;
        static bool show = false;

        static void Main(string[] args)
        {
            byte[] read = new byte[8];
            stream = new FileStream(args[0], FileMode.OpenOrCreate);

            Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress);

            while (stream.Read(read, 0, 8) != 0)
            {
                ulong _index = BitConverter.ToUInt64(read, 0);
                if (_index > index)
                {
                    //Console.WriteLine(index); Console.ReadKey(true);
                    primes.Add(index = _index);
                }
            }


            Console.WriteLine("Reading has finished.");
            if (primes.Count == 0)
            {
                primes.Add(index = 2);
            }
            else
            {
                Console.WriteLine("The Largest Number was {0}.", index);
            }
            Console.WriteLine("Searching started...");
            {
                Thread searchthread = new Thread(new ThreadStart(Search));
                searchthread.Start();
                Console.WriteLine();
                Console.WriteLine("Press SpaceBar to switch show/hide found prime numbers...");
                Console.WriteLine("Press ESC to exit...");
                while (true)
                {
                    ConsoleKey keyinfo = Console.ReadKey(true).Key;
                    switch (keyinfo)
                    {
                        case ConsoleKey.Spacebar:
                            show = !show;
                            break;
                        case ConsoleKey.Escape:
                            exit = true;
                            break;
                    }
                    if (exit)
                    {
                        break;
                    }
                }
            }
        }

        static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
        {
            exit = true;
            e.Cancel = false;
        }


        static void Search()
        {
            for (; ; index++)
            {
                foreach (ulong prime in primes)
                {
                    if (exit)
                    {
                        stream.Dispose();
                        return;
                    }
                    if (index < prime * prime)
                    {
                        stream.Write(BitConverter.GetBytes(index), 0, 8);
                        primes.Add(index);
                        break;
                    }
                    else if (index % prime == 0)
                    {
                        break;
                    }
                }
            }
        }
    }
}

使い方

  • 〜.exe "ファイル名"
    • ファイルに書き込んである生データ列を読み出し素数探索を継続する。ファイルは存在していなくても新規作成される。


今思いついたんだけれど、素数を表示するのon/offできるようにしてみようかな。


[追記] 実装しました。スペースバーで切り替えられます。でも表示してないときのほうが、断然速いです。