Китайская шахматная доска

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

счет

Это : выигрывает самый короткий код в байтах.

DLosc
источник
Могут ли выходные данные содержать пустые строки пробелов до и после?
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)}*$/}

Неуправляемый в тестовой программе

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]
Уровень реки St
источник
8

Python 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)

А вот моя чуть более длинная рекурсивная 149-байтовая попытка 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
источник
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

Ретроспективно, это неправильный подход для 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].

XNOR
источник
Код не работает для меня.
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строку с пробелом плюс и точка, минус а Bи Yдо тех пор, пока нет BиY осталось.
  • Скопируйте все строки в обратной последовательности после текущей строки (с помощью маркера q). Мы держим маркер (w ) в середине.
  • Мы меняем буквы RPOнаGBY если они находятся перед маркером.
  • Добавьте пропущенные промежуточные пробелы.

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

edc65
источник