Нарисуйте шестиугольник ASCII со стороной n.

Jan 06 2021

Для целого положительного числа \$n\$вывести шестиугольник ASCII с диагональной стороной \$n\$, как на фото (обратите внимание, что есть \$2n\$ _ символы на верхнем краю)

Примеры:

\$n = 1\$

 __
/  \
\__/

\$n = 2\$

  ____
 /    \
/      \
\      /
 \____/

\$n = 5\$

     __________
    /          \
   /            \
  /              \
 /                \
/                  \
\                  /
 \                /
  \              /
   \            /
    \__________/

и т.п.

Самый короткий код в байтах побеждает. Применяются обычные методы ввода / вывода .

Ответы

11 Razetime Jan 06 2021 at 16:01

Холст , 15 9 байт

 _;1*⁸/∔╬

Попробуйте здесь!

-6 байт после исправления программы.

Рисует четверть шестиугольника, и четырехугольник палиндромизирует.

9 xnor Jan 06 2021 at 17:16

Python 2 , 92 байта

k=n=input()
while 1:a=k^k>>n;print" "*a+"\/_"[k/n-2]+"_ "[-n<k<n]*2*(2*n+~a)+"\_/"[k/n];k-=1

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

6 Razetime Jan 06 2021 at 15:54

Уголь , 14 байт

←×_θ↖θ→↗θ×_θ‖M

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

+1 байт исправление из ASCII-Only.

Рисует половину шестиугольника и отражает его.

6 AZTECCO Jan 07 2021 at 15:50

C (gcc) , 119 109 байт

a,i,j;f(n){for(i=a+=a=j=n*2;~j;)putchar(!i--?i=a,j--,13:i%(n*3)<n|j%(n*2)?(i-~j-n)%a?(i-j+n)%a?32:92:47:95);}

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

  • сэкономлено 2 благодаря @ceilingcat

Таблица ниже не обновляется, поэтому значения могут отличаться, но концепция такова:

  • у нас есть 2 пары параллельных линий
        . .
_______.______.________   
  | / \ | .
. | / \ | .
 . | / \ |.
  | / \ |
  | \ / |.
 . | \ / | .
. | \ / |
__ | ___ \ ________ / ___ | ___   
  | . .

мы выполняем итерацию x, y от размера до 0 и суммируем их, чтобы проверить, следует ли печатать /, вычитаем, чтобы проверить \, мы используем по модулю, чтобы проверить обе параллели.

    я 65432109876543210. j
 i + jn ________ 8 
13 + 7-4 => / \ 7 
14 + 6-4 / \ 6 
15 + 5-4 / \ 5 
      / \ 4 
      \ 1 + 3-4 => / 3
       \ 2 + 2-4 / 2
        \ 3 + 1-4 / 1
         \ ________ / 0
5 NahuelFouilleul Jan 07 2021 at 03:22

Perl 5 ( -p), 102 байта

