[Question]
  [
## Introduction
Yesterday I saw a [birthday puzzle](https://codegolf.stackexchange.com/questions/57277/its-my-birthday-d). Congrats!!
Also this week I watched an episode of the TV show *Bones* where a dead body was found buried under a tree. To calculate the time of death, they counted the tree rings.
Tree rings form because trees grow slower during the winter and faster during the summer. Thus you can calculate the tree's age by counting the rings. Also you can see natural events like rainy or dry seasons.
[![enter image description here](https://i.stack.imgur.com/2BqEX.png)](https://i.stack.imgur.com/2BqEX.png)
## Challenge
Given an integer `n >= 1` as input, write a full program to output the tree age rings.
Because rings can change of shape use three diferent characters ('0', '\*', '+') to show climate cycles.
Age 1
```
0
```
Age 2
```
***
*0*
***
```
Age 3
```
+++++
+***+
+*0*+
+***+
+++++
```
Age 4
```
0000000
0+++++0
0+***+0
0+*0*+0
0+***+0
0+++++0
0000000
```
Size of the tree is a square of sides `2*n - 1`
## Winning
Shortest code in bytes wins.
  
[Answer]
# 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](https://i.stack.imgur.com/8ho6U.gif)](https://i.stack.imgur.com/8ho6U.gif)
[Answer]
# CJam, 25 bytes
```
q~,_1>W%\+_ff{e>"0*+"=}N*
```
[Test it here.](http://cjam.aditsu.net/#code=q~%2C_1%3EW%25%5C%2B_ff%7Be%3E%220*%2B%22%3D%7DN*&input=7)
## 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.
```
[Answer]
# 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*"
 "*********")
```
[Answer]
## Python 2, 83 bytes
```
I=n=input()
while I+n-1:I-=1;i=abs(I);w=("O*+"*n)[i:n];print w[::-1]+w[0]*2*i+w[1:]
```
Prints line by line. Each line is chopped into three parts:
* The left cycling part, including the first repeated char.
* The repeating center part
* The right cycling part.
For `n=4`:
```
0    000000    
0+    ++++    0
0+*    **    +0
0+*0        *+0
0+*    **    +0
0+    ++++    0
0    000000    
```
We generate the left part in reverse as `w`, clone its last character `2*i` times, then add on the original version without the first character.
[Answer]
## Matlab, 63 bytes
```
n=input('')-1;x='0*+';t=abs(-n:n);x(mod(bsxfun(@max,t,t'),3)+1)
```
Example:
```
>> n=input('')-1;x='0*+';t=abs(-n:n);x(mod(bsxfun(@max,t,t'),3)+1)
5
ans =
*********
*0000000*
*0+++++0*
*0+***+0*
*0+*0*+0*
*0+***+0*
*0+++++0*
*0000000*
*********
```
[Answer]
## Python 2, 83 bytes
```
n=input()
R=range(1-n,n)
for i in R:print''.join('0*+'[max(i,-i,j,-j)%3]for j in R)
```
If we think of the tree as a coordinate grid, the symbol at `(i,j)` is determined by `max(abs(i),abs(j))%3`, or equivalently `max(i,-i,j,-j)%3`.
For each row `i`, we join and print the symbols in that row. 
[Answer]
# Pyth, 23 bytes
```
VK+_StQUQsm@"0*+"eS,dNK
```
Try it online: [Demonstration](http://pyth.herokuapp.com/?code=VK%2B_StQUQsm%40%220%2A%2B%22eS%2CdNK&input=3&debug=0)
### Explanation:
```
VK+_StQUQsm@"0*+"eS,dNK   implicit: Q = input number
    StQ                   the list [1, 2, ..., Q-1]
   _                      reverse it [Q-1, ..., 2, 1]
       UQ                 the list [0, 1, ..., Q-1]
  +                       combine them [Q-1, ..., 1, 0, 1, ..., Q-1]
 K                        and store in K
VK                        for each N in K:
          m           K      map each element d in K to:
                 eS,dN          the maximum of d and N
           @"0*+"               and pick the corresponded char (modulo 3)
         s                   join the chars to a string and print
```
[Answer]
# MATLAB, ~~80~~ ~~78~~ 73 bytes
## Thanks Luis Mendo for helping me shave 5 bytes!
```
A=eye(2*input('')-1);a='0*+';a(mod(bwdist(A.*rot90(A),'chessboard'),3)+1)
```
# Example
```
>> A=eye(2*input('')-1);a='0*+';a(mod(bwdist(A.*rot90(A),'chessboard'),3)+1)
5
ans =
*********
*0000000*
*0+++++0*
*0+***+0*
*0+*0*+0*
*0+***+0*
*0+++++0*
*0000000*
*********
```
# Ungolfed and Code Explanation
```
%// Accepts an integer n from the user and creates a 2*n - 1 x 2*n - 1 identity matrix
A=eye(2*input('')-1);
%// Creates an array of three characters to print each level of the ring
a='0*+';
%// By taking the identity matrix and element-wise multiplying with its 90 degree rotated 
%// version of itself, this creates a zero matrix except for the centre most
%// value, which is 1
%// This takes the distance transform via the chessboard / Chebyshev distance
%// from the centre element
%// This mirrors what "level" each square would be at
%// 1: https://en.wikipedia.org/wiki/Distance_transform
%// 2: https://en.wikipedia.org/wiki/Chebyshev_distance
b = bwdist(A.*rot90(A),'chessboard');
%// Because each level cycles through each of the characters in the
%// character array a, we need to perform a mod operation so that
%// all of the values cycle from 1 to 3
%// This changes the distance transform output so that we range
%// from 1 to 3 instead
c = mod(b,3) + 1;
%// The values in the matrix c correspond exactly to the locations
%// we need to sample from the array a and we display our result
a(c)
```
# Minor Note
[`bwdist`](http://www.mathworks.com/help/images/ref/bwdist.html) is a function that's part of the image processing toolbox, and can only be run in MATLAB. Octave (IIRC) does not have `bwdist` implemented yet so this can't be run in Octave.
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 15 14 bytes
```
ＦＮ«Ｂ⊕⊗ι§0*+ιＭ↖
```
[Try it online!](https://tio.run/##AS0A0v9jaGFyY29hbP//77ym77yuwqvvvKLiipXiipfOucKnMCorzrnvvK3ihpb//zU)
## explanation
```
ＦＮ                 #start a for loop, iterating n (input) times
   «                 #the loop contains 2 expressions so a body is opened
    Ｂ               #draw a box
      ⊕⊗ι          #size of box is 2*i+1
           §0*+ι     #character of the box is "0*+" index i
                Ｍ↖  #move up left 1
                     #the result is printed implicitly
```
## 15 bytes
```
ＦＮ«Ｂ⊕×²ι§0*+ιＭ↖
```
Improved version by [Psuedo Nym](https://codegolf.stackexchange.com/users/80383/pseudo-nym) replaced `×²` with `⊗`, the in-built doubled operator.
[Answer]
# [Pyke](https://pyke.catbus.co.uk/docs), 13 bytes
```
0QV"0*+"[[email protected]](/cdn-cgi/l/email-protection)
```
Based on [this excellent Pyke answer on another challenge](https://codegolf.stackexchange.com/a/106757/52210), so make sure to upvote that one as well!
[Try it online.](https://tio.run/##K6jMTv3/3yAwTMlAS1sp38FRL@L/fxMA)
**Explanation:**
```
0              # Start with a "0" in the center
 QV            # Loop the input amount of times:
   "0*+"       #  Push string "0*+"
        o      #  Push index++ (0 by default; and increases by 1 after pushing)
         @     #  And use it to index it into the string (0-based with automatic wraparound)
          A    #  Deep apply the following command:
           .X  #   Surround the string with this character around it
               # (after which the result is output implicitly)
```
[Answer]
# Python 2, 134 bytes
```
def l(x,c=1):
 p="\n\x1b[%d"%c;d=p+";%dH"%c
 if x:s=x*2-1;d+=(p+"G").join(["0*+"[(x+1)%3]*s]*s)+l(x-1,c+1)
 return d
print l(input())
```
[Answer]
# [Perl 5](https://www.perl.org/), 57 bytes
Using the approach from [@xnor's answer](https://codegolf.stackexchange.com/a/57477/9365), please upvote them!
```
//,say map{qw(0 * +)[max(abs,abs$')%3]}@;for@;=- --$_..$_
```
[Try it online!](https://tio.run/##K0gtyjH9/19fX6c4sVIhN7GgurBcw0BBS0FbMzo3sUIjMalYB4hV1DVVjWNrHazT8oscrG11FXR1VeL19FTi//83@5dfUJKZn1f8Xzfvv66vqZ6hgZ4BkOGTWVxiZRVakpmjDTQIAA "Perl 5 – Try It Online")
[Answer]
# Matlab 92
```
input('')-1;x=ones(2*n+1,1)*abs(-n:n);z=mod(max(x,x'),3);z(z>1)=2;z(z<1)=7;disp([z+41,''])
```
[Answer]
# Sed, ~~277~~ 252 characters
(251 character code + 1 character command line option.)
Expects input in [unary](http://meta.codegolf.stackexchange.com/questions/5343/can-numeric-input-output-be-in-unary) format.
```
:m
s/1/0/
s/1/*/
s/1/+/
tm
h
s/^/:/
:r
s/(.*):(.)/\2\1:/
tr
s/://
G
s/\n.//
h
:
/^(.)\1*$/ba
s/(.)(.)(\2*)\1/\1:\2\3:\1/
:c
s/(:_*)[^_](.*:)/\1_\2/
tc
:u
s/(.)(:\1*)_/\1\2\1/
tu
s/://g
H
b
:a
g
s/[^\n]+/:/
:f
s/(.*):(\n[^\n]+)/\2\1:/
tf
s/://
G
s/\n//
```
Sample run:
```
bash-4.3$ sed -rf treering.sed <<< 1
0
bash-4.3$ sed -rf treering.sed <<< 11
***
*0*
***
bash-4.3$ sed -rf treering.sed <<< 111
+++++
+***+
+*0*+
+***+
+++++
bash-4.3$ sed -rf treering.sed <<< 1111
0000000
0+++++0
0+***+0
0+*0*+0
0+***+0
0+++++0
0000000
```
[Answer]
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/Powershell), 68 bytes
```
$f={($l=($c='+0*'[$_--%3])+"$c$c"*$_)
if($_){&$f $_|%{"$c$_$c"}
$l}}
```
[Try it online!](https://tio.run/##K8gvTy0qzkjNyfn/XyXNtlpDJcdWQyXZVl3bQEs9WiVeV1fVOFZTW0klWSVZSUslXpMrM00DSFWrqaQpqMTXqFaDpOKBkrVcKjm1tf8N9fRMQaKO6alAeSVriDprdfXa/wA "PowerShell – Try It Online")
Unrolled:
```
$f={
    $_--
    $char='+0*'[$_%3]
    $line=$char+"$char$char"*$_
    Write-Output $line
    if($_){
        &$f $_|ForEach-Object{
            Write-Output "$char$_$char"
        }
        Write-Output $line
    }
}
```
[Answer]
# [Canvas](https://github.com/dzaima/Canvas), 15 [bytes](https://github.com/dzaima/Canvas/blob/master/files/chartable.md)
```
Ｈ0*+＠¹２×╷：＊；２２╋
```
[Try it here!](https://dzaima.github.io/Canvas/?u=JXVGRjI4MCorJXVGRjIwJUI5JXVGRjEyJUQ3JXUyNTc3JXVGRjFBJXVGRjBBJXVGRjFCJXVGRjEyJXVGRjEyJXUyNTRC,i=MTY_,v=8)
Can probably be shortened further.
## Explanation
```
H0*+@¹2×|:*;22╋
H               push an empty art object, start a loop using input
 0*+            string "0*+"
    @           get the nth element, circularly <-----------+
     ¹          loop iteration                              |
      2×        double it                                   |
        |       decrement it                                |
         :      duplicate it                                |
          *     use that to box the character from here ----+
           ;    swap the box with the previous iteration
            22╋ overlap at (2,2) 
```
[Answer]
# [Japt](https://github.com/ETHproductions/japt) [`-h`](https://codegolf.meta.stackexchange.com/a/14339/), 20 [bytes](https://en.wikipedia.org/wiki/ISO/IEC_8859-1)
```
Ñ ÆP=Õû"0*+"gX=z)XÑÄ
```
[Try it](https://petershaggynoble.github.io/Japt-Interpreter/?v=1.4.6&flags=LWg&code=0SDGUD3V%2byIwKisiZ1g9eilY0cQ&input=NA) or [run all test cases](https://petershaggynoble.github.io/Japt-Interpreter/?v=1.4.6&code=0SDGUD3V%2byIwKisiZ1g9eilY0cQ&footer=UmlVzA&input=WzEsMiwzLDRdCi1tUg)
```
Ñ ÆP=Õû"0*+"gX=z)XÑÄ     :Implicit input of integer U
Ñ                        :U*2
  Æ                      :Map each X in the range [0,U*2)
   P=                    :  Reassign to P (initially the empty string)
     Õ                   :  Transpose P
      û                  :  Centre pad with
       "0*+"             :    Literal string
            g            :    Get character at 0-based index
             X=          :      Reassign to X
               z         :      X floor divided by 2
                )        :    End get
                 XÑÄ     :    To length X*2+1
```
[Answer]
# JavaScript (ES6), 114
Using alert for output - bad proportional font and the result is ugly. In the snippet below the alert is redirect to the snipped body, giving a better result.
The newline inside backticks is significant and counted.
Test running the snippet in Firefox.
```
/* Redefine alert for testing purpose */ alert=x=>O.innerHTML=x;
[...'*+0'.repeat(n=prompt()-1)].map((c,i)=>i<n?b=[z=c.repeat(i-~i),...b,z].map(r=>c+r+c):0,b=[0]);alert(b.join`
`)
```
```
<pre id=O></pre>
```
[Answer]
# Ruby, 85 characters
```
puts (m=0..(n=gets.to_i-1)*2).map{|i|m.map{|j|"0*+"[[(i-n).abs,(j-n).abs].max%3]}*""}
```
Sample run:
```
bash-4.3$ ruby -e 'puts (m=0..(n=gets.to_i-1)*2).map{|i|m.map{|j|"0*+"[[(i-n).abs,(j-n).abs].max%3]}*""}' <<< 4
0000000
0+++++0
0+***+0
0+*0*+0
0+***+0
0+++++0
0000000
```
[Answer]
# Moonscript - 104 bytes
```
m=io.read!
n=2*m-1
for y=1,n
 io.write ({'0','*','+'})[(math.max y-m,x-m,m-y,m-x)%3+1]for x=1,n
 print!
```
[Answer]
# C, 138 bytes
```
j,k,l;t(i){l=2*i;char*c=calloc(l,l);memset(c,10,l*(l-2));for(;k<i;++k)for(j=k;j<l-1-k;)memset(c+j++*l+k,"+0*"[(i-k)%3],l-2*k-1);puts(c);}
```
Function `t` taking one integer parameter - the age.
Ungolfed (with `main` function to easily run the above one):
```
#include "stdlib.h" /* calloc - only necessary for 64-bit system */
j,k,l;t(i)
{
    l=2*i;
    char*c=calloc(l,l);
    memset(c,10,l*(l-2)); /* fill with '\n' */
    for(;k<i;++k)for(j=k;j<l-1-k;)memset(c+j++*l+k,"+0*"[(i-k)%3],l-2*k-1);
    puts(c);
}
main(int c,char**v)
{
    t(atoi(v[1]));
}
```
The `stdlib.h` may be necessary on some systems, because without it the return type of the undeclared function `calloc` would default to `int`. Because `int` and `char*` are not necessarily of same size, an invalid pointer could be written into `c`. In most 32-bit systems both `char*` and `int` have same size, but this is not true for 64-bit systems.
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), 23 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
0¸sG…0*+Nè©δ.ø®N·>×.ø}»
```
[Try it online](https://tio.run/##yy9OTMpM/f/f4NCOYvdHDcsMtLT9Dq84tPLcFr3DOw6t8zu03e7wdCCz9tDu//9NAA) or [verify a few more test cases](https://tio.run/##yy9OTMpM/R/iquSZV1BaYqWgZO@nw6XkX1oC4en4/Tc4tKPY/VHDMgMtbb/DKw6tPLdF7/COQ@v8Dm23OzwdyKw9tPu/zqFt9v8B).
**Explanation:**
```
0¸                     # Start with a 0 wrapped in a list as the center: [0]
  sG                   # Loop `N` in the range [1, input):
    …0*+               #  Push string "0*+"
        Nè             #  Use `N` to index into this string
                       #  (0-based with automatic wraparound)
          ©            #  Store this character in variable `®` (without popping)
           δ.ø         #  Surround each line with this character
               N·>     #  Push 2 * `N` + 1
              ®   ×    #  Repeat the character `®` that many times as string
                   .ø  #  And surround the list with this string
   }»                  # After the loop: join all strings by newlines
                       # (after which the resulting string is output implicitly as result)
```
[Answer]
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/Powershell), 118 bytes
```
param($n)((--$n..0+1..$n|%{-join(($z=($x='0*+'*$n)[$n..$_])+"$($x[$_])"*2*$_+($z[($n-$_-1)..0],'')[$n-eq$_])}),0)[!$n]
```
[Try it online!](https://tio.run/##Fc1LDoIwGATgPadAMtoXbcDEleEkTdOwgKiBgrjQiD17/bubZL7MrMt72F63YZoSxm5Pa7/1M0cQnGuNYEyjWmMQfsddP5Z74BzfjuPTsUYqJgnarOCdUBWosDlW8izhFVlLWxpet4KmXM1Y9np4ZhVF3Qh7QHApFgXdXOjlhLGEv5aMxfQH "PowerShell – Try It Online")
:(
[Answer]
# [J](http://jsoftware.com/), 22 bytes
```
'0*+'{~3|>./~&:|@i:@<:
```
[Try it online!](https://tio.run/##y/qvpKeepmBrpaCuoKNgoGAFxLp6Cs5BPm7/1Q20tNWr64xr7PT069SsahwyrRxsrP5rcnGlJmfkK6QpGEIY6uowASN0AWN0AZP/AA "J – Try It Online")
]