Вбудовані шестикутники!


18

Ваше завдання: задавши ціле число n, генеруйте вбудований шестикутник, дотримуючись наведених нижче правил, до n-ої глибини.

Основна форма цього вбудованого шестикутника: ( n=0)

 __      
/  \
\__/

Вбудовані шестикутники n=1та n=2:

  ____    
 /  \ \
/\__/  \
\      /
 \____/

    ________    
   /  \ \   \
  /\__/  \   \
 /\      /    \
/  \____/      \
\              /
 \            /
  \          /
   \________/

Довжина кожної сторони в 2 рази перевищує довжину цієї ж сторони в попередній глибині в два рази. Верхня та нижня сторони мають 2 символи, n=0а решта починаються як 1 символ. Довжина бічної сторони, що не має верхньої та нижньої, повинна бути 2^nдовгою ( OEIS: A000079 ), а верхня та нижня сторони повинні відповідати правилу 2^(n+1)(той же OEIS).

Поточні шестикутники є 0-індексованими, ви можете вибрати, якщо хочете, 1-індексованими.

Це , тому найкоротша відповідь виграє!


@LuisMendo Добре, я зміню ім'я.
Товариш СпарклПоні

З великим вкладом може бути важко впоратися (наприклад, 64). Чи є обмеження на n?
Меттью Рох

@SIGSEGV N немає обмежень на n.
Товариш SparklePony

1
Буде весело побачити відповідь у Гексагонії :))
Містер Xcoder

1
Гей, графіка черепах мого представлення кривої Коха також може це зробити (змінилася лише перша функція). Безумовно, занадто довго для цього :)
Шріхан Йохансен

Відповіді:


10

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

11 байтів збереглися завдяки @Neil, змінивши цикл while на цикл for-other серед інших хитрощів

FN«AX²ιβ×__β↓↘β←↙β↑←×__β↖β→↗β

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

Пояснення (застаріле)

Ця програма починається з генерації найбільшого шестикутника, а потім робить менші по черзі циклу (1-індексований). Для довідки α- це вхідний номер, βце змінна, яка містить 2^(α-1)і ιє ітераційною змінною в циклі.

Nα                        # Take input and store in α
Wα«                       # While α do:
 ×_X²ι                    #  Write "_"*(2**ι); this forms the top edge of the hexagon
 ↓                         #  Go down
 AX²⁻ι¹β                 #  Assign 2**(ι-1) to β
 ↘β←                       #  Write \ β times in a SE direction (top right edge) and then go left
 ↙β↑                       #  Write / β times in a SW direction (bottom right edge) and then go up
 ←×_X²ι                   #  Write the bottom edge
 ↖β→↗β                    #  Just like before, write the top and bottom left edges
 A⁻α¹α                    #  Decrement α
                          # Now the pointer is at the top left corner of the hexagon,
                          # from where the other smaller hexagons will soon be generated

Я помітив, що немає "Привіт, світ!" Програма для вугілля ще. Ви повинні додати його.
mbomb007

@ mbomb007 Хіба це не був би дублікат тривіального "Відповідь ця мова друкує вихідний файл, якщо він не містить команд"?
Ніл

Я зберег декілька байтів, коли зрозумів, що ×_X²ιце те саме ×__β, що й те, а ще кілька байтів, перетворивши ваш в а , що також уникає необхідності зберігати вхідне число. Спробуйте в Інтернеті! .
Ніл

@Neil Спасибі, це досить акуратно :)
Kritixi Lithos

5

Haskell , 230 217 207 байт

Редагувати:

  • -13 байт: @xnor побачив, що моє #може бути справедливим max.
  • -10 байти: А також , що zipWithі pможуть бути об'єднані в ?оператор, і що я (як - то!) Переписаний replicate.

mбере Integerі повертає a String.

m n=unlines.foldr1 o$((2^n)&).(2^)<$>[0..n]
l&t|a<-c[l,2*t]" _",b<-[c[l-i,1,2*t+2*i-2,1,l-i]" / \\ "|i<-[1..t]]=a:b++r(r<$>o[a]b)
c=(concat.).z replicate
o=max?' '?""
f?e=z f.(++repeat e)
r=reverse
z=zipWith

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

Як це працює

  • mє основною функцією. Він використовує &для генерування шестикутників за допомогою правильних накладок, потім згортає їх o.
  • l&tгенерує невеликий шестикутник бічної довжини t, накладений всередині великої бічної довжини l, як список Stringліній.
    • a - верхня лінія шестикутника, з підкресленнями.
    • b- список інших рядків у верхній половині шестикутника. Лінії bвідцентровані в обшивці, яка є прямокутною; це дозволяє наступному кроку працювати.
    • Нижня половина шестикутника aнакладна на вершину bз o, а потім зворотним порядком (як лінії і в межах кожного рядка).
  • cбере два аргументи, список довжин і рядок, і генерує рядок, який містить стільки копій кожного символу в оригіналі, скільки відповідна довжина, наприклад c[1,3,2]"abc" == "abbbcc". Він використовується &для генерації ліній.
  • o приймає два аргументи, що представляють зображення як списки рядків, і накладає перший, менший, поверх другого.
    • Він використовується як для комбінування шестикутників, так і для додавання дна до кожного шестикутника.
    • Він по суті працює, використовуючи ?двічі, щоб накласти перше зображення на нескінченно багато пробілів і вниз, і вправо, а потім зв'язати разом відповідні символи max, які вибирають непробільний символ, якщо такий є.
  • (f?e)l mпрошиває список l, додаючи нескінченно багато елементів 'e', ​​потім перебирає отриманий список та список mіз fфункцією.

