Встроенные шестиугольники!

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 Хорошо, я поменяю имя.
Товарищ SparklePony
Это может быть трудно обрабатывать большой ввод (например, 64). Есть ли предел n?
Мэтью Ро,
@SIGSEGV Нет предела.
Товарищ SparklePony
1
Было бы забавно увидеть ответ в Hexagony :))
Mr. Xcoder
1
Хех, черепаха графика моего представления кривой Коха может сделать это тоже (изменилась только первая функция). Определенно, слишком долго для этого, хотя :)
Орджан Йохансен

Ответы:

10

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

Благодаря байту @Neil удалось сэкономить 11 байт, изменив цикл while на цикл for среди других приемов.

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

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

Объяснение (устарело)

Эта программа начинается с генерации самого большого шестиугольника, а затем делает меньшие по одному в цикле while (с 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
Kritixi Lithos
источник
Я заметил, что нет "Привет, мир!" программы для Charcoal пока нет. Вы должны добавить это.
mbomb007
@ mbomb007 Разве это не просто дубликат тривиального ответа «этот язык печатает свой исходный файл, если он не содержит команд»?
Нил
Я сохранил несколько байтов, когда понял, что ×_X²ιэто то же самое ×__β, и еще несколько байтов, преобразовав ваш в a , что также избавляет от необходимости хранить входной номер. Попробуйте онлайн! ,
Нил
@Neil Спасибо, это довольно опрятно :)
Kritixi Lithos
5

Haskell , 230 217 207 байт

РЕДАКТИРОВАТЬ:

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

mпринимает Integerи возвращает 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.
Орджан Йохансен,
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>

Объяснение: Для шестиугольников после первого, предыдущий шестиугольник сначала создается и дополняется с каждой стороны (это зависит от того, является ли выход прямоугольником). (Для первого заголовка создается несколько фиктивных отступов.) Создаются верхняя и верхняя стороны шестиугольника, а все пробелы объединяются с предыдущим шестиугольником. (Есть некоторая хитрость, чтобы заставить шестиугольники выстраиваться в линию; это было бы легче, если бы были допущены дополнительные поля.) Нижние стороны шестиугольника генерируются аналогично верхним сторонам, а затем заполняется нижняя часть шестиугольника. Необходимо соблюдать осторожность, чтобы возвращать прямоугольный вывод, включая завершающий перевод строки, для рекурсии в работу.

Нил
источник
Итак, вы демонстрируете, что эта, тефлоновая и Deep Dish Pizza, действительно похожи по конструкции? Это довольно аккуратно.
AdmBorkBork
1
@AdmBorkBork У меня есть несколько других ответов, которые делают это; эти диагонали /s популярны в искусстве ASCII, и этот replaceметод является относительно дешевым способом их генерации в JavaScript.
Нил
1<<n>>1: Хорошая симметрия ;-)
Люк
@ Луки, я мог бы изменить переменную, скажем, 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
Йорг Хюльсерманн
источник