Faire pivoter un damier chinois

19

Un damier chinois ressemble à ceci (basé sur cette question , mais cette fois il a une taille fixe):

            G
           . G
          G G G
         G G . G
B B B B . . Y G . Y . Y Y
 B B B . . G . . . Y Y Y
  B . B . . . . . Y . Y
   B . . . . . . . . Y
    . . . . . . . . .
   . P . . . . . O O .
  P P . . . . . . . O O
 P P P . . . R . . O O .
P P P P . . R . . O O O O
         R . R R
          R R R
           R .
            R

Chaque caractère non espace dans cet exemple peut être remplacé par n'importe quel caractère ASCII imprimable non espace dans l'entrée, tandis que les espaces ne sont jamais modifiés. Notez qu'il n'est pas garanti d'être un arrangement valide dans le vérificateur chinois (tel qu'il ne peut pas avoir exactement 7 types de caractères différents).

Votre tâche consiste à le faire pivoter d'un multiple de 60 degrés.

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

            B
           B B
          B B B
         B . B B
P P P . . . B . . G G . G
 P P P P . . . . . G G G
  P P . . . . . G Y . G
   P . . . . . . . G G
    . . . . . . . . .
   R . . . . . . . . Y
  R . R R . . . . Y Y .
 R R R . . . O . . . Y Y
R . R R . . . O . Y Y Y Y
         O O O .
          O O O
           O .
            O

L'entrée est un entier non négatif et un damier chinois. 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.

jimmy23013
la source

Réponses:

16

CJam, 61 59 43 40 38 36 octets

{{_N/eeSf.*:sW%zsS-\{_' >{;(}&+}/}*}

Il s'agit d'une fonction anonyme qui attend une chaîne et un entier sur la pile.

Merci à @ jimmy23013 pour avoir joué au golf sur 19 octets.

Essayez-le en ligne dans l' interpréteur CJam .

Idée

Nous pouvons attribuer un ordre aux caractères imprimables des damiers en les lisant vers l'est, puis vers le sud.

De cette façon, le damier original et tourné

            G                                  B            
           . G                                B B           
          G G G                              B B B          
         G G . G                            B . B B         
B B B B . . Y G . Y . Y Y          P P P . . . B . . G G . G
 B B B . . G . . . Y Y Y            P P P P . . . . . G G G 
  B . B . . . . . Y . Y              P P . . . . . G Y . G  
   B . . . . . . . . Y                P . . . . . . . G G   
    . . . . . . . . .                  . . . . . . . . .    
   . P . . . . . O O .                R . . . . . . . . Y   
  P P . . . . . . . O O              R . R R . . . . Y Y .  
 P P P . . . R . . O O .            R R R . . . O . . . Y Y 
P P P P . . R . . O O O O          R . R R . . . O . Y Y Y Y
         R . R R                            O O O .         
          R R R                              O O O          
           R .                                O .           
            R                                  O            

devenir

G.GGGGGG.GBBBB..YG.Y.YYBBB..G...YYYB.B.....Y.YB........Y..........P.....OO.PP.......OOPPP...R..OO.PPPP..R..OOOOR.RRRRRR.R

et

BBBBBBB.BBPPP...B..GG.GPPPP.....GGGPP.....GY.GP.......GG.........R........YR.RR....YY.RRR...O...YYR.RR...O.YYYYOOO.OOOO.O

respectivement.

On retrouve la deuxième séquence dans le premier damier en lisant ses caractères vers le nord-est, puis vers le sud-est.

Pour y parvenir dans le code, nous commençons par ajouter n - 1 espaces à la n ème ligne du damier (montré à gauche). Ensuite, nous inversons l'ordre des lignes (indiqué à droite).

            G                                                       R        
            . G                                                   R .        
            G G G                                               R R R        
            G G . G                                           R . R R        
    B B B B . . Y G . Y . Y Y                       P P P P . . R . . O O O O
      B B B . . G . . . Y Y Y                       P P P . . . R . . O O .  
        B . B . . . . . Y . Y                       P P . . . . . . . O O    
          B . . . . . . . . Y                       . P . . . . . O O .      
            . . . . . . . . .                       . . . . . . . . .        
            . P . . . . . O O .                   B . . . . . . . . Y        
            P P . . . . . . . O O               B . B . . . . . Y . Y        
            P P P . . . R . . O O .           B B B . . G . . . Y Y Y        
            P P P P . . R . . O O O O       B B B B . . Y G . Y . Y Y        
                      R . R R                       G G . G                  
                        R R R                       G G G                    
                          R .                       . G                      
                            R                       G                        

Enfin, nous transposons des lignes avec des colonnes:

                 ​



            B    

           BB    

          BBB    

         B.BB    

    PPP...B..GG.G

    PPPP.....GGG

    PP.....GY.G

    P.......GG

    .........

   R........Y

  R.RR....YY.

 RRR...O...YY

R.RR...O.YYYY

OOO.

OOO

O.

O

L'espace est partout, mais les caractères imprimables sont dans le bon ordre si nous les lisons vers l'est, puis vers le sud.

Il ne reste plus qu'à remplacer le n ème caractère imprimable du damier d'origine par le n ème caractère imprimable de la dernière modification.

Code

                                   e# Stack: String B, Integer A
{                               }* e# Repeat A times:
 _N/                               e#   Push a copy of B and split it at linefeeds.
    ee                             e#   Enumerate the lines of B.
      Sf.*:s                       e#   Execute S.*s for each line:
                                   e#     [4 "abc"] -> "    abc"
            W%                     e#   Reverse the order of line lines.
              z                    e#   Zip; transpose rows with columns.
               s                   e#   Flatten the arrays of strings.
                S-                 e#   Remove spaces.
                                   e#   This pushes a string L.
                  \{          }/   e#   For each character C in the unmodified B:
                    _' >           e#     Check if C is bigger than ' '.
                        {  }&      e#     If it is:
                         ;(        e#      Discard C and shift out a char from L.
                             +     e#     Append a char (C or from L) to L.
                                   e#  L is B rotated by 60 degrees. Set L := B.
Dennis
la source
_,,Sf*\.+W%ze_.
jimmy23013
@ jimmy23013: Beaucoup mieux que mon approche de tri. Merci!
Dennis
liq{_N/eeSf.*W%:szsS-\{_' >{;(}&\}/;]}@*, mais je pensais à tourner de 60 degrés, pas de 45 degrés lorsque j'écrivais ce défi ...
jimmy23013
@ jimmy23013: Wow, merci! J'essayais une approche différente, mais qN/(i{_eeSf.*W%:szSf-{},.{' f+sW<\,' e[}}*N*c'est encore plus long que ce que j'avais avant ...
Dennis
11

Python 2, 171 octets

def f(S,n):
 o="";E=enumerate;B=S.splitlines(1)
 for r,l in E(B):
  for c,q in E(l):z=r-8;y=6-(z+c)/2;x=-y-z;exec"x,y,z=-y,-z,-x;"*n;o+=q*(q<"!")or B[z+8][12-y+x]
 print o

C'est peut-être la seule fois que j'ai trouvé str.splitlinesutile - pour toutes les autres fois, .split("\n")c'est plus court.

Utilisez comme f(S,10).

Explication

Pour chaque caractère en entrée, nous:

  • Gardez-le s'il s'agit d'un espace ou d'une nouvelle ligne, ou
  • Remplacez-le par le bon caractère sinon

Pour déterminer avec quel caractère remplacer, nous convertissons la grille en coordonnées de cube (x, y, z) , tournons les ntemps en transformant (x, y, z) -> (-y, -z, -x), puis reconvertissons.

Sp3000
la source