1
Приємне рішення! Я думаю, що (#)може бути max.
xnor

1
Архівування можна комбінувати з , pщоб зберегти байт: o=max?' '?"";f?e=z f.(++repeat e). Можливо, буде коротшою точковою.
xnor

2
(\n->(<$[1..n]))є replicate.
xnor

@xnor replicate? Тепер це просто безтурботно. Я просто занадто звик <$[1..n]або [1..n]>>майже завжди перемагаю. Однак я не бачу, як вкоротити ?далі. Я вже спробував зробити ppointfree, і ++це просто в неправильному місці, підірвавши речі flip.
Ørjan Johansen

3

JavaScript (ES6), 258 байт

f=(n,s=` `.repeat(1<<n),p=(n?f(n-1):`


`).replace(/(.*)\n/g,s+`$1 `+s)+s,t=`_`.repeat(2<<n))=>(s+t+s+`
`+s.replace(/ /g,"$'/$'$'  $`$`$`$`\\$'\n")).replace(/ /g,(c,i)=>p[i+(1<<n>>1)])+s.replace(/ /g,"$`\\$`$`  $'$'$'$'/$`\n").replace(/ +\/( *)\n$/,t+`/$1
`)
<input type=number min=0 oninput=o.textContent=f(+this.value)><pre id=o>

Пояснення: Для шестикутників після першого спочатку генерується попередній шестикутник і набивається з кожної сторони (це спирається на результат, який є прямокутником). (Для першого заголовка створено кілька манекенових накладок.) Верхня та верхня сторони шестикутника генеруються, і всі пробіли зливаються з попереднім шестикутником. (Існує певна хитрість, щоб змусити шестикутники вирівнюватися; це було б простіше, якщо були допущені додаткові поля.) Нижні сторони шестикутника генеруються аналогічно верхнім сторонам, а нижня шестикутник заповнюється. Слід подбати про повернення прямокутного виводу, включаючи зворотний новий рядок, для рекурсії в роботу.


Отже, ти демонструєш, що ця, тефлонова і піца з глибокої страви, справді схожа конструкція? Це якось акуратно.
AdmBorkBork

1
@AdmBorkBork У мене є кілька інших відповідей, які роблять це; ці діагоналі /популярні в мистецтві ASCII, і replaceметод є відносно дешевим способом їх створення в JavaScript.
Ніл

1<<n>>1: Приємна симетрія ;-)
Лука

@Luke Я міг би змінити змінну на, скажімо, vале, на жаль, 1це не симетрично в жодному з моїх звичайних шрифтів.
Ніл

2

PHP, 337 байт

0 Індексація

$h=array_fill(0,1+2*$v=2**($c=$argn),str_pad("",4*$v));for(;1+$c;$c--)for($i=0;$i<$e=2**$c*2+1;$i++){$z=$e-$i<2;$y=$i&&$i<$e/2;$x=$i>=$e/2&$i<$e-1;$h[$i]=substr_replace($h[$i],$s=str_pad(!$y?$z|$x?"\\":"":"/",$e-1+$z-$y+$y*$i*2-$x+$x*2*($e-$i),$z|!$i?"_":" ").(!$y?$z|$x?"/":"":"\\"),$v-$z-$y*$i-$x*($e-$i),strlen($s));}echo join("\n",$h);

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

Розширено

$h=array_fill(0,1+2*$v=2**($c=$argn),str_pad("",4*$v)); # fill array with maximal width
for(;1+$c;$c--)  # greatest hexagon to lowest
for($i=0;$i<$e=2**$c*2+1;$i++){ # loop through the rows
    $z=$e-$i<2;$y=$i&&$i<$e/2;$x=$i>=$e/2&$i<$e-1; # booleans last first ad second half
    $h[$i]=substr_replace($h[$i], # replace substring
    $s=str_pad(
        $z?"\\":($y?"/":($x?"\\":"")),
        $e-1+$z-$y+$y*$i*2-$x+$x*2*($e-$i),
        $z|!$i?"_":" "
        ).(!$z?!$y?$x?"/":"":"\\":"/"), # with string for smaller hexagon
    $v-$z-$y*$i-$x*($e-$i), # at offset
    strlen($s));
}
echo join("\n",$h); # Output
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.