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)
):
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:
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)
Notes:
I tried to make the
s
function anonymous too, of course that would reduce the count significantly. However, there are 2 issues: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.
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);