Выкручивай алфавит!

13

Посмотрите на следующую строку. Заметили шаблон?

ABEFNOPEFGH
DC GQI
MHRJ
LKJI SK
DTL
ЦУМ
BAZYXWV N
Е.О.
DP
CQ
BAZYXWVUTSR

Как некоторые могли заметить, это в основном спираль алфавита, где расстояния между строками / столбцами постепенно увеличиваются на 1 пробел / перевод строки.

Строгое определение

  • Давайте иметь счетчик с , который изначально равен 0.
  • Выпишем первые с + 1 буквы алфавита слева направо: A.
  • Затем сверху вниз на следующий (с + 1) (с + 2) / 2 буквы (добавить B): AB.

  • Слева направо, следующее (с + 1) (с + 2) / 2 (добавить C):

    AB
     C
    
  • И снизу вверх, следующие c + 1 буквы (добавить D):

    AB
    DC
    
  • Дошел до конца цикла. Следовательно, давайте увеличивать c (который становится 1). Затем он начинается с первого шага, с той лишь разницей, что вместо использования первых c + 1 букв алфавита мы используем следующие c + 1 буквы, начиная с последнего элемента этого цикла ( Dв данном случае так что продолжим EFG...). Когда Zдостигается, он возвращается назад A.

задача

Если задано целое число N (положительное для 1-индексации или неотрицательное для 0-индексации), выведите первые N циклов спирали.

правила

  • Вы можете использовать как строчные, так и прописные буквы, но ваш выбор должен быть последовательным (используйте только один из них, смешивание не допускается).

  • Вы можете принимать и выводить данные любым стандартным методом на любом языке программирования , при этом отмечая, что эти лазейки по умолчанию запрещены.

  • Приемлемые форматы вывода: многострочная строка, список строк, представляющих строки, список, содержащий несколько списков символов, каждый из которых представляет одну строку, или все, что вы считаете подходящим. Если вы не выберете первый формат, было бы неплохо включить версию вашего кода в красивой печати.

  • Это , поэтому выигрывает самый короткий код в байтах (на каждом языке), который соответствует требованиям!


Контрольные примеры

Входное целое число будет разделено соответствующим выводом через новую строку, а тесты будут разделены тире. Обратите внимание, что они 1-индексированы.

1

AB
ОКРУГ КОЛУМБИЯ

--------

2

ABEF
DC G
MH
LKJI 

--------

3

ABEFNOP
DC GQ
MHR
LKJI S
DT
CU
BAZYXWV

-------

4

ABEFNOPEFGH
DC GQI
MHRJ
LKJI SK
DTL
ЦУМ
BAZYXWV N
Е.О.
DP
CQ
BAZYXWVUTSR

-------
5

ABEFNOPEFGHFGHIJ
DC GQIK
MHRJL
LKJI SKM
DTLN
CUMO
BAZYXWV NP
EOQ
DPR
ОКК
BAZYXWVUTSR T
ру
QV
PW
OX
NMLKJIHGFEDCBAZY

------

6

ABEFNOPEFGHFGHIJSTUVWX
DC GQIKY
MHRJLZ
LKJI SKMA
DTLNB
CUMOC
BAZYXWV NPD
EOQE
DPRF
CQSG
BAZYXWVUTSR TH
RUI
QVJ
PWK
OXL
NMLKJIHGFEDCBAZY M
SN
RO
QP
PQ
ИЛИ 
NMLKJIHGFEDCBAZYXWVUTS
Мистер Xcoder
источник
Тестовые случаи должны быть n = 1,2,3,5,6, я думаю.
TFeld

Ответы:

9

Древесный уголь , 31 байт

F⮌…⁰NB⁺²⊘×ι⁺³ι⭆α§α⁺λ÷×ι⊕×ι⁺⁹⊗ι⁶

Попробуйте онлайн! Ссылка на подробную версию кода. Примечание. По какой-то причине девербозификатор выводит завершающий разделитель. Объяснение:

F⮌…⁰NB

Нарисуйте прямоугольники в обратном порядке размера (от наибольшего к наименьшему).

⁺²⊘×ι⁺³ι

Рассчитайте размер коробки.

⭆α§α⁺λ

Нарисуйте границу рамки, используя повернутый алфавит.

÷×ι⊕×ι⁺⁹⊗ι⁶

Вычислите букву, которая будет отображаться в левом верхнем углу поля (с индексами 0).

Нил
источник
6

Python 2 , 176 байт

n=input()
k=n*-~n/2+1
a=eval(`[[' ']*k]*k`)
x=y=z=0
for s in range(4*n+4):exec s/4*(s/4+1)/2*"if'!'>a[y][x]:a[y][x]=chr(z%26+65);z+=1\nx+=abs(2-s%4)-1;y+=s%2-s%4/3*2\n"
print a

Попробуйте онлайн!

объяснение

