Can square tree rings be generated from primes?

MATLAB - 197 185 178 175 184 163 162 148 142 140 bytes

Shaved 12 bytes, thanks to Ander and Andras, and lots thanks to Luis for putting the two together. Shaved 16 thanks to Remco, 6 thanks to flawr

function F(n)
p=@primes
s=@isprime
for a=2:n^2
c=0
if~s(a)
b=nnz(p(a))
while~s(b)
b=nnz(p(b))
c=c+1
end
end
d(a)=c
end
imagesc(d(spiral(n)))

Result for N=301 (F(301)):

enter image description here

Explanation:

function F(n)
p=@primes % Handle
s=@isprime % Handle
for a=2:n^2 % Loop over all numbers
    c=0 % Set initial count
    if~s(a) % If not a prime
        b=nnz(p(a)) % Count primes
        while~s(b) % Stop if b is a prime. Since the code starts at 2, it never reaches 1 anyway
            b=nnz(p(b)) % count again
            c=c+1 % increase count
        end
    end
    d(a)=c % store count
end
imagesc(d(spiral(n))) % plot

Wolfram Language (Mathematica), 124 bytes

Thanks to Martin Ender for saving 12 bytes!

Image[#/Max@#]&[Array[(n=0;Max[4#2#2-Max[+##,3#2-#],4#
#-{+##,3#-#2}]+1//.x_?CompositeQ:>PrimePi[++n;x];n)&,{#,#},(1-#)/2]]&

Try it online!


The image generated is:

Spiral

Closed form formula of the spiral value taken directly from this answer of mine.


MATLAB: 115 114 110 bytes

One liner (run in R2016b+ as function in script) 115 bytes

I=@(N)imagesc(arrayfun(@(x)s(x,0),spiral(N)));function k=s(n,k);if n>1&~isprime(n);k=s(nnz(primes(n)),k+1);end;end

Putting the function in a separate file, as suggested by flawr, and using the 1 additional byte per additional file rule

In the file s.m, 64 + 1 bytes for code + file

function k=s(n,k);if n>1&~isprime(n);k=s(nnz(primes(n)),k+1);end

Command window to define I, 45 bytes

I=@(N)imagesc(arrayfun(@(x)s(x,0),spiral(N)))

Total: 110 bytes


This uses recursion instead of while looping like the other MATLAB implementations do (gnovice, Adriaan). Run it as a script (in R2016b or newer), this defines the function I which can be run like I(n).

Structured version:

% Anonymous function for use, i.e. I(301)
% Uses arrayfun to avoid for loop, spiral to create spiral!
I=@(N)imagesc(arrayfun(@(x)s(x,0),spiral(N)));

% Function for recursively calculating the s(n) value
function k=s(n,k)
    % Condition for re-iterating. Otherwise return k unchanged
    if n>1 && ~isprime(n)
        % Increment k and re-iterate
        k = s( nnz(primes(n)), k+1 );
    end
end

Example:

I(301)

plot

Notes:

  • I tried to make the s function anonymous too, of course that would reduce the count significantly. However, there are 2 issues:

    1. Infinite recursion is hard to avoid when using anonymous functions, as MATLAB doesn't have a ternary operator to offer a break condition. Bodging a ternary operator of sorts (see below) also costs bytes as we need the condition twice.

    2. You have to pass an anonymous function to itself if it is recursive (see here) which adds bytes.

    The closest I came to this used the following lines, perhaps it can be changed to work:

    % Condition, since we need to use it twice 
    c=@(n)n>1&&~isprime(n);
    % This uses a bodged ternary operator, multiplying the two possible outputs by
    % c(n) and ~c(n) and adding to return effectively only one of them
    % An attempt was made to use &&'s short-circuiting to avoid infinite recursion
    % but this doesn't seem to work!
    S=@(S,n,k)~c(n)*k+c(n)&&S(S,nnz(primes(n)),k+1);