Chińska szachownica

21

Gra w chińskie warcaby rozgrywana jest na planszy ze spacjami w kształcie sześcioramiennej gwiazdy:

Obraz płyty

Zdjęcie z Wikipedii

Możemy stworzyć ASCII-graficzną reprezentację tej tablicy, używając .pustych miejsc i liter GYORPBdla sześciu kolorowych początkowych lokalizacji:

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

Aby było bardziej interesująco, możemy również zmienić rozmiar. Zmierzymy rozmiar deski na podstawie długości boków jej trójkątnych początkowych lokalizacji: deska powyżej ma rozmiar 4.

Ponieważ pisanie tego wszystkiego ręcznie jest bardzo trudne, napiszmy program (lub funkcję), aby to zrobić!

Detale

Twój kod powinien przyjmować dodatnią liczbę całkowitą reprezentującą rozmiar płytki, poprzez STDIN, ARGV lub argument funkcji. Wyjście wzoru szachownicy do STDOUT (możesz naprzemiennie zwrócić go jako ciąg, jeśli przesłanie jest funkcją).

Wyjście musi albo

  • nie mają żadnych spacji końcowych, lub
  • mieć dokładnie tyle spacji końcowych, aby wypełnić wzór do idealnego prostokąta o szerokości 6 * N + 1.

Wyjście może opcjonalnie mieć końcowy znak nowej linii. Żadne inne dodatkowe (wiodące, końcowe) białe znaki nie są dozwolone.

Przykłady

Rozmiar 1:

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

Rozmiar 2:

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

Rozmiar 4:

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

Punktacja

To jest : wygrywa najkrótszy kod w bajtach.

DLosc
źródło
Czy dane wyjściowe mogą zawierać puste wiersze spacji przed i po?
xnor
Powiem nie.
DLosc
Wspominałeś o końcach spacji, ale co z wiodącymi spacjami? Czy obraz musi być wyrównany do lewej, czy może ma taką samą liczbę początkowych spacji w każdej linii?
Sp3000,
Spłucz w lewo, jak pokazano na przykładowym wyjściu.
DLosc
Czy mogą być spacje poza prawą krawędzią, ale nadal tworzą prostokąt?
xnor

Odpowiedzi:

2

Ruby, 141 127

Zwraca ciąg prostokątny

->n{(-2*n..2*n).map{|i|j=i.abs
k=j>n ?0:j 
(([i>0??P:?B]*k+[j>n ?i>0??R:?G:?.]*(2*n+1-j)+[i>0??O:?Y]*k)*" ").center(6*n+1)}*$/}

Niegolfowany w programie testowym

f=->n{
  (-2*n..2*n).map{|i|                    #Iterate rows from -2*n to 2*n
    j=i.abs                              #Absolute value of i
    k=j>n ?0:j                           #Value of j up to n: for PBYO
    (                                    #An array of characters forming one line
      ([i>0??P:?B]*k+                    #B or P * (k=j or 0 as appropriate)
       [j>n ?i>0??R:?G:?.]*(2*n+1-j)+    #R,G or . * (2*n+1-j) to form centre diamond
       [i>0??O:?Y]*k                     #O or Y * (k=j or 0 as appropriate)
      )*" "                              #Concatenate the array of characters into a string separated by spaces.
    ).center(6*n+1)                      #pad the string to the full width of the image, adding spaces as necessary.
  }*$/                                   #Concatenate the array of lines into a string separated by newlines.
}

puts f[gets.to_i]
Level River St
źródło
8

Python 2, 140 bajtów

n=input()
for k in range(4*n+1):x=abs(k-2*n);y=2*n-x;p,q,r=" BP G..R YO "[(k-~k)/(n-~n)::4];print(" "*y+" ".join(p*x+q*-~y+r*x)+" "*y)[n:-n]

Nie wspaniale, ale oto moja wstępna oferta.

Reguły białych znaków dodały wiele bajtów. Dla porównania, oto 120-bajtowy program Python 3, który jest poprawny tylko wizualnie i nie przestrzega reguł białych znaków:

