Добре розташована спіраль ASCII


13

Розглянемо цю спіраль

###########
#
# #######
# #     #
# # ### #
# # # # #
# # # # #
# #   # #
# ##### #
#       #
#########

Починаючи з центру:

  • Перший рядок (вгору) містить 3 символи.
  • Другий рядок має однакову кількість символів (3)
  • Далі додаємо дві символи (5) для наступних двох сторін.
  • Ця схема продовжується, дві сторони однакової довжини потім збільшують довжину на 2.

Я хочу створити цю спіраль для N ліній.

  • Пишіть будь-якою мовою.
  • Вхід / аргумент тощо - це кількість рядків у вашій спіралі.
  • Кожен рядок починається із закінчувального символу попереднього рядка у напрямку 90 градусів за годинниковою стрілкою попереднього рядка.
  • Мені все одно, скільки пробілів до або після кожного рядка, поки елементи спіральної лінії вгору.
  • Виведіть текст, щоб намалювати спіраль із будь-яким символом, який ви не розбігаєте.
  • Спроба зробити це в найменшій кількості байтів.

Тестові приклади (використовуючи хеш як вихід):

N = 1

#
#
#

N = 2

###
#
#

N = 3

###
# #
# #
  #
  #

N = 10

###########
#
# #######
# #     #
# # ### #
# # # # #
# # # # #
# #   # #
# ##### #
#       #
#########

@Shaggy "Виведіть текст, щоб намалювати спіраль із будь-яким символом, який ви не виділяєте пробілом." Так, що завгодно.
AJFaraday


3
Початкове зображення *замість #. Очікували?
Верніш

@Wernisch Це мало бути корисною відправною точкою, але я вважаю, що це вводить в оману. Ви можете використовувати будь-який символ, який вам подобається.
AJFaraday

Відповіді:


11

05AB1E , 13 11 байт

Код:

Дякуємо Еміньї за збереження двох байтів!

LDÈ-Ì'#3Ý·Λ

Використовує кодування 05AB1E . Спробуйте в Інтернеті!

Пояснення

Довжина кожного окремого краю на спіралі починається з довжини 3 і поступово збільшується кожні два кроки на два:

3,3,5,5,7,7,9,

Для спіралі з ребрами нам просто потрібно обрізати цей список до розміру . Це робиться за допомогою наступного фрагмента коду:nnn

L                # Create a list from [1 .. input]
 DÈ              # Duplicate and check for each number if even
   -             # Subtract that from the first list
    Ì            # Add 2

Це в основному дає нам бажаний перелік довжин.

     '#          # Push the '#' character
       0246S     # Push the array [0, 2, 4, 6]
            Λ    # Write to canvas

Полотно працює як функція, яка виділяє три параметри (де найперший параметр вискакується спочатку): <довжина (и)> , <char (s)> , <напрям (и)> . Параметр вказівки в цьому випадку є списком чисел. Номери, які відповідають вказівкам:

[70162543]

У цьому випадку [0, 2, 4, 6] відповідає списку вказівок [↑, →, ↓, ←]. Полотно перебирає кожну довжину, отриману зі списку довжин, використовує символ "#" і циклічно перебирає список списку напрямків.


0246S=3Ý·
Емінья

@Emigna Ах, я не думав про це, дякую!
Аднан

6

Пітон 2 , 176 170 165 161 157 байт

g=lambda a,r:r and g(map(''.join,zip(*a))[::-1],r-1)or a
R=['#']
n=1
exec"R=g(['  '+l for l in g(R,n)][:-1]+[(n+2)*'#'],3*n);n+=1;"*input()
print'\n'.join(R)

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

Неодноразово: Використовує gдля обертання nітерації спіралі в "канонічне" положення (подібне до N = 3 або N = 7), додає новий сегмент, додаючи 2 пробіли зліва від кожного існуючого рядка, потім замінюючи останній рядок з усіма '#'s (в результаті виходить позиція, порівнянна з N = 4 або N = 8), і, нарешті, gзнову використовуйте для повернення її до правильної позиції. Натріть, промийте, повторіть.


4

Вугілля , 16 15 14 байт

↶FN«¶×#⁺³⊗÷ι²↷

-2 байти завдяки @Neil .

Спробуйте в Інтернеті (багатослівний) або Спробуйте в Інтернеті (чисто) .

Пояснення:

Напрямок друку за замовчуванням праворуч, і ми хочемо починати вгору, тому ми починаємо з обертання на 45 градусів проти годинникової стрілки:

PivotLeft();
↶

Потім петлю iв діапазоні [0, input):

For(InputNumber()){ ... }
FN« ...

Роздрукуйте новий рядок, щоб імітувати ефект переміщення на одну позицію:

Print("\n");
¶

Вивести "#" xкількість разів у поточному напрямку:

Print(Times("#", ... ));
×# ...

Де xзнаходиться: 3 + i // 2 * 2:

Add(3,Doubled(IntegerDivide(i,2))
⁺³⊗÷ι²

А потім поверніть на 45 градусів за годинниковою стрілкою для наступної ітерації циклу:

PivotRight();
↷

Я припускаю, що у Вугілля немає команди для руху назад?
Емінья

@Emigna Не впевнений, але я також не міг його знайти. Дійсно шукав себе, коли писав цю відповідь. Існує Move з заданим напрямком, а також стрибок із заданими координатами, але, на жаль, не MoveBack.
Кевін Круїйсен

1
⊗÷ι²- байт коротший, ніж ⁻ι﹪ι². Крім того, ви можете отримати ефект переміщення назад, надрукувавши a \nперед #s, що дозволить вам видалити »#додаткову загальну економію байтів.
Ніл

@Neil Дякую за те ⊗÷ι², але які зміни були б для друку a \nдо #s? Спіраль неправильна, якщо я додаюPrint("\n") .
Кевін Круїйсен

Оскільки зброї тепер перекриваються, вам потрібно зробити їх додатковими #довше.
Ніл

3

Пітон 2 , 179 178 байт

спасибі Кевіну Крейсейну за -1 байт.

n=input()
S,H=' #'
m=[S*n]*(n%2-~n)
x=n/4*2
y=0--n/4*2
k=2
m[y]=S*x+H+S*n
M=[1,0,-1,0]*n
exec'exec k/2*2*"x+=M[~k];y+=M[k];m[y]=m[y][:x]+H+m[y][x+1:];";k+=1;'*n
print'\n'.join(m)

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


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

У такому підході формули використовуються для xі yдельти замість списку пошуку.

n=input()
S,H=' #'
m=[S*n]*(n%2-~n)
x=n/4*2
y=0--n/4*2
k=2
m[y]=S*x+H+S*n
exec'exec k/2*2*"x+=k%-2+k%4/3*2;y-=(k%2or k%4)-1;m[y]=m[y][:x]+H+m[y][x+1:];";k+=1;'*n
print'\n'.join(m)

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


n+1+n%2до n%2-~n-1 байт. І мені потрібно пам’ятати, 0--n/4*2що на 1 коротше -(-n/4*2). Гарна відповідь, +1 від мене.
Кевін Кройсейсен

1

JavaScript (ES6), 185 байт

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

r=(a,n=1)=>n?r(a.reduce((_,c)=>c).map((_,i)=>a.map(e=>e[i])).reverse(),n-1):a,
s=n=>n?r(s(n-1)).map((r,i)=>[...r,w,w].map(x=>i?x:'#')):[[w=' ']],
d=n=>r(s(n),1-i).map(r=>r.join``).join`
`

Використання: d(10)повертає рядок відповідно до прикладу завдання N = 10.

Визначає функцію r(a,n)обертання масиву aпо nчерзі; функція s(n)для генерації двовимірного масиву, що представляє спіраль розміром, nшляхом рекурсивного обертання та додавання проміжків і ліній (не повернутих назад у вихідне положення); і функція d(n)малювати спіраль розміром n, що обертається послідовно відповідно до виклику і відображається як повернута рядок.

Це було справді веселим викликом: ¬)

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