Show tree rings age

BBC Basic, 93 bytes

1I.r:r=r-1:F.i=-r TOr:F.j=-r TOr:p=ABS(i):q=ABS(j):IFp<q TH.p=q
2V.48-(p MOD3)*6MOD7:N.:P.:N.

The abbreviated keywords help out a lot here. In line 2, I'm using the VDU command (equivalent to C's putchar()) to print each character. This is a lot more efficient than P.MID$("0*+",p MOD3+1,1).

Here it is running in BeebEm3 on a Mac:

enter image description here


K5, 27 30 26 25 22 bytes

"0"{4(|+y,)/x}/"0*+"3!1_!

This approach iteratively "wraps" a core (beginning with "0") on all four sides using some other character ({4(|+y,)/x}). The sequence of seasonal wrappings is determined by a modulo 3 (3!) sequence. It's a bit fiddly to get the base case to line up just right.

edit:

"0*+"3!u|\:u:t,1_|t:|!

This alternative builds the entire rectangular array at once from the provided exclusive range (!) reversed and joined with itself after dropping an item (t,1_|t:|). We then take the cartesian product maximum (u|\:u:), take the entire matrix modulo 3 (3!) and index into the array of characters.

In action:

  "0*+"3!u|\:u:t,1_|t:|!1
,,"0"

  "0*+"3!u|\:u:t,1_|t:|!3
("+++++"
 "+***+"
 "+*0*+"
 "+***+"
 "+++++")

  "0*+"3!u|\:u:t,1_|t:|!5
("*********"
 "*0000000*"
 "*0+++++0*"
 "*0+***+0*"
 "*0+*0*+0*"
 "*0+***+0*"
 "*0+++++0*"
 "*0000000*"
 "*********")

CJam, 25 bytes

q~,_1>W%\+_ff{e>"0*+"=}N*

Test it here.

Explanation

q~,       e# Read input N, turn into range [0 1 ... N-1]
_1>       e# Duplicate and cut off the zero.
W%        e# Reverse.
\+        e# Prepend to original range to give [N-1 ... 1 0 1 ... N-1]
_         e# Duplicate
ff{       e# Nested map for each pair of elements in that array.
  e>      e# Take the maximum, i.e. chessboard distance from the centre.
  "0*+"=  e# Select the right character using cyclic indexing into this string.
}
N*        e# Join the lines with line feeds.