Мы создаем пустой массив пробелов правильного размера, а затем перемещаемся по нему, начиная с верхнего левого угла:

  • 1 шаг →, 1 шаг ↓, 1 шаг ←, 1 шаг ↑

  • 3 шага →, 3 шага ↓, 3 шага ←, 3 шага ↑

  • 6 шагов →, 6 шагов ↓, 6 шагов ←, 6 шагов ↑

  • 10 шагов →, 10 шагов ↓, 10 шагов ←, 10 шагов ↑

  • ...

Каждый раз, когда мы находим пустую ячейку, мы помещаем туда букву и переходим к следующей букве в алфавите.

В коде s%4указано направление (→ ↓ ← ↑), и мы многократно повторяем это:

TriangularNumber(s/4) = s/4*(s/4+1)/2.

Гольф возможности

  • Есть ли более короткий способ сопоставить s%4с 1,0,-1,0чем abs(2-s%4)-1?

  • Есть ли более короткий способ сопоставить s%4с 0,1,0,-1чем s%2-s%4/3*2?

кредиты

  • Мистер Xcoder сохранил байт.
Линн
источник
2
+1 Ого, это просто замечательно. Мне понадобилось время, чтобы понять, как это работает. Я нашел сокращение для 21/(s%4+3)%3-1: s%2-2*(s%4>2)( 179 байт ). Это все еще может быть пригодным для игры в гольф, хотя
г-н Xcoder
4

C  305  281 байт

Благодаря @Mr. Xcoder для сохранения четырех байтов!

#define L(x,y)l[x][y]=a++%26+65;
#define F for(
c,i,j,a,p;f(n){char**l=calloc(8,i=a=n*n*4);F;i--;memset(l[i],32,a))l[i]=malloc(a);F c=a=p=i=0;c<n;++c){F i=p;i<c+p+!c;)L(j=0,c+i++)F p=i;j<=-~c*(c+2)/2;)L(j++,c+i)F;c+i-1;)L(j-1,c+--i)F i=0;i<=c;)L(j+~i++,0)}F i=0;i<j;)puts(l[i++]);}

Попробуйте онлайн!

Steadybox
источник
1
В первый раз я вижу #defineдля for((это на самом деле экономит байты). +1 от меня. :)
Кевин Круйссен
2

Python 2 , 262 260 254 245 байт

lambda n:[[[' ',chr(65+(4*(i<j)+sum((i<j)*8+2+I*[5,9][i<j]+sum(2*R(I))for I in R(S(i,j)-1))+[i+j,-i-j][i<j])%26)][max(i,j)==S(i,j)*-~S(i,j)/2or i*j<1]for i in R(1+n*-~n/2)]for j in R(1+n*-~n/2)]
R=range
S=lambda x,y:int((8*max(x,y)+1)**.5+.99)/2

Попробуйте онлайн!

Новый метод с большим количеством математики!

Возвращает список списков символов.


Старая версия:

Python 2 , 322 321 308 298 байт

R=range
n=input()
w=1+n*-~n/2;r=[w*[' ']for _ in R(w)];r[0][0]='A';l=R(1,w*w*9);c=lambda:chr(65+l.pop(0)%26)
for i in R(n+1):
 w=1+i*-~i/2;W=w-i
 for x in R(W,w):r[0][x]=c()
 for y in R(1,w):r[y][w-1]=c()
 for x in R(1,w):r[w-1][w+~x]=c()
 for x in R(1,w-W):r[w+~x][0]=c()
for l in r:print`l`[2::5]

Попробуйте онлайн!

TFeld
источник
@ Mr.Xcoder Не .49достаточно просто в этом случае, или он терпит неудачу для очень больших входов?
Кевин Круйссен
1
@KevinCruijssen Не уверен, но это точно работает, 260 байтов .
г-н Xcoder
Я не очень хорошо знаю Python, но возможно ли сделать встроенную переменную для i<j, так как вы используете его четыре раза?
Кевин Круйссен
1
245 байт при игре в гольф +1==1+от моего предыдущего метода
Mr. Xcoder
1

Perl 5, 177 +2 (-nl) = 179 байт

2 байта сохранены благодаря Xcali

sub n{chr 65+$c++%26}@O=(n);while($,++<$_){$_.=$"x$,for@O;push@O,($"x length$O[0])x$,;$O[0]=~s/ /n/eg;s/ $/n/e for@O;1while$O[-1]=~s/.*\K /n/e;s/^ /n/e for reverse@O}print for@O

Попробуйте онлайн

Науэль Фуйе
источник
Вы можете сохранить байт, используя -1вместо $#O. Кроме того, используя $,вместо $nпозволит вам удалить пробел перед forв$_.=$"x$n for@O
Xcali
спасибо, я искал другие улучшения, но не мог найти на данный момент
Науэль Фуйе
сохранил еще 2 байта, изменив регулярное выражение s/ (?=\S)/n/eнаs/.*\K /n/e
Nahuel Fouilleul