Китайська шахівниця


21

Гра китайських шашок проводиться на дошці з пробілами у формі шестикутної зірки:

Зображення дошки

Зображення з Вікіпедії

Ми можемо створити ASCII-художнє зображення цієї дошки, використовуючи .порожні плями та букви GYORPBдля шести кольорових початкових місць:

            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

Щоб зробити це цікавіше, ми можемо також змінити розмір. Ми виміряємо розмір дошки за стороною довжини її трикутних початкових місць: дошка вище розміром 4.

Оскільки насправді болісно набрати все це вручну, давайте напишемо програму (або функцію), щоб це зробити!

Деталі

Ваш код повинен мати додатне ціле число, що відображає розмір плати, через STDIN, ARGV або аргумент функції. Виведіть шаблон шаблону в STDOUT (ви можете по черзі повернути його як рядок, якщо ваше подання є функцією).

Вихід повинен бути будь-яким

  • взагалі не мають пробілів, або
  • мати достатньо пробілів, щоб заповнити візерунок до ідеального прямокутника шириною 6 * N + 1.

Необов'язково вихідний рядок може мати зворотний новий рядок. Ніякі інші додаткові (провідні, кінцеві) пробіли не дозволені.

Приклади

Розмір 1:

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

Розмір 2:

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

Розмір 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

Оцінка балів

Це : виграє найкоротший код у байтах.


Чи можуть у виході бути порожні рядки пробілів до і після?
xnor

Я скажу ні.
DLosc

Ви згадали пробіли, але як щодо провідних просторів? Чи потрібно зображення залишити розмитим, чи воно може мати рівну кількість провідних пробілів у кожному рядку?
Sp3000

Промийте ліворуч, як показано у вибірку зразка.
DLosc

Чи можуть бути пробіли за правим краєм, але все ж утворювати прямокутник?
xnor

Відповіді:


2

Рубі, 141 127

Повертає прямокутну рядок

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

Ungolfed в тестовій програмі

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]

8

Пітон 2, 140 байт

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]

Не чудово, але ось моя початкова пропозиція.

Правила пробілів додали багато байтів. Для порівняння, ось 120-байтна програма Python 3, яка правильна лише візуально і не відповідає правилам пробілів:

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)

І ось моя трохи довша рекурсивна спроба Python 3 з 149 байтами:

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}))]

7

Пітон 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

Це, в ретроспективі, неправильний підхід для Python, але я публікую його тут, якщо хтось може ним скористатися. Замість того, щоб пояснювати цей безлад коду, я спробую сказати ідею, що стоїть за ним.

Ідея полягає у використанні трикутних координат , у яких трикутна решітка відповідає цілим трійкам (a,b,c)з a+b+c=0.

введіть тут опис зображення

(Тут точки решітки малюються як шестикутники.)

Ми можемо перетворити декартові координати в трикутні як

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

відзначивши , що xі yповинні мати однакову парність, або в іншому випадку це поза шахівниці , і ми повинні надрукувати пробіл.

В трикутних координатах, що обмежують лінії шестигранною зірки мають рівняння: a==n, b==n, c==n, a==-n, b==-n, c==-n.

Отже, ми можемо визначити, в якому регіоні ми перебуваємо, в якому з [a,b,c,-a,-b,-c]них більше n.

  • Якщо жодної немає, ми знаходимося в центрі і друкуємо крапку.
  • Якщо саме такий є, ми знаходимося в одному з шести зовнішніх трикутників і друкуємо букву, відповідну індексу.
  • Якщо два або більше, ми знаходимось поза дошкою та друкуємо пробіл.

Обмежуючий прямокутник вимагає, щоб ми це робили xв закритому інтервалі [-2 * n, 2 * n] та yв закритому інтервалі [-3 * n, 3 * n].


Код для мене не працює.
BadAtGeometry


Яку версію ви використовуєте?
BadAtGeometry

@BadAtGeometry TIO використовує 2.7.15 . Що відбувається, коли ви запустите його?
xnor

7

Сітківка , 234 байт

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

Здійснює введення в одинаковому режимі.

Кожен рядок повинен мати свій власний файл і його #слід змінити на новий рядок у файлі. Це недоцільно, але ви можете запустити код як один файл із -sпрапором, зберігаючи #маркери та, можливо, змінивши їх на нові рядки у висновку для читабельності, якщо бажаєте.

Код має мінімальну регекс-складність. Основними кроками в поколінні є наступні:

  • Створіть останню G і перший B.Yрядок (розмежований маркерами ijkта фактично використаними лететерами RPO).
  • Скопіюйте верхній Gрядок з пробілом плюс мінус G, поки не залишиться лише один G.
  • Скопіюйте нижню B.Yлінію плюс пробіл і крапки, мінус a BіY до тих пір, поки їх немає Bі не Yзалишилося.
  • Скопіюйте всі рядки у зворотному порядку після поточного рядка (за допомогою маркера q ). Тримаємо маркер ( w) посередині.
  • Міняємо букви RPO на те, GBYякщо вони знаходяться перед маркером.
  • Додайте пропуски пропусків між ними.

Результати після кожного з вищезазначених пунктів (відмежованих ='s) для введення 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

4

JavaScript ( ES6) ) 228

Будівництво по черзі. Неймовірно довго в порівнянні з @ Sp3000, що робить те саме.

Використовуючи рядок шаблону, щоб зберегти ще 3 байти для нових рядків. Усі нові рядки є вагомими і підраховані.

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>

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.