Drehe ein chinesisches Schachbrett

19

Ein chinesisches Schachbrett sieht folgendermaßen aus (basierend auf dieser Frage , diesmal jedoch mit einer festen Größe):

            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

Jedes Nicht-Leerzeichen in diesem Beispiel kann durch ein nicht-Leerzeichen-druckbares ASCII-Zeichen in der Eingabe ersetzt werden, während Leerzeichen niemals geändert werden. Es wird nicht garantiert, dass es sich um ein gültiges Arrangement in Chinese Checker handelt (da es möglicherweise nicht genau 7 verschiedene Arten von Zeichen enthält).

Ihre Aufgabe ist es, es um ein Vielfaches von 60 Grad zu drehen.

Dies ist das obige Beispiel, das um 60 Grad im Uhrzeigersinn gedreht wurde:

            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

Die Eingabe ist eine nicht negative Ganzzahl und ein chinesisches Schachbrett. Ihr Programm (oder Ihre Funktion) sollte es um die ganze Zahl * 60 Grad drehen. Sie entscheiden, ob Sie im oder gegen den Uhrzeigersinn drehen möchten, sofern dies konsistent ist. Sowohl die Eingabe als auch die Ausgabe sollten keine zusätzlichen führenden oder nachfolgenden Leerzeichen enthalten.

Das ist Code-Golf. Kürzester Code gewinnt.

jimmy23013
quelle

Antworten:

16

CJam, 61 59 43 40 38 36 Bytes

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

Dies ist eine anonyme Funktion, die eine Zeichenfolge und eine Ganzzahl auf dem Stapel erwartet.

Vielen Dank an @ jimmy23013 für das Abschlagen von 19 Byte.

Probieren Sie es online im CJam-Interpreter aus .

Idee

Wir können den druckbaren Zeichen der Schachbretter eine Reihenfolge zuweisen, indem wir sie nach Osten und dann nach Süden lesen.

Auf diese Weise wird das Original und das Schachbrett gedreht

            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            

werden

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

und

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

beziehungsweise.

Wir können die zweite Sequenz im ersten Schachbrett finden, indem wir die Zeichen in nordöstlicher Richtung und dann in südöstlicher Richtung lesen.

Um dies im Code zu erreichen, stellen wir zunächst n - 1 Leerzeichen vor die n- te Zeile des Schachbretts (siehe Abbildung links). Dann kehren wir die Reihenfolge der Zeilen um (siehe rechts).

            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                        

Zuletzt transponieren wir Zeilen mit Spalten:

                 ​



            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

Das Leerzeichen ist überall, aber die druckbaren Zeichen sind in der richtigen Reihenfolge, wenn wir sie nach Osten und dann nach Süden lesen.

Sie müssen lediglich das n- te druckbare Zeichen des ursprünglichen Schachbretts durch das n- te druckbare Zeichen der letzten Änderung ersetzen .

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
quelle
_,,Sf*\.+W%ze_.
Jimmy23013
@ jimmy23013: Viel besser als mein Sortieransatz. Vielen Dank!
Dennis
liq{_N/eeSf.*W%:szsS-\{_' >{;(}&\}/;]}@*, aber ich dachte daran, mich um 60 Grad zu drehen, nicht um 45 Grad, als ich diese Herausforderung schrieb ...
jimmy23013
@ Jimmy23013: Wow, danke! Ich habe versucht, einen anderen Ansatz, aber qN/(i{_eeSf.*W%:szSf-{},.{' f+sW<\,' e[}}*N*ist noch länger als das, was ich vorher hatte ...
Dennis
11

Python 2, 171 Bytes

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

Dies ist vielleicht das einzige Mal, dass ich jemals für str.splitlinesnützlich befunden habe - für alle anderen Zeiten .split("\n")ist es kürzer.

Verwenden Sie wie f(S,10).

Erläuterung

Für jedes Zeichen in der Eingabe haben wir entweder:

  • Behalten Sie es, wenn es ein Leerzeichen oder ein Zeilenumbruch ist, oder
  • Ersetzen Sie es ansonsten durch das richtige Zeichen

Um herauszufinden, durch welches Zeichen ersetzt werden soll, konvertieren wir das Gitter in Würfelkoordinaten (x, y, z) , drehen die nZeiten durch Transformieren (x, y, z) -> (-y, -z, -x)und konvertieren sie dann zurück.

Sp3000
quelle