Спіраль з алфавіту!


13

Подивіться на наступний рядок. Помітили шаблон?

ABEFNOPEFGH
DC GQI
MHRJ
LKJI SK
DTL
CUM
BAZYXWV N
EO
DP
CQ
BAZYXWVUTSR

Як деякі могли помітити, це в основному спіраль алфавіту, де відстані між рядками / стовпцями поступово збільшуються на 1 пробіл / новий рядок.

Суворе визначення

  • Нехай лічильник c , який спочатку дорівнює 0.
  • Випишемо перші з + 1 літери алфавіту зліва направо: A.
  • Потім зверху вниз на наступний (з + 1) (з + 2) / 2 букви (додати B): AB.

  • Зліва направо, наступний (c + 1) (c + 2) / 2 (add 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

АБЕФ
DC G
MH
LKJI 

--------

3

АБЕФНОП
DC GQ
MHR
LKJI S
DT
МС
BAZYXWV

-------

4

ABEFNOPEFGH
DC GQI
MHRJ
LKJI SK
DTL
CUM
BAZYXWV N
EO
DP
CQ
BAZYXWVUTSR

-------
5

ABEFNOPEFGHFGHIJ
DC GQIK
MHRJL
LKJI SKM
DTLN
CUMO
BAZYXWV NP
EOQ
ДНР
CQS
BAZYXWVUTSR T
RU
QV
PW
OX
NMLKJIHGFEDCBAZY

------

6

ABEFNOPEFGHFGHIJSTUVWX
DC GQIKY
MHRJLZ
LKJI SKMA
DTLNB
CUMOC
BAZYXWV NPD
EOQE
ДНРФ
CQSG
BAZYXWVUTSR TH
RUI
QVJ
PWK
OXL
NMLKJIHGFEDCBAZY M
СН
RO
QP
PQ
АБО 
NMLKJIHGFEDCBAZYXWVUTS

Я думаю, тестові корпуси повинні бути n = 1,2,3,5,6.
TFeld

Відповіді:


9

Вугілля деревне , 31 байт

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

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Примітка: Девербосифікатор чомусь видає кінцевий роздільник. Пояснення:

F⮌…⁰NB

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

⁺²⊘×ι⁺³ι

Обчисліть розмір коробки.

⭆α§α⁺λ

Намалюйте рамку коробки за допомогою обертового алфавіту.

÷×ι⊕×ι⁺⁹⊗ι⁶

Обчисліть букву, яка з’явиться у верхньому лівому куті поля (0-індексовано).


6

Пітон 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++]);}

Спробуйте в Інтернеті!


1
Перший раз я бачу знак #definefor 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

Спробуйте в Інтернеті!

Новий метод з більшою кількістю математики!

Повертає список списків char.


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

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]

Спробуйте в Інтернеті!


@ Mr.Xcoder Не .49достатньо просто в такому випадку, або це не вдається для дуже великих входів?
Кевін Круїссен

1
@KevinCruijssen Не впевнений, але це працює точно, 260 байт .
Містер Xcoder

Я не знаю Python так добре, але чи можна зробити вбудовану змінну i<j, оскільки ви її використовуєте чотири рази?
Кевін Круїссен

1
245 байт гольфу +1==1+від мого попереднього методу
містер 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

дякую, я шукав інші вдосконалення, але наразі не міг знайти
Nahuel Fouilleul

зберігаються більше 2 байта мінливого регулярного виразу s/ (?=\S)/n/eдляs/.*\K /n/e
Науель FOUILLEUL

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