s/_+/__$&/g,s/^|$/ /gm,s/^ *\S /$& /gm,s-( +)\\ -$&/ $1 \\ \\ $1 /
- for($\=' __ / \ \__/')x--$_}{

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

-pи }{в конце есть уловка, чтобы напечатать только разделитель выходной записи $\в конце. Это работает только для одной входной записи; заголовок используется для печати всего в одной ссылке.

$\=' __ 
/  \
\__/'   # output record separator initialized with hexagon (size 1)

s/_+/__$&/g,s/^|$/ /gm,s/^ *\S /$& /gm,s-( +)\\ -$&/ $1 \\ \\ $1 /
- # regexes to increase the hexagon by 1

for .. --$_ # to repeat n-1 times where n is the input
5 WheatWizard Jan 08 2021 at 23:56

Haskell , 150 байт

r=reverse
m(o:c:k)=o:c:c:c:k++" "
f 1=[["\\  /","__ "],["/__\\"]]
f n|[w:i,j]<-map m<$>f(n-1),_:_:k<-r$m w=[r k:w:i,k:j]
h[i,j]=unlines$r<$>r i++j
h.f

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

Более рекурсивная версия этого ответа. Произвол этого вызова делает это довольно неприятным.

Объяснение

Этот ответ сложно объяснить. Проблема, как я уже сказал, произвольна в нескольких отношениях, поэтому код представляет собой своего рода набор символов.

Идея

Идея программы состоит в том, чтобы построить две половинки. То есть при вычислении n-го шестиугольника мы получаем две половины для n-1-го шестиугольника и используем их для создания следующей по величине.

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

подробности

Первая строка довольно прямолинейна r- это псевдоним для reverse. Вторая линия не так прямолинейна. m- бессмысленная функция, она существует потому, что ее или аналогичную операцию нужно выполнить в нескольких местах. На самом деле это не имеет смыслового значения. Лучшее объяснение того, что он здесь делает, - это код.

m(o:c:k)=o:c:c:c:k++" "

Отсюда мы начинаем переходить к тому, fчто обрабатывает в основном всю логику. Первый случай f- это базовый вариант, он довольно стандартный

f 1=[["\\  /","__ "],["/__\\"]]

Обратите внимание, что мы возвращаем список из двух элементов вместо кортежа. В любой разумной программе мы будем использовать кортеж, поскольку он состоит из двух элементов. Однако позже мы сопоставим оба аргумента this с той же функцией. Это сложно сделать с кортежем, но легко со списком, и список не имеет никаких недостатков, поэтому мы его используем.

Тогда у нас есть индуктивный случай. Сначала мы извлекаем предыдущий случай и дважды сопоставляем mего. Это делает шестиугольник на 1 единицу шире (2 символа) и перемещает его на половину единицы (1 символ) вправо (хотя, поскольку все это происходит в обратном направлении, символы пробела добавляются справа ). Мы сопоставим это с шаблоном, [w:i,j]потому что хотим использовать его wдля создания новых строк позже. Говоря о том, что дальше делаем ряды. Мы делаем это с сопоставлением с образцом:

_:_:k<-r$m w

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

После того, как fу нас есть, hкоторый превращает вывод fв строку. Он отменяет все дурацкие преобразования, которые мы использовали во время конструирования, и упаковывает их для использования.

При этом мы просто сочиняем fи hдля финальной функции.

5 xnor Jan 11 2021 at 00:58

Haskell , 100 байт

f n=unlines[q<$>[1..3*n]++[1-n..0]|y<-[-n..n],let q x|abs y==n,x>n='_'|x==y='\\'|x+y==1='/'|1>0=' ']

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

Ответ AZTECCO на гольф плюс некоторые новые техники.

Основная идея в том, что шестиугольник проще, если первые nстолбики пересадить в конец.

|-|
   ______   
  /      \  
 /        \ 
/          \
\          /
 \        / 
  \______/  

         |-|
______      
      \    /
       \  / 
        \/  
        /\  
       /  \  
______/    \

Теперь все /и \находятся в одной строке, а _все слева от них. Это значительно упрощает реализацию стратегии AZTECCO по определению символа по координате. Чтобы реализовать эти перемаркированные координаты, мы заменяем x-координаты [1..4*n]на зацикленную и сдвинутую версию [1..3*n]++[1-n..0].

4 Neil Jan 06 2021 at 17:08

Retina 0.8.2 , 94 байта

.+
$* ¶$&$* \G ¶$%'/$`$%_$%_$`\
r` \G
$%`\$'$%_$%_$%'/¶ ^¶( *) $1 $.&$*_$.&$*_$& T` `\_` +/$

Попробуйте онлайн! Ссылка включает тестовые примеры. Пояснение:

.+
$* ¶$&$* 

Вставьте два ряда nпробелов.

\G 
¶$%'/$`$%_$%_$`\

Преобразуйте первый ряд в верхние стороны шестиугольника.

r` \G
$%`\$'$%_$%_$%'/¶

Преобразуйте второй ряд в нижние стороны шестиугольника.

^¶( *)
$1 $.&$*_$.&$*_$&

Вставьте верхнюю строку.

T` `\_` +/$

Заменить нижнюю строчку.

4 ovs Jan 06 2021 at 16:32

Python 2 , 119 114 байт

i=n=input()
d=0
exec"k=i/n|d;print' '*i+'\_/'[~k]+'_ '[i-d<n]*2*(2*n+~i)+'\_/'[k]\nif i==d:d=i=-1\ni-=d|1;"*(n-~n)

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

4 Arnauld Jan 07 2021 at 03:27

JavaScript (ES6),  109  107 байт

w=>(x=0,W=w*4,i=g=y=>~y?`
 /\\_`[x++-W?y*!i|w/x|x>w*3?(x+~y+w)%W?(x+y)%W-w?1:3:2:4:x=i=0&y--]+g(y):'')(w*2)

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

Прокомментировал

w => (                        // w = input
  x = 0,                      // initialize x to 0
  W = w * 4,                  // W = total width
  i =                         // initialize i to a non-zero value
  g = y =>                    // g is a recursive function taking y
  ~y ?                        //   if y is not equal to -1:
    `\n /\\_`[                //     list of characters
      x++ - W ?               //     if this is not the end of the row:
        y * !i |              //       if this is neither the first nor the last row
        w / x |               //       or x is less than or equal to w
        x > w * 3 ?           //       or x is greater than w * 3:
          (x + ~y + w) % W ?  //         if (x - y - 1 + w) mod W is not equal to 0:
            (x + y) % W - w ? //           if (x + y) mod W is not equal to w:
              1               //             draw a space
            :                 //           else:
              3               //             draw a '\'
          :                   //         else:
            2                 //           draw a '/'
        :                     //       else:
          4                   //         draw a '_'
      :                       //     else:
        x = i = 0 & y--       //       decrement y, set x and i to 0 and draw a linefeed
    ] + g(y)                  //     append the result of a recursive call
  :                           //   else:
    ''                        //     stop the recursion
)(w * 2)                      // initial call to g with y = w * 2
4 Noodle9 Jan 06 2021 at 21:18

С (gcc) , 194 \$\cdots\$ 149 144 байта

Сохранено 13 14 19 байт благодаря потолку !!!

p(n,c){for(;n--;)printf(L"/\\ _\n"+c);}i;t;f(n){p(n,2);for(i=t=p(2*n,3);i>=p(1,4);t=i/n?--i,1:t)i+=!p(!p(n+i<<!p(!p(n+~i,2),t),t&!i|2),!t)-2*t;}

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

Объяснение (перед гольфом)

p(n,c){for(;n--;)                     // Helper function to print  
         putchar("/\\ _\n"[c]);}      //  one of '/', '\', ' ', '_' , or  
                                      //  newline n times, this function  
                                      //  also returns 0 
i;t;f(n){                             // Main function prints an n hexagon  
        p(n,2);                       // Print n leading spaces for the 1st  
                                      //  line 
        for(                          // Main loop
            i=t=p(2*n,3);             // Set i and t to 0,  
                                      //  and print 2*n '_'s for the 1st line
            i>=p(1,4);                // Loop until i goes below 0, and 
                                      //  print a newline
                                      // At the end of each loop:  
            i+=1-2*t,                 //  increment i for the 1st half  
                                      //   and then decrement i in the 2nd  
            t=i/n?--i,1:t)            //  keep t as t unless i equals n,   
                                      //  then make t 1 and decrement i   
                                      // In the main loop:
                p(n+~i,2),            //  print n-i-1 leading spaces     
                p(1,t),               //  print a '/' in the 1st half and a  
                                      //   '\' in the 2nd    
                p(n+i<<1,t&!i|2),     //  print the 2*(n+i) middle spaces  
                                      //   unless at the bottom print '_'s  
                p(1,!t);              //  print a '\' in the 1st half and a  
                                      //   '/' in the 2nd    
   }  
 
4 ovs Jan 07 2021 at 05:12

05AB1E , 33 29 25 байт

-4 ( 7 ) байта благодаря Кевину Кройссену !

L+<'/úíºI·'_ך»∊¶¡`ðs‡).c

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

