Task: Ulam spiral (for primes)


C++: #include <cmath>
#include <iostream>
#include <string>
#include <iomanip>
#include <vector>

class ulamSpiral {
public:
    void create( unsigned n, unsigned startWith = 1 ) {
        _lst.clear();
        if( !( n & 1 ) ) n++;
        _mx = n;
        unsigned v = n * n;
        _wd = static_cast<unsigned>( log10( static_cast<long double>( v ) ) ) + 1;
        for( unsigned u = 0; u < v; u++ )
            _lst.push_back( -1 );

        arrange( startWith );

    }
    void display( char c ) {
        if( !c ) displayNumbers();
        else displaySymbol( c );
    }

private:
    bool isPrime( unsigned u ) {
        if( u < 4 ) return u > 1;
        if( !( u % 2 ) || !( u % 3 ) ) return false;
 
        unsigned q = static_cast<unsigned>( sqrt( static_cast<long double>( u ) ) ),
                 c = 5;
        while( c <= q ) {
            if( !( u % c ) || !( u % ( c + 2 ) ) ) return false;
            c += 6;
        }
        return true;
    }
    void arrange( unsigned s ) {
        unsigned stp = 1, n = 1, posX = _mx >> 1, 
                 posY = posX, stC = 0;
        int dx = 1, dy = 0;
    
        while( posX < _mx && posY < _mx ) {
            _lst.at( posX + posY * _mx ) =  isPrime( s ) ? s : 0;
            s++;
        
            if( dx ) {
                posX += dx;
                if( ++stC == stp ) {
                    dy = -dx;
                    dx = stC = 0;
                }
            } else {
                posY += dy;
                if( ++stC == stp ) {
                    dx = dy;
                    dy = stC = 0;
                    stp++;
                }
            }
        }
    }
    void displayNumbers() {
        unsigned ct = 0;
        for( std::vector<unsigned>::iterator i = _lst.begin(); i != _lst.end(); i++ ) {
            if( *i ) std::cout << std::setw( _wd ) << *i << " ";
            else std::cout << std::string( _wd, '*' ) << " ";
            if( ++ct >= _mx ) {
                std::cout << "\n";
                ct = 0;
            }
        }
        std::cout << "\n\n";
    }
    void displaySymbol( char c ) {
        unsigned ct = 0;
        for( std::vector<unsigned>::iterator i = _lst.begin(); i != _lst.end(); i++ ) {
            if( *i ) std::cout << c;
            else std::cout << " ";
            if( ++ct >= _mx ) {
                std::cout << "\n";
                ct = 0;
            }
        }
        std::cout << "\n\n";
    }

    std::vector<unsigned> _lst;
    unsigned _mx, _wd;
};

int main( int argc, char* argv[] )
{
    ulamSpiral ulam;
    ulam.create( 9 );
    ulam.display( 0 );
    ulam.create( 35 );
    ulam.display( '#' );
    return 0;
}









Fortran: program ulam
  implicit none

  integer, parameter :: nsize = 49
  integer :: i, j, n, x, y
  integer :: a(nsize*nsize) = (/ (i, i = 1, nsize*nsize) /)
  character(1)  :: spiral(nsize, nsize) = " " 
  character(2)  :: sstr
  character(10) :: fmt
  
  n = 1
  x = nsize / 2 + 1
  y = x
  if(isprime(a(n))) spiral(x, y) = "O"
  n = n + 1

  do i = 1, nsize-1, 2
    do j = 1, i
      x = x + 1
      if(isprime(a(n))) spiral(x, y) = "O"
      n = n + 1
    end do

    do j = 1, i
      y = y - 1
      if(isprime(a(n))) spiral(x, y) = "O"
      n = n + 1
    end do

    do j = 1, i+1
      x = x - 1
      if(isprime(a(n))) spiral(x, y) = "O"
      n = n + 1
    end do

    do j = 1, i+1
      y = y + 1
      if(isprime(a(n))) spiral(x, y) = "O"
      n = n + 1
    end do
  end do

  do j = 1, nsize-1
    x = x + 1
    if(isprime(a(n))) spiral(x, y) = "O"
    n = n + 1
  end do

  write(sstr, "(i0)") nsize
  fmt = "(" // sstr // "(a,1x))"
  do i = 1, nsize
    write(*, fmt) spiral(:, i)
  end do

contains

function isprime(number)
  logical :: isprime
  integer, intent(in) :: number
  integer :: i
 
  if(number == 2) then
    isprime = .true.
  else if(number < 2 .or. mod(number,2) == 0) then
    isprime = .false.
  else
    isprime = .true.
    do i = 3, int(sqrt(real(number))), 2
      if(mod(number,i) == 0) then
        isprime = .false.
        exit
      end if
    end do
  end if
end function
end program