Random ASCII Art of the Day #5: Diamond Tilings Mash Up Time!

This is instalment #5 of both my Random Golf of the Day and Optimizer's ASCII Art of the Day series. Your submission(s) in this challenge will count towards both leaderboards (which you can find the linked posts). Of course, you may treat this like any other code golf challenge, and answer it without worrying about either series at all.

Hole 5: Diamond Tilings

A regular hexagon can always be tiled with diamonds like so:



We will use an ASCII art representation of these tilings. For a hexagon of side-length 2, there are 20 such tilings:

   ____     ____     ____     ____     ____     ____     ____     ____     ____     ____  
  /\_\_\   /\_\_\   /\_\_\   /\_\_\   /_/\_\   /_/\_\   /\_\_\   /_/\_\   /_/\_\   /_/\_\ 
 /\/\_\_\ /\/_/\_\ /\/_/_/\ /\/_/\_\ /\_\/\_\ /\_\/_/\ /\/_/_/\ /\_\/\_\ /\_\/_/\ /_/\/\_\
 \/\/_/_/ \/\_\/_/ \/\_\_\/ \/_/\/_/ \/\_\/_/ \/\_\_\/ \/_/\_\/ \/_/\/_/ \/_/\_\/ \_\/\/_/
  \/_/_/   \/_/_/   \/_/_/   \_\/_/   \/_/_/   \/_/_/   \_\/_/   \_\/_/   \_\/_/   \_\/_/ 
   ____     ____     ____     ____     ____     ____     ____     ____     ____     ____  
  /_/_/\   /\_\_\   /_/\_\   /_/_/\   /_/\_\   /_/\_\   /_/_/\   /_/_/\   /_/_/\   /_/_/\ 
 /\_\_\/\ /\/_/_/\ /_/\/_/\ /\_\_\/\ /\_\/_/\ /_/\/_/\ /_/\_\/\ /\_\_\/\ /_/\_\/\ /_/_/\/\
 \/\_\_\/ \/_/_/\/ \_\/\_\/ \/_/\_\/ \/_/_/\/ \_\/_/\/ \_\/\_\/ \/_/_/\/ \_\/_/\/ \_\_\/\/
  \/_/_/   \_\_\/   \_\/_/   \_\/_/   \_\_\/   \_\_\/   \_\/_/   \_\_\/   \_\_\/   \_\_\/ 


Given a side length N, you should generate such a tiling for a hexagon of side length N at random. The exact distribution doesn't matter, but each tiling must be returned with non-zero probability.

For N ≤ 4, your submission must produce a tiling within 1 minute at least 80% of the time and at least 80% of the tilings must potentially be generated within 1 minute. Most approaches won't have to worry about this rule (it's very lenient) - this is just to rule out very naive rejection-based algorithms that generate arbitrary strings until one happens to be a tiling.

You might like to know that the total number of possible tilings for given N can be found in OEIS A008793.

You may write a full program or a function and take input via STDIN (or closest alternative), command-line argument or function argument and produce output via STDOUT (or closest alternative), function return value or function (out) parameter.

You must not output more leading spaces than necessary to align the hexagon (that is the left corner of the hexagon should have no spaces in front of it). Each line may contain up to N trailing spaces (not necessarily consistently, so you could e.g. have a rectangular output, printing the hexagon's bounding box).

This is code golf, so the shortest submission (in bytes) wins. And of course, the shortest submission per user will also enter into the overall leaderboard of the series.

Leaderboards

The first post of each series generates a leaderboard.


Random Golf Leaderboard
ASCII Art Leaderboard


To make sure that your answers show up, please start every answer with a headline, using the following Markdown template:

# Language Name, N bytes


where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

# Ruby, &lt;s&gt;104&lt;/s&gt; &lt;s&gt;101&lt;/s&gt; 96 bytes


(The language is not currently shown, but the snippet does require and parse it, and I may add a by-language leaderboard in the future.)
CJam, 105 bytes

ri:A" __"e*A,2f*:B,[W1]{J+B:):B,{N1$S*"\/"J%A2*4$-:D*
0{;B{_1&amp;!2mr+J*m1e&gt;D(2*e&lt;}%__:)&amp;}g:B{'_t}/+@J+}*}fJ;


Newline added to avoid scrolling. Try it online

Explanation:

This solution starts each line as a zigzag, then places N underscores on it, based on their position on the previous line and a couple of rules. I got this from a series of observations while looking at the output as a plain 2D matrix of characters:


each line has exactly N underscores
the underscores can be replaced with / or \ to make a perfectly repeating zigzag pattern (/\ in the top half, \/ in the bottom half)
underscores can not touch the sides, and can't be adjacent to another underscore
when going to the next line, the position of each underscore changes by -1, 0 or 1
more than that, /_/ can only change by -1 or 0, and \_\ can only change by 0 or 1
for the initial underscore positions we can either use a "_ " pattern or a " _" pattern, both are fine
the above rules are sufficient to obtain all the tilings


So I decided to implement it by keeping the previous underscore positions, modifying them with a random factor (2 choices for each underscore) and repeating until the rules are satisfied. In the process of optimizing, I switched to underscore positions relative to the left side of the hexagon (not including spaces).

ri:A" __"e*       read the input (A) and generate the top line
A,2f*:B           make an array [0 2 4 ... 2A-2] and store in B
                  these are the initial positions for the underscores
,                 B's length = A, used as the initial number of leading spaces
                  let's call it C
[W1]{…}fJ         for J in [-1 1] (top half, bottom half)
  J+              add J to C
  B:):B           increment the underscore positions (adjustment before each half)
  ,{…}*           repeat A times
    N1$S*         add a newline and C spaces
    "\/"J%        take "\/" and reverse it if J=-1 (zigzag pattern)
    A2*4$-:D*     calculate D=A*2-C and repeat the pattern
    0             dummy value (for the next loop)
    {…}g          do-while
      ;B          pop last value and push B
      {…}%        apply block to each item (say x)
        _1&amp;!      duplicate x and calculate !(x&amp;1) (for /_/ vs \_\)
        2mr+      randomly add 0 or 1
        J*m       multiply by J and subtract from x
        1e&gt;       limit the minimum value to 1
        D(2*e&lt;    and the maximum value to 2*(D-1)
      __:)&amp;       check if the modified array has any adjacent values
    :B            store the new positions in B
    {'_t}/        place underscores over the zigzag pattern
    +@J+          bring C to the top and add J to it
;                 pop C


Old "3D" version, 189 bytes:

ri:A" __"e*aA4*S*aA2**+[0-2XXW1]:C;"/\_\\\/_/":D;A3m*{{C2/.f*:.+~
A(2*+:V;A+:U;2{UI+1$1$=4{_V+D4/I=@=t}/t}fI}:F~}/[0Y1WWW]:C;
"/_/\\\_\/":D;AaA*:B;A{A[_{_BI=e&lt;)mr}fI]:B;{BQ={[PQR]F}fR}fQ}fPN*


Try it online