# 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:

• Martin will be so jealous! Commented Jun 25, 2015 at 15:35

# Pyth, 81 bytes

ju.es.e.reh|@s.e.e[yYykZ)bGCa+LV,t-y+k*3Y*5J-+kY/lG2Jc2j406610 4K"_/\\_\\"dKbGQ.z


Try it online

Rotates counterclockwise.

Each 60° rotation is performed using the following algorithm. Suppose the input is a hexagon of order k, so it has 2⋅k + 1 rows and 4⋅k columns. To find the rotated character at row i column j, let

• u = i + jk
• v = j − 3⋅i + 5⋅k

Then the output character is

• \, if the input has / at row (u + 1)/2 column (v + 1)/2; else
• /, if the input has _ at row u/2 column v/2 or row u/2 column (v + 2)/2; else
• _, if the input has \ at row (u + 2)/2 column v/2 or row (u + 1)/2 column (v − 1)/2; else
• space.

(We do not count characters at half-integer indices.)

• I think you can guarantee which positions have \ s, it's just the _s that you have to check in both places.
– Neil
Commented Jul 16, 2016 at 11:27
• @Neil Yes, you know where the \ s are, but you might have to draw two _s for each \ . Commented Jul 16, 2016 at 14:18
• Oh, you check each underscore separately?
– Neil
Commented Jul 16, 2016 at 16:09

## JavaScript (ES6), 452356 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)=>(z=s.search_,l=(f,n=z*2+1)=>[...Array(n)].map(f),a=s.split\n,l(_=>(o=a.map(s=>[...s].fill ),l((_,r)=>l((_,c)=>(d=z+c*2-r,a[s=z+r-c]&&(a[s][r+c]=='/'?o[r][d]=o[r][d+1]='_':0,a[s][r+c-1]=='\\'?o[r][d]='/':0),a[--s]&&(a[s][r+c]==_||a[s][r+c-1]==_?o[r][d+1]=\\:0)))),a=o.map(a=>a.join)),n),a.join\n)
;
<pre id=i1>
______
/_/_/\_\
/_/\_\/\_\
/\_\/_/\/_/\
\/_/\_\/_/\/
\_\/_/\_\/
\_\_\/_/
</pre>
<input type=button value="Rotate!" onclick="i1.textContent = r(i1.textContent, 1)">
<pre id=i2>
____________
/   /   /\   \
/___/___/  \___\
/   /\   \  /\   \
/___/  \___\/  \___\
/\   \  /   /\  /   /\
/  \___\/___/  \/___/  \
\  /   /\   \  /   /\  /
\/___/  \___\/___/  \/
\   \  /   /\   \  /
\___\/___/  \___\/
\   \   \  /   /
\___\___\/___/
</pre>
<input type=button value="Rotate!" onclick="i2.textContent = r(i2.textContent, 1)">

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 => Array.from(s).fill(' '));
// Loop over a diamond that encloses the hexagon.
for (var destrow = 0; destrow <= size * 2; destrow++) {
for (var col = 0; col <= 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] &&
(arr[srcrow - 1][srccol] == '_' || arr[srcrow - 1][srccol - 1] == '_')) {
res[destrow][destcol + 1] = '\\';
}
}
}
arr = res.map(a => a.join(''));
}
return arr.join('\n');
}