📜  在素数螺旋中查找素数的坐标

📅  最后修改于: 2021-04-29 08:25:48             🧑  作者: Mango

介绍
Ulam螺旋线是数学家Stanislaw Ulam设计的素数集的图形描述。它是通过将正整数写成正方形螺旋并特别标记质数来构造的。您可以在此处了解更多信息。

但是,我们将在此螺旋的替代版本上进行计算,其中素数在螺旋中排列,而不是原始Ulam螺旋中的自然数。

如上图所示,素数以螺旋形式从原点(0,0)开始并移动。右列和底行中显示的数字分别是列号和行号(即y和x坐标)

目的是找到给定质数的位置(x和y坐标)。

例子:

Input : 5
Output : 1 1 
As per the diagram above 5 corresponds to 
the column 1 and row 1.

Input : 11
Output : -1 1 
Similarly, 11 will correspond to column -1
and row 1. 

方法:该问题的一般解决方案是创建一种算法,以预测移动螺旋点在每个步长处的位置,并将螺旋中的每个步长引用为质数(例如,步骤0 –> 2;步骤1 –> 3)。 ;步骤2 –> 5,依此类推)。使用这个素数,我们可以追溯到我们的解决方案坐标(2 –> [0,0],3 –> [1,0],5 –> [1,1])。

我们从保持x和y的计数开始,对于步骤k = 1:x = y =0。k = 2导致x增加1(x = 1),接下来是k = 3,前提是y = 1。螺旋旋转,我们现在将值减小2。连续运动如下所示:

从上面的计算中,我们观察到对于一批步骤而言,这些操作是相同的,例如,首先,K = 2&3,然后是其中x递增1,然后y递增1的操作。接下来是K = 4,5,6,在图7中,对于4和5,在K = 6和7中,x减小,而y减小。同样,从K = 8、9和10开始,x在重复的步骤中增大,而11、12、13由y减小组成。

每个步骤都可以分为一个批次,两次运行后,批次的大小增加1。运行后,操作从y切换到x,反之亦然,每两批运行一次后,加法操作切换到减法,反之亦然。下表对此进行了说明。

最后,我们还需要创建一个素数生成器,该素数生成器将继续向上述算法提供素数,该素数将被引用到相应的步骤,并且它将为我们提供所需的坐标。

这是上述想法的实现:
输入限制: 2 假设:素数是该程序的唯一输入。

C++
// C++ Program to find coordinates of a
// prime number in a Prime Spiral
#include 
  
using namespace std;
  
// The main algorithm that keeps track of
// coordinates
void spiralSplicer(int input)
{
    // Batch size tracker
    int step_count = 1;
  
    // Batch size limiter
    int step_limit = 2;
  
    // switches between -1 and +1
    int adder = 1;
  
    // Co-ordinates of step K
    int x = 0, y = 0;
  
    for (int n = 2; n != input + 1; n++, 
                       step_count++) { 
  
        // Keeps track of steps
        // Checks on the current batch
        if (step_count <= .5 * step_limit)
            x += adder; // Switch to operating on x
  
        else if (step_count <= step_limit)
            y += adder; // Switch to operating on x
          
        if (step_count == step_limit) {
   
            // Changes adder to -1 and vice versa
            adder *= -1; 
  
           // Keeps on updating 'step_limit'
           step_limit += 2; 
             
           // Resets count
           step_count = 0; 
        }
    }
    cout << x << " " << y;
}
  
int primeIndex(int input)
{
    int j, cnt, prime_c = 0;
    for (int i = 2; i <= 1000000; i++) {
        cnt = 0;
        for (j = 2; j <= i; j++) {
            if (i % j == 0)
                cnt++;
        }
  
        if (cnt == 1) {
            prime_c++;
  
            if (input == i) {
  
           /* Replaces the prime number with 
              Step K which will be fed into
              the main algorithm*/
                input = prime_c; 
                break;
            }
        }
    }
    return input;
}
  
// driver code
int main()
{
    int input = 113;
  
    // Prime Index Finder Output ported
    // to final algorithm
    spiralSplicer(primeIndex(input));
}


Java
// java Program to find coordinates of a
// prime number in a Prime Spiral
public class GFG {
      
    // The main algorithm that keeps track of
    // coordinates
    static void spiralSplicer(int input)
    {
          
        // Batch size tracker
        int step_count = 1;
      
        // Batch size limiter
        int step_limit = 2;
      
        // switches between -1 and +1
        int adder = 1;
      
        // Co-ordinates of step K
        int x = 0, y = 0;
      
        for (int n = 2; n != input + 1; 
                    n++, step_count++)
        { 
      
            // Keeps track of steps
            // Checks on the current batch
            if (step_count <= .5 * step_limit)
              
                // Switch to operating on x
                x += adder;
      
            else if (step_count <= step_limit)
              
                // Switch to operating on x
                y += adder;
              
            if (step_count == step_limit)
            {
      
                // Changes adder to -1 and
                // vice versa
                adder *= -1; 
      
                // Keeps on updating 'step_limit'
                step_limit += 2; 
                      
                // Resets count
                step_count = 0; 
            }
        }
          
        System.out.print( x + " " + y);
    }
      