05AB1E имеет брезентовую встроенную команду , которая может оказаться полезной, но довольно сложно получить работу, это просто зеркало встроенных функций ºи и централизовать встроенный .c.

4 xash Jan 07 2021 at 01:26

J , 50 47 байт

-3 спасибо Ионе!

' \/_'{~]|."1((0,]+2*|.)@=@i.,.3,3,~0$~<:,])@+:

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

((0,]+2*|.)@=@i.  ,.  3,3,~0$~<:,])@+:
     0 0 0 0            3 3 3 3
     1 0 0 2            0 0 0 0
     0 1 2 0            0 0 0 0
     0 2 1 0            0 0 0 0
     2 0 0 1            3 3 3 3

    ]|."1
0 0 3 3 3 3 0 0
0 2 0 0 0 0 1 0
2 0 0 0 0 0 0 1
1 0 0 0 0 0 0 2
0 1 3 3 3 3 2 0

' \/_'{~ 
  ____
 /    \    
/      \    
\      /  
 \____/  
4 Anakhand Jan 06 2021 at 17:25

Python 3.8 (предварительная версия) , 174 байта

n=int(input())
b,a,s="\/ "
z,f=range(n),lambda c,d,t:((n-1-i)*s+c+2*(n+i)*s+d for i in t)
print(f"{'_'*2*n:^{4*n}}",*f(a,b,z),*f(b,a,z[:0:-1]),f"{b:>{n}}{'_'*2*n}/",sep="\n")

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

-1 байт благодаря @Duncan

-8 байт благодаря @Danis

4 AZTECCO Jan 10 2021 at 18:02

Haskell , 129 120 байт

g=mod
f n|a<-n*4=[c|y<-[-n..n],x<-[0..a],let c|x<1='\n'|g x(n*3+1)>n,abs y==n='_'|g(x+y)a==1='/'|g(x-y)a<1='\\'|1>0=' ']

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

  • спасло 9 благодаря @Wheat Wizard и @xnor.

  • Проверьте ответ @xnor и его большое улучшение в подходе к проблеме (избегая по модулю и параллельных линий)!

  • Эквивалент моего ответа C

Мы составляем декартовы координаты, используя понимание списка | y <- [0..n * 2], x <- [0..a]

[c | ..., пусть c | ... | ... | ...] и мы выделили необходимый символ на основе xy или x + y для рисования линий.
Мы используем модуль для рисования нескольких линий (2).
Особый случай, _когда не требуется соотношение осей / y, а требуется диапазон, мы используется по модулю, чтобы выполнить только одно сравнение >вместо a> x> b, например

2 vrintle Jan 06 2021 at 15:15

Ruby , 141 байт

->(n,g=->c,d{(1..n).map{|i|" "*(n-i)+d+" "*2*(n+i-1)+c}},l=g[?/,e=?\\].reverse){[" "*n+?_*n*2,g[e,?/],l[0..-2],l[-1].sub(/ +(?=\/)/,?_*n*2)]}

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

Если верхнее подчеркивание разрешено, то потребуется немного меньше байтов, а шестиугольник будет таким же красивым, как и раньше ;-)

