Girar um mosaico de diamantes

21

Qualquer hexágono comum pode ser lado a lado com diamantes, por exemplo, assim (roubado desta pergunta ):

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

Consideraremos o tamanho acima como um ladrilho do tamanho 1 (já que os lados dos diamantes são feitos de um / ou \ cada). O mesmo lado a lado do tamanho 2 seria semelhante a:

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

Sua tarefa é girar as inclinações de diamante em um múltiplo de 60 graus. O mosaico de diamantes na entrada pode ter qualquer tamanho (e o tamanho não está especificado explicitamente na entrada). Mas sempre seria um ladrilho válido e todos os lados do hexágono teriam o mesmo comprimento.

Estes são os exemplos acima girados 60 graus no sentido horário:

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

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

A entrada é um número inteiro não negativo e um mosaico de diamantes. Seu programa (ou função) deve girá-lo pelo número inteiro * 60 graus. Você decide se gira no sentido horário ou anti-horário, desde que seja consistente. Tanto a entrada como a saída não devem ter espaços iniciais ou finais extras.

Isso é código-golfe. O menor código vence.

Perguntas relacionadas:

jimmy23013
fonte
12
Martin vai ficar com ciúmes!
Optimizer

Respostas:

3

Pitão, 81 bytes

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

Experimente online

Gira no sentido anti-horário.

Cada rotação de 60 ° é realizada usando o seguinte algoritmo. Suponha que a entrada seja um hexágono da ordem k , portanto, possui 2⋅ k + 1 linhas e 4⋅ k colunas. Para encontrar o caractere girado na linha i coluna j , deixe

  • u = i + j - k
  • v = j - 3⋅ i + 5⋅ k

Então o caractere de saída é

  • \, se a entrada tiver /na linha ( u + 1) / 2 coluna ( v + 1) / 2; outro
  • /, se a entrada tiver _na linha u / 2 coluna v / 2 ou linha u / 2 coluna ( v + 2) / 2; outro
  • _, se a entrada tiver \na linha ( u + 2) / 2 coluna v / 2 ou na linha ( u + 1) / 2 coluna ( v - 1) / 2; outro
  • espaço.

(Não contamos caracteres com índices de meio inteiro.)

Anders Kaseorg
fonte
Eu acho que você pode garantir quais posições têm \ s, são apenas as _que você precisa verificar nos dois lugares.
Neil
@ Neil Sim, você sabe onde \ estão, mas pode ter que desenhar dois _para cada um \ .
Anders Kaseorg
Oh, você verifica cada sublinhado separadamente?
Neil
3

JavaScript (ES6), 452 356 315 bytes

Onde \nrepresenta o caractere literal de nova linha. Edit: Salvo 96 bytes, percebendo que o meu algoritmo não precisa saber o número e tamanho dos diamantes separadamente, além de alguns pequenos golfinhos que eu perdi na primeira vez. Economizei 41 bytes reorganizando o código para que o destino fosse sempre o mesmo par de caracteres, além de um pequeno golfe que eu perdi ao converter para o meu algoritmo anterior.

Explicação: Considera cada par de caracteres de saída, o que poderia ser __, /_, _\, /ou \, para verificar os caracteres apropriados na entrada que mapeiam para esses caracteres de saída. 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');
}
Neil
fonte