Kotak-kotak cina

21

Permainan catur Cina dimainkan di papan dengan spasi berbentuk bintang berujung enam:

Gambar papan

Gambar dari Wikipedia

Kita dapat membuat representasi ASCII-art dari papan ini, menggunakan .untuk tempat-tempat kosong dan surat-surat GYORPBuntuk enam lokasi awal berwarna:

            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

Untuk membuatnya lebih menarik, kita juga bisa mengubah ukurannya. Kami akan mengukur ukuran papan dengan panjang sisi dari lokasi awal segitiga: papan di atas adalah ukuran 4.

Karena sangat sulit untuk mengetik semua itu dengan tangan, mari kita menulis sebuah program (atau fungsi) untuk melakukannya!

Detail

Kode Anda harus mengambil bilangan bulat positif yang mewakili ukuran papan, melalui STDIN, ARGV, atau argumen fungsi. Keluarkan pola kotak-kotak ke STDOUT (Anda dapat secara bergantian mengembalikannya sebagai string jika kiriman Anda adalah fungsi).

Output juga harus

  • tidak memiliki spasi sama sekali, atau
  • memiliki cukup ruang trailing yang cukup untuk mengisi polanya menjadi persegi panjang sempurna dengan lebar 6 * N + 1.

Keluaran dapat secara opsional memiliki baris tambahan. Tidak ada spasi putih tambahan (terkemuka, tertinggal) yang diizinkan.

Contohnya

Ukuran 1:

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

Ukuran 2:

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

Ukuran 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

Mencetak gol

Ini adalah : kode terpendek dalam byte menang.

DLosc
sumber
Bisakah output memiliki garis ruang kosong sebelum dan sesudah?
xnor
Saya akan mengatakan tidak.
DLosc
Anda menyebutkan spasi tambahan, tapi bagaimana dengan ruang utama? Apakah gambar perlu rata kiri, atau dapatkah itu memiliki jumlah ruang utama yang sama pada setiap baris?
Sp3000
Siram ke kiri, seperti yang ditunjukkan pada sampel output.
DLosc
Mungkinkah ada ruang di luar tepi kanan tetapi masih membentuk persegi panjang?
xnor

Jawaban:

2

Ruby, 141 127

Mengembalikan string persegi panjang

->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)}*$/}

Tidak digabungkan dalam program uji

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
sumber
8

Python 2, 140 byte

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]

Tidak hebat, tapi inilah tawaran awal saya.

Aturan spasi putih menambahkan banyak byte. Sebagai perbandingan, inilah program Python 3 120 byte yang hanya benar secara visual, dan tidak mengikuti aturan spasi putih:

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)

Dan inilah upaya Python 3 149 rekursif saya yang sedikit lebih lama:

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
sumber
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

Ini, dalam retrospeksi, pendekatan yang salah untuk Python, tapi saya mempostingnya di sini kalau-kalau ada yang bisa memanfaatkannya. Daripada menjelaskan kekacauan kode ini, saya akan mencoba mengatakan ide di baliknya.

Idenya adalah untuk menggunakan koordinat segitiga , di mana kisi segitiga sesuai dengan bilangan bulat tiga kali lipat (a,b,c)dengan a+b+c=0.

masukkan deskripsi gambar di sini

(Di sini, titik-titik kisi digambarkan sebagai segi enam.)

Kami dapat mengonversi koordinat Cartesian menjadi yang segitiga sebagai

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

mencatat itu xdan yharus memiliki paritas yang sama, atau selain itu kotak-kotak dan kita harus mencetak spasi.

Dalam koordinat segitiga, garis pembatas dari bintang bersisi enam memiliki persamaan: a==n, b==n, c==n, a==-n, b==-n, c==-n.

Jadi, kita bisa menentukan wilayah mana [a,b,c,-a,-b,-c]yang lebih besar dari kita n.

  • Jika tidak ada, kami berada di tengah dan mencetak satu titik.
  • Jika tepat satu, kita berada di salah satu dari enam segitiga luar, dan cetak huruf yang sesuai dengan indeks.
  • Jika dua atau lebih, kita di luar papan, dan cetak spasi.

Rectangle pembatas mengharuskan kita melakukan ini xdalam interval tertutup [-2 * n, 2 * n] dan ydalam interval tertutup [-3 * n, 3 * n].

Tidak
sumber
Kode tidak berfungsi untuk saya.
BadAtGeometry
@BadAtGeometry Ini berfungsi untuk saya .
xnor
Versi apa yang Anda gunakan?
BadAtGeometry
@BadAtGeometry TIO menggunakan 2.7.15 . Apa yang terjadi ketika Anda menjalankannya?
xnor
7

Retina , 234 byte

.
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
.
 #
#

Mengambil input di unary.

Setiap baris harus menuju ke file sendiri dan #harus diubah ke baris baru di file. Ini tidak praktis tetapi Anda dapat menjalankan kode seperti halnya satu file dengan -sflag, menjaga #marka dan mungkin mengubahnya menjadi baris baru di output agar mudah dibaca jika diinginkan.

Kode ini memiliki kompleksitas regex minimal. Langkah-langkah utama dalam generasi adalah sebagai berikut:

  • Buat Gbaris terakhir dan baris pertama B.Y(dibatasi oleh marker ijkdan letetrs yang digunakan sebenarnya RPO).
  • Gandakan Ggaris paling atas dengan spasi plus, minus G hingga hanya ada satu G.
  • Gandakan intinya B.Ydengan ruang plus dan titik, minus a Bdan Ysampai tidak ada Bdan Ytersisa.
  • Salin semua baris dalam urutan terbalik setelah string saat ini (dengan bantuan marker q). Kami menyimpan penanda ( w) di tengah.
  • Kami mengubah huruf RPOke GBYjika mereka sebelum penanda.
  • Tambahkan spasi di antara yang hilang.

Hasil setelah masing-masing poin di atas (dibatasi oleh ='s) untuk input 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
sumber
4

JavaScript ( ES6 ) 228

Konstruksi garis demi garis. Sangat lama dibandingkan dengan @ Sp3000 yang melakukan hal yang sama.

Menggunakan string template untuk menyimpan 3 byte lebih banyak untuk baris baru. Semua baris baru signifikan dan dihitung.

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
sumber