    static int primeIndex(int input)
    {
        int j, cnt, prime_c = 0;
        for (int i = 2; i <= 1000000; i++) 
        {
            cnt = 0;
            for (j = 2; j <= i; j++)
            {
                if (i % j == 0)
                    cnt++;
            }
      
            if (cnt == 1) 
            {
                prime_c++;
      
                if (input == i) 
                {
      
                    /* Replaces the prime 
                    number with Step K which 
                    will be fed into
                    the main algorithm*/
                    input = prime_c; 
                    break;
                }
            }
        }
          
        return input;
    }     
      
    // Driver code
    public static void main(String args[]) {
  
        int input = 113;
  
        // Prime Index Finder Output ported
        // to final algorithm
        spiralSplicer(primeIndex(input));
  
    }
}
  
// This code is contributed by Sam007.


Python
# Python Program to find coordinates of a
# prime number in a Prime Spiral
  
# The main algorithm that keeps track of
# coordinates
def spiralSplicer(inp):
     
    # Batch size tracker
    step_count = 1
   
    # Batch size limiter
    step_limit = 2
   
    # switches between -1 and +1
    adder = 1
   
    # Co-ordinates of step K
    x, y = 0, 0
   
    for n in range(2, inp + 1):
     
        # Keeps track of steps
        # Checks on the current batch
        if (step_count <= .5 * step_limit):
            x += adder # Switch to operating on x
   
        elif (step_count <= step_limit):
            y += adder # Switch to operating on x
           
        if (step_count == step_limit):
            # Changes adder to -1 and vice versa
            adder *= -1
   
            # Keeps on updating 'step_limit'
            step_limit += 2
              
            # Resets count
            step_count = 0
        step_count += 1
    print x, y
   
def primeIndex(inp):
    cnt, prime_c = 0, 0
    for i in range(2, 1000000 + 1):
        cnt = 0
        for j in range(2, i + 1):
            if (i % j == 0):
                cnt += 1
          
        if (cnt == 1):
            prime_c += 1
   
            if (inp == i):
   
                """ Replaces the prime number with 
                    Step K which will be fed into
                    the main algorithm """
                inp = prime_c
                break
    return inp
   
# driver code
inp = 113
  
# Prime Index Finder Output ported
# to final algorithm
temp = primeIndex(inp)
  
spiralSplicer(temp)
  
#This code is contributed by Sachin Bisht


C#
// C# Program to find coordinates of a
// prime number in a Prime Spiral
using System;
  
class GFG {
      
    // The main algorithm that keeps track of
    // coordinates
    static void spiralSplicer(int input)
    {
          
        // Batch size tracker
        int step_count = 1;
      
        // Batch size limiter
        int step_limit = 2;
      
        // switches between -1 and +1
        int adder = 1;
      
        // Co-ordinates of step K
        int x = 0, y = 0;
      
        for (int n = 2; n != input + 1; 
                     n++, step_count++)
        { 
      
            // Keeps track of steps
            // Checks on the current batch
            if (step_count <= .5 * step_limit)
              
                // Switch to operating on x
                x += adder;
      
            else if (step_count <= step_limit)
              
                // Switch to operating on x
                y += adder;
              
            if (step_count == step_limit)
            {
      
                // Changes adder to -1 and
                // vice versa
                adder *= -1; 
      
                // Keeps on updating 'step_limit'
                step_limit += 2; 
                      
                // Resets count
                step_count = 0; 
            }
        }
          
        Console.Write( x + " " + y);
    }
      
    static int primeIndex(int input)
    {
        int j, cnt, prime_c = 0;
        for (int i = 2; i <= 1000000; i++) 
        {
            cnt = 0;
            for (j = 2; j <= i; j++)
            {
                if (i % j == 0)
                    cnt++;
            }
      
            if (cnt == 1) 
            {
                prime_c++;
      
                if (input == i) 
                {
      
                    /* Replaces the prime 
                    number with Step K which 
                    will be fed into
                    the main algorithm*/
                    input = prime_c; 
                    break;
                }
            }
        }
          
        return input;
    }     
      
    // Driver code
    public static void Main ()
    {
        int input = 113;
  
        // Prime Index Finder Output ported
        // to final algorithm
        spiralSplicer(primeIndex(input));
    }        
}
  
// This code is contributed by Sam007.


PHP


输出 :

3 2