def f(n):
 for k in range(4*n+1):x=abs(k-2*n);y=2*n-x;p,q,r=" BP G..R YO "[(k-~k)//(n-~n)::4];print(" "*y,*p*x+q*-~y+r*x)

A oto moja nieco dłuższa rekurencyjna 149-bajtowa próba Python 3:

def f(n,k=0):x=2*n-k;s=" ".join(["B"*x+"."*-~k+"Y"*x,"G"*-~k][k<n]).center(6*n+1);print(s);k<n*2and[f(n,k+1),print(s.translate({71:82,66:80,89:79}))]
Sp3000
źródło
7

Python 2, 152

n=input();x=N=2*n
while~N<x:s='';y=n*3;exec"a=x+y;q=[0,a>N,x-y>N,-x>n,-a>N,y-x>N,x>n,1];s+=' BYROPG.'[q.index(sum(q)<~a%2*3)];y-=1;"*(y-~y);print s;x-=1

Z perspektywy czasu jest to niewłaściwe podejście do Pythona, ale zamieszczam je tutaj, na wypadek, gdyby ktoś mógł z niego skorzystać. Zamiast wyjaśniać ten bałagan kodu, postaram się wyrazić pomysł, który za tym stoi.

Chodzi o to, aby używać trójkątne współrzędnych , w którym trójkątny krata odpowiada całkowitą trzyosobowe (a,b,c)z a+b+c=0.

wprowadź opis zdjęcia tutaj

(Tutaj punkty sieci są rysowane jako sześciokąty.)

Możemy przekształcić współrzędne kartezjańskie na trójkątne jako

a = (x+y)/2
b = (x-y)/2
c = -x

zauważając to xiy musi mieć tę samą parzystość, w przeciwnym razie jest poza szachownicą i powinniśmy wydrukować spację.

We współrzędnych trójkątnych linie ograniczające gwiazdy sześciokątnej mają równania: a==n, b==n, c==n, a==-n, b==-n, c==-n .

Możemy więc określić, w jakim regionie jesteśmy, o który z nich [a,b,c,-a,-b,-c]jest większy niż n.

  • Jeśli nie ma, jesteśmy w centrum i drukujemy kropkę.
  • Jeśli dokładnie jest jeden, znajdujemy się w jednym z sześciu zewnętrznych trójkątów i wypisujemy literę odpowiadającą indeksowi.
  • Jeśli są dwa lub więcej, jesteśmy poza planszą i wydrukujemy spację.

Prostokąt ograniczający wymaga, abyśmy to robili xw zamkniętym przedziale [-2 * n, 2 * n] oraz yw zamkniętym przedziale [-3 * n, 3 * n].

xnor
źródło
Kod nie działa dla mnie.
BadAtGeometry
@BadAtGeometry To działa dla mnie .
xnor
Jakiej wersji używasz?
BadAtGeometry
@BadAtGeometry TIO używa wersji 2.7.15 . Co się stanie, gdy go uruchomisz?
xnor
7

Siatkówka , 234 bajty

.
P
.+
iP$0$0x$0j$0x$0Px$0kqw
P(?=P*xP*j)
s
P(?=P*j)
R
P(?=P*xP*k)
c
P(?=P*k)
O
x

+`i(s+R+)R
is$1#$1R
+`(s*)P(P*c*)(O*)O(?=k)
$0#s$1$2c$3
j|k
#
s

+`([^#]+#)q(.*)
q$1$2$1
R(?=.*w)
G
P(?=.*w)
B
O(?=.*w)
Y
w[^#]*#|q|i

\w
$0 
c
.
 #
#

Pobiera dane wejściowe jednoargumentowe.

Każda linia powinna przejść do własnego pliku i #powinna zostać zmieniona na nową linię w pliku. Jest to niepraktyczne, ale możesz uruchomić kod tak jak plik z -sflagą, zachowując #znaczniki i być może zmieniając je na znaki nowej linii w celu zwiększenia czytelności, jeśli chcesz.

Kod ma minimalną złożoność wyrażeń regularnych. Główne etapy generacji to:

  • Utwórz ostatni Gwiersz i pierwszy B.Ywiersz (rozdzielone znacznikami ijki rzeczywistymi użytymi letletamiRPO ).
  • Duplikuj najwyższą Glinię ze spacją plus minus G, aż będzie tylko jeden G.
  • Duplikuj dolną B.Ylinię za pomocą spacji plus kropki, minus a Bi Ydopóki nie będzie żadnych znaków Bi nie Ypozostanie.
  • Skopiuj wszystkie wiersze w odwrotnej kolejności po bieżącym ciągu (za pomocą znacznika q). Trzymamy marker ( w) na środku.
  • Zmieniamy litery, RPOaby GBYznajdowały się przed znacznikiem.
  • Dodaj brakujące spacje.

Wyniki po każdym z powyższych punktów (ograniczonych przez ='s) dla danych wejściowych 1111 (unary 4):

1111
==============================
isssssssssRRRRjPPPPcccccOOOOkqw
==============================
issssssssssssR
sssssssssssRR
ssssssssssRRR
sssssssssRRRRjPPPPcccccOOOOkqw
==============================
issssssssssssR
sssssssssssRR
ssssssssssRRR
sssssssssRRRRjPPPPcccccOOOO
sPPPccccccOOO
ssPPcccccccOO
sssPccccccccO
ssssccccccccckqw
==============================
qi            R
           RR
          RRR
         RRRR
PPPPcccccOOOO
 PPPccccccOOO
  PPcccccccOO
   PccccccccO
    ccccccccc
w    ccccccccc
   PccccccccO
  PPcccccccOO
 PPPccccccOOO
PPPPcccccOOOO
         RRRR
          RRR
           RR
i            R
==============================
qi            G
           GG
          GGG
         GGGG
BBBBcccccYYYY
 BBBccccccYYY
  BBcccccccYY
   BccccccccY
    ccccccccc
w    ccccccccc
   PccccccccO
  PPcccccccOO
 PPPccccccOOO
PPPPcccccOOOO
         RRRR
          RRR
           RR
i            R
==============================
            G
           G G
          G G G
         G G G G
B B B B . . . . . Y Y Y Y
 B B B . . . . . . Y Y Y
  B B . . . . . . . Y Y
   B . . . . . . . . Y
    . . . . . . . . .
   P . . . . . . . . O
  P P . . . . . . . O O
 P P P . . . . . . O O O
P P P P . . . . . O O O O
         R R R R
          R R R
           R R
            R
randomra
źródło
4

JavaScript ( ES6 ) 228

Linia konstrukcyjna po linii. Niewiarygodnie długi w porównaniu do @ Sp3000, który robi to samo.

Używanie ciągu szablonu do zapisania kolejnych 3 bajtów dla znaków nowej linii. Wszystkie nowe linie są znaczące i liczone.

f=w=>(i=>{r=(n,s=b=' ')=>s.repeat(n),l=c=>(c='GBYPOR'[c])+r(i,b+c),t=n=>r(w*3-i)+l(n)+`
`,s=n=>r(w-1-i)+l(n)+b+r(w+w-i,'. ')+l(n+1)+`
`;for(o='',q=r(w)+r(w+w,'. ')+`.
`;++i<w;o+=t(0))q+=s(3);for(;i--;o+=s(1))q+=t(5)})(-1)||o+q

// LESS GOLFED

u=w=>{
  r =(n,s=b=' ') => s.repeat(n),
  l = c => (c='GBYPOR'[c])+r(i, b+c),
  t = n => r(w*3-i) + l(n) + '\n',
  s = n => r(w-1-i) + l(n) + b + r(w+w-i,'. ') + l(n+1) + '\n',
  o = '',
  q = r(w) + r(w+w,'. ') + '.\n';
  for(i=0; i<w; i++)
    o += t(0), q += s(3);  
  for(;i--;)
    o += s(1), q += t(5);
  return o+q
}  

go=()=> O.innerHTML=f(I.value|0)

go()
<input id=I value=5><button onclick='go()'>-></button><br>
<pre id=O></pre>

edc65
źródło