سؤال

أبحث عن الأفكار / الرمز (يفضل أن يكون C #، ولكن اللغات الأخرى تعمل أيضا) لإنشاء حلزو ulam كبير بلا حدود (محدود بطول الوقت يعمل البرنامج، أو حتى توقف).

alt text

الآن الأرقام هي جميع الأعداد الأولية حتى يكون الكود لأولئك غير ذي صلة بالأحرى. الجزء المثير للاهتمام هو كيفية ترتيب الترتيب في دوامة Evergroging (اللانهائية)، أي نوع من هيكل البيانات مفيد لدعمه، وربما أفكار الإخراج (ملف الرسومات أو الملف النصي؟).

كيف يمكنك أن تذهب نحو هذا؟

هل كانت مفيدة؟

المحلول

النظر في أطوال كل جانب: 1، 1، 2، 2، 3، 3، 4، 4، ...

الشيء المباشر هو التكرار فوق كل جانب، مما يجعل هذا الجانب. يمكنك استخدام أسلوب الشعار تقديم البدائيات:

Angle = 0;
x=0; y = 0;
int number = 1;
int sideLength = 1;

StartLine();
for (int side = 1; side < maxSize; side++) {
 for (int k = 0; k < sideLength; k++) {
  Forward(1);
  number++;

  if (isPrime(number)) {
   StopLine();
   Ouput(number);
   StartLine();
  }
 }
 TurnLeft();
 if (side % 2 == 0) sideLength++;
}

قد تتحسن هذا من خلال التكرار فقط في الأعداد الأولية على جانب:

نصائح أخرى

يعمل البرنامج التالي عن طريق حساب إحداثيات رقم مباشرة مباشرة. طريقة NumberToPoint() يؤدي رسم الخرائط التالية.

0 => (x0    , y0    )
1 => (x0 + 1, y0    )
2 => (x0 + 1, y0 - 1)
3 => (x0    , y0 - 1)
4 => (x0 - 1, y0 - 1)
5 => (x0 - 1, y0    )
6 => ...

الباقي هو اختبار الأرقام البسيطة للغاية وتطبيق وحدة التحكم الصغيرة.

من أجل حفظ صورة فسوف أعتبر حلنتين. إذا كان بإمكانك إنشاء مخزن مؤقت للصورة بأكملها، فيمكنك فقط استخدام البرنامج أدناه لملء المخزن المؤقت.

إذا كان المخزن المؤقت هو كبير، فسأخلق طريقة PointToNumber() وحذر الحساب - الطريقة تأخذ إحداثيات اثنين وإرجاع الرقم في هذه المرحلة. مع هذه الطريقة، يمكنك التكرار من أعلى إلى أسفل واليسار إلى اليمين وحساب الرقم في هذه المرحلة، والتحقق مما إذا كان الأمر الرئيسي، وإخراج البكسل كما تذهب بدون مخزن مؤقت. ولكن لكلا الحلول يجب أن يكون حجم الصورة معروفا قبل أن تبدأ، لأن إضافة بكسل في الأعلى واليسار مكلفة للغاية (ولكن من السبب ممكن).

أسئلة

  1. أي أفكار جيدة لتحويل البحث معامل في NumberToPoint() في الصخور الصلبة الرياضيات دون استخدام modulo، قسم عدد صحيح، وتوقيع ألف مرة؟
  2. أي أفكار جيدة لتقصير أو تسريع اختبار الأرقام الأول؟

شفرة

using System;
using System.Drawing;
using System.Linq;
using System.Threading;

namespace UlamsSpiral
{
   public static class Program
   {
      public static void Main()
      {
         Int32 width = 60;
         Int32 height = 60;

         Console.SetWindowSize(Math.Min(width, 120), Math.Min(height, 60));
         Console.SetBufferSize(width, height);
         Console.CursorVisible = false;

         Int32 limit = (Int32)Math.Pow(Math.Min(width, height) - 2, 2);

         for (Int32 n = 1; n <= limit; n++)
         {
            Point point = NumberToPoint(n - 1, width / 2 - 1, height / 2);

            Console.ForegroundColor = n.IsPrime() ? ConsoleColor.DarkBlue : ConsoleColor.DarkGray;

            Console.SetCursorPosition(point.X, point.Y);
            Console.Write('\u25A0');

            Console.SetCursorPosition(0, 0);
            Console.Write(n);

            Thread.Sleep(10);
         }

         Console.ReadLine();
      }

      private static Point NumberToPoint(Int32 n, Int32 x0, Int32 y0)
      {
         Int32[,] c = { { -1, 0, 0, -1, 1, 0 }, { -1, 1, 1, 1, 0, 0 }, { 1, 0, 1, 1, -1, -1 }, { 1, -1, 0, -1, 0, -1 } };

         Int32 square = (Int32)Math.Floor(Math.Sqrt(n / 4));

         Int32 index;
         Int32 side = (Int32)Math.DivRem(n - 4 * square * square, 2 * square + 1, out index);

         Int32 x = c[side, 0] * square + c[side, 1] * index + c[side, 2];
         Int32 y = c[side, 3] * square + c[side, 4] * index + c[side, 5];

         return new Point(x + x0, y + y0);
      }

      private static Boolean IsPrime(this Int32 n)
      {
         if (n < 3) return (n == 2);
         return Enumerable.Range(2, (Int32)Math.Sqrt(n)).All(m => n % m != 0);
      }
   }
}

إحدى الطرق الممكنة للقيام بذلك هي إنشاء مجموعة خطية أو قائمة لتخزين الأرقام واستخدم صيغة لتحديد متى يحتاج الاتجاه إلى التغيير. أما بالنسبة للمخرجات، فأنا أحب المثال على ويكيبيديا رسم بكسل أسود لرسم بيكسل أبيض لجميع الأرقام الأخرى.

لماذا لا يكون لديك عملية / مؤشر ترابط "مولد" يقوم بإنشاء الأرقام و "Reader / Display" / مؤشر ترابط يعرضها، ثم يمكنك فصل الإنشاء من الشاشة ثم سيكون البرنامج محدودا فقط بمبلغ مقدار البيانات يستهلك "القارئ / العرض". منذ أن أفترض أن "المولد" يحتاج إلى مجموعة من البيانات بحجم ثابت إلى حد ما للعمل معها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top