Rotate a diamond tiling Any regular hexagon can be tiled with diamonds, for instance like so (stolen from this question):

   ______
  /_/_/\_\
 /_/\_\/\_\
/\_\/_/\/_/\
\/_/\_\/_/\/
 \_\/_/\_\/
  \_\_\/_/


We'll consider the above a tiling of size 1 (since the diamonds' sides are made of one / or \ each). The same tiling of size 2 would look like:

      ____________
     /   /   /\   \
    /___/___/  \___\
   /   /\   \  /\   \
  /___/  \___\/  \___\
 /\   \  /   /\  /   /\
/  \___\/___/  \/___/  \
\  /   /\   \  /   /\  /
 \/___/  \___\/___/  \/
  \   \  /   /\   \  /
   \___\/___/  \___\/
    \   \   \  /   /
     \___\___\/___/


Your task is to rotate diamond tilings by a multiple of 60 degrees. The diamond tiling in the input can be in any size (and the size is not explicitly specified in the input). But it would always be a valid tiling, and all sides of the hexagon would have the same length.

These are the above examples rotated by 60 degrees clockwise:

   ______
  /_/\_\_\
 /\_\/_/\_\
/\/_/\_\/_/\
\/\_\/_/_/\/
 \/_/\_\_\/
  \_\/_/_/

      ____________
     /   /\   \   \
    /___/  \___\___\
   /\   \  /   /\   \
  /  \___\/___/  \___\
 /\  /   /\   \  /   /\
/  \/___/  \___\/___/  \
\  /\   \  /   /   /\  /
 \/  \___\/___/___/  \/
  \  /   /\   \   \  /
   \/___/  \___\___\/
    \   \  /   /   /
     \___\/___/___/


The input is a non-negative integer and a diamond tiling. Your program (or function) should rotate it by the integer * 60 degrees. You decide whether to rotate clockwise or counterclockwise, as long as it is consistent. Both the input and output shouldn't have extra leading or trailing spaces.

This is code-golf. Shortest code wins.

Related questions:


Rotate a Chinese checkerboard
Rotate a two-dimensional list by 45 degrees
Scale up a Diamond Tiling
JavaScript (ES6), 452 356 315 bytes

Where \n represents the literal newline character. Edit: Saved 96 bytes by realising that my algorithm doesn't need to know the number and size of diamonds separately, plus a few minor golfs that I missed the first time around. Saved 41 bytes by rearranging the code so that the destination was always the same pair of characters, plus a minor golf that I missed when converting to my previous algorithm.



r=
(s,n)=&gt;(z=s.search`_`,l=(f,n=z*2+1)=&gt;[...Array(n)].map(f),a=s.split`\n`,l(_=&gt;(o=a.map(s=&gt;[...s].fill` `),l((_,r)=&gt;l((_,c)=&gt;(d=z+c*2-r,a[s=z+r-c]&amp;&amp;(a[s][r+c]=='/'?o[r][d]=o[r][d+1]='_':0,a[s][r+c-1]=='\\'?o[r][d]='/':0),a[--s]&amp;&amp;(a[s][r+c]==`_`||a[s][r+c-1]==`_`?o[r][d+1]=`\\`:0)))),a=o.map(a=&gt;a.join``)),n),a.join`\n`)
;
&lt;pre id=i1&gt;
   ______
  /_/_/\_\
 /_/\_\/\_\
/\_\/_/\/_/\
\/_/\_\/_/\/
 \_\/_/\_\/
  \_\_\/_/
&lt;/pre&gt;
&lt;input type=button value="Rotate!" onclick="i1.textContent = r(i1.textContent, 1)"&gt;
&lt;pre id=i2&gt;
      ____________
     /   /   /\   \
    /___/___/  \___\
   /   /\   \  /\   \
  /___/  \___\/  \___\
 /\   \  /   /\  /   /\
/  \___\/___/  \/___/  \
\  /   /\   \  /   /\  /
 \/___/  \___\/___/  \/
  \   \  /   /\   \  /
   \___\/___/  \___\/
    \   \   \  /   /
     \___\___\/___/
&lt;/pre&gt;
&lt;input type=button value="Rotate!" onclick="i2.textContent = r(i2.textContent, 1)"&gt;




Explanation: Considers each pair of output characters, which could be __, /_, _\, / or \, checking for the appropriate characters in the input which map to those output characters. Ungolfed:

function rotate(str, num) {
  // Measure the size using the indent of the _ in the first row.
  var size = str.indexOf('_');
  var arr = str.split('\n');
  while (num--) {
    // We build a character array to represent the output by turning the
    // input into a nested array and replacing everything with spaces.
    // Note that the output will have any trailing spaces from the input.
    var res = arr.map(s =&gt; Array.from(s).fill(' '));
    // Loop over a diamond that encloses the hexagon.
    for (var destrow = 0; destrow &lt;= size * 2; destrow++) {
      for (var col = 0; col &lt;= size * 2; col++) {
        var destcol = size + col * 2 - destrow;
        var srcrow = size + destrow - col;
        var srccol = destrow + col;
        // Map / to __, \ to / and __ to \.
        // We write __ first in case it gets overwritten by / or \.
        if (arr[srcrow]) {
          if (arr[srcrow][srccol] == '/') {
            res[destrow][destcol] = res[destrow][destcol + 1] = '_';
          }
          if (arr[srcrow][srccol - 1] == '\\') {
            res[destrow][destcol] = '/';
          }
        }
        // Need to check both positions in case one was overwritten.
        if (arr[srcrow - 1] &amp;&amp;
            (arr[srcrow - 1][srccol] == '_' || arr[srcrow - 1][srccol - 1] == '_')) {
          res[destrow][destcol + 1] = '\\';
        }
      }
    }
    arr = res.map(a =&gt; a.join(''));
  }
  return arr.join('\n');
}