Faire pivoter un carrelage diamant

21

Tout hexagone ordinaire peut être carrelé de diamants, par exemple comme ça (volé à cette question ):

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

Nous considérerons ce qui précède comme un carrelage de taille 1 (puisque les côtés des diamants sont constitués d'un / ou \ chacun). Le même pavage de taille 2 ressemblerait à:

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

Votre tâche consiste à faire pivoter les carreaux de diamant d'un multiple de 60 degrés. Le pavage en losanges dans l'entrée peut être de n'importe quelle taille (et la taille n'est pas explicitement spécifiée dans l'entrée). Mais ce serait toujours un pavage valide, et tous les côtés de l'hexagone auraient la même longueur.

Voici les exemples ci-dessus tournés de 60 degrés dans le sens des aiguilles d'une montre:

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

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

L'entrée est un entier non négatif et un pavage en losanges. Votre programme (ou fonction) doit le faire pivoter de l'entier * 60 degrés. Vous décidez de faire pivoter dans le sens horaire ou antihoraire, tant qu'il est cohérent. L'entrée et la sortie ne doivent pas avoir d'espaces de début ou de fin supplémentaires.

C'est du code-golf. Le code le plus court gagne.

Questions connexes:

jimmy23013
la source
12
Martin sera tellement jaloux!
Optimizer

Réponses:

3

Pyth, 81 octets

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

Essayez-le en ligne

Tourne dans le sens antihoraire.

Chaque rotation de 60 ° est effectuée en utilisant l'algorithme suivant. Supposons que l'entrée soit un hexagone d'ordre k , donc elle a 2⋅ k + 1 lignes et 4⋅ k colonnes. Pour trouver le caractère pivoté à la ligne i de la colonne j , laissez

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

Ensuite, le caractère de sortie est

  • \, si l'entrée a /à la ligne ( u + 1) / 2 colonne ( v + 1) / 2; autre
  • /, si l'entrée a _à la colonne u / 2 colonne v / 2 ou à la colonne u / 2 ( v + 2) / 2; autre
  • _, si l'entrée a la \ligne ( u + 2) / 2 colonne v / 2 ou la ligne ( u + 1) / 2 colonne ( v - 1) / 2; autre
  • espace.

(Nous ne comptons pas les caractères aux indices demi-entiers.)

Anders Kaseorg
la source
Je pense que vous pouvez garantir quelles positions ont des \ s, c'est juste les _s que vous devez vérifier aux deux endroits.
Neil
@Neil Oui, vous savez où sont les \ s, mais vous devrez peut-être tirer deux _s pour chacun \ .
Anders Kaseorg
Oh, vous vérifiez chaque trait de soulignement séparément?
Neil
3

JavaScript (ES6), 452 356 315 octets

\nreprésente le caractère de nouvelle ligne littéral. Edit: économisé 96 octets en réalisant que mon algorithme n'a pas besoin de connaître le nombre et la taille des diamants séparément, plus quelques golfs mineurs que j'ai ratés la première fois. Enregistré 41 octets en réorganisant le code afin que la destination soit toujours la même paire de caractères, plus un golf mineur que j'ai manqué lors de la conversion vers mon algorithme précédent.

Explication: considère chaque paire de caractères de sortie, ce qui pourrait être __, /_, _\, /ou \, en vérifiant pour les caractères appropriés dans l'entrée qui mappent à ces caractères de sortie. Non golfé:

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
la source