Рубин , 114 байтов

->n{[" "*n+?_*2*n,(g=->c,d{(1..n).map{|i|" "*(n-i)+c+" "*2*(n+i-1)+d}})[?/,e=?\\],g[e,?/].reverse," "*n+?‾*n*2]}

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

2 Makonede Jan 07 2021 at 00:45

05AB1E , 70 байт

ðש'_¹·×«©¶«©¹'/1Λ¹·Ì'.2Λ¹'\3.Λ«©„./`.;©¶¡Â‚€»`s'.ð:,¹3*>(£„._`:„/\‡,

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

2 KjetilS. Jan 07 2021 at 00:54

Perl 5 , 143 байта

sub f{$n=pop;@b=map{join'',$"x($n-$_),'/','  'x($n+$_-1),'\\',$/}1..$n;join('',$"x$n,$u=__ x$n,$/,@b,map y|/\\|\\/|r,reverse@b)=~s| +/$|$u/|sr}

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

sub f{
  $n=pop;             #n = input
  @b=map{             #set array @b to line 2 - n+1
    join'',           #join parts into a line string
    $" x ($n-$_), #space times n-1 '/', #char / ' ' x ($n+$_-1), #space times n+iterator minus 1 '\\', #char \ $/                #char newline
  } 1..$n; #n lines join('', #return string of these joined: $" x $n, #n spaces $u = __ x$n, #n*2 underscores $/,               #char newline
    @b,               #lines 2 to n+1 constructed above
    map y|/\\|\\/|r,  #and bottom part which is the same
      reverse@b       #as top part reversed and /\ rotated
  )=~s| +/$|$u/|sr    #and change last spaces of last line to _'s
}
2 StevenFontanella Jan 07 2021 at 12:31

Haskell , 186 168 байт

-18 байт с исправлениями xnor и удалением ненужных пробелов в последней строке

s=' '
(!)=replicate
e=reverse
h n=unlines$(\m->(n!s++(2*n)!'_'++n!s):e(e<$>m)++init m++[(n-1)!s++'\\':(2*n)!'_'++"/"])$(\i->i!s++'\\':(4*n-2*i-2)!s++'/':i!s)<$>[0..n-1]

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

Без гольфа:

hex :: Int -> String
hex n = unlines $ first: middle ++ (init $ reverse (map reverse middle)) ++ [last]
  where
    first = replicate n ' ' ++ replicate (2*n) '_' ++ replicate n ' '
    f i = replicate i ' ' ++ "/" ++ replicate (n-i + 2*n + n-i -2) ' ' ++ "\\" ++ replicate i ' '
    middle = map f [n-1,n-2..0]
    last = replicate (n-1) ' ' ++ "\\" ++ replicate (2*n) '_' ++ "/" ++ replicate (n-2) ' '