Я хочу соты


39

Напишите самую короткую программу, которая печатает этот художественный раздел ASCII из шестиугольной плитки или соты :

       __
    __/  \__
 __/  \__/  \__
/  \__/  \__/  \
\__/  \__/  \__/
/  \__/  \__/  \
\__/  \__/  \__/
/  \__/  \__/  \
\__/  \__/  \__/
   \__/  \__/
      \__/
  • Вклад не должен быть взят.
  • Выведите на стандартный вывод или ближайшую альтернативу вашего языка.
  • Вместо программы вы можете написать именованную функцию, которая не принимает параметров и обычно печатает результат или возвращает его в виде строки.
  • Выходные данные могут иметь любое количество начальных и / или конечных новых строк, и каждая строка в выходных данных может иметь любое количество начальных и / или конечных пробелов (при условии, что шаблон выстраивается правильно).
  • Самый короткий код в байтах побеждает.

13
Ты много играешь в катан?
user3490

@ user3490 На самом деле я делаю ^^
Увлечения Кэлвина

2
На следующей неделе на PCG: написать генератор Catan Board?
user3490

7
У него должен быть вход IMO, в вашем случае это должно быть 3.
user3819867

3
@ user3819867 Я считал это, но предпочел это. Уже слишком поздно, чтобы измениться, но еще не слишком поздно, чтобы кто-то мог сделать связанный вызов.
Увлечения Кэлвина

Ответы:


33

CJam, 45 43 42 41 40 байт

741e8 36+Ab"\__/  "38*21/.{G2$-<\S*.e<N}

Попробуйте онлайн в интерпретаторе CJam .

Как это работает

"\__/  "38*21/

повторяет шаблон \__/ 38 раз и разбивает его на куски длиной 21 . Если бы фрагменты были разделены переводом строки, это было бы результатом:

\__/  \__/  \__/  \__
/  \__/  \__/  \__/  
\__/  \__/  \__/  \__
/  \__/  \__/  \__/  
\__/  \__/  \__/  \__
/  \__/  \__/  \__/  
\__/  \__/  \__/  \__
/  \__/  \__/  \__/  
\__/  \__/  \__/  \__
/  \__/  \__/  \__/  
\__/  \__/  \__/  

Это явно содержит желаемые соты. Все, что осталось сделать, это заменить некоторые символы пробелами, отрезать некоторые другие и фактически ввести перевод строки.

741e8 36+Ab

генерирует целое число 74 100 000 036 и преобразует его в массив [7 4 1 0 0 0 0 0 0 3 6] . Каждый элемент массива кодирует количество начальных символов соответствующей строки, которые должны быть заменены пробелами. Вычитая это число из 16 , мы также получаем правильную длину для этой линии.

.{            } e# Execute for each pair of a digit D and a line L:
  G2$-<         e#   Chop off L after 16 - D characters.
       \S*      e#   Push a string of D spaces.
          .e<   e#   Compute the vectorized minimum.
             N  e#   Push a linefeed.

Поскольку пробел имеет более низкую кодовую точку, чем другие символы L, и векторизованные операторы оставляют символы более длинной строки, которые не соответствуют ни одному из более коротких строк, нетронутыми, .e<первые символы D заменяются пробелами.


2
Это великолепно. Хорошо сделано.
Алекс А.

28

Python 2, 73

i=0
exec"k=max(7-i,i-24,0);print' '*k+('\__/  '*9)[i:][k:16-k];i+=3;"*11

Смотри, беги.

Для каждой из 11 выходных строк вычисляется количество первых пробелов kкак максимум трех линейных функций, которые образуют оболочку левой стороны шестиугольника. Поскольку диагональные линии имеют наклон 3и -3, лучше индексировать номер строки как i=0,3,...30.

Чтобы создать шестиугольную сетку, мы сначала разбиваем плитку на части '\__/ '. Затем сдвиг [i:]выравнивает его на 3 для нечетных строк. Наконец, мы берем необходимую часть [k:16-k], оставляя поле kслева и справа.


22

CJam, 65 56 55 байт

"Ý6TNð*¯5"303b4b["/\_")"_ "4*S]f=sB/z{_W%"\/"_W%erN}/

Попробуйте онлайн в интерпретаторе CJam .

идея

Правая половина каждой строки - это перевернутая копия левой половины с пометкой косой черты и обратной косой черты. Поэтому достаточно кодировать левую половину соты:

       _
    __/ 
 __/  \_
/  \__/ 
\__/  \_
/  \__/ 
\__/  \_
/  \__/ 
\__/  \_
   \__/ 
      \_

Вместо того, чтобы анализировать этот шаблон построчно, мы можем проанализировать его столбец за столбцом:

   /\/\/\  
  _ _ _ _  
  _ _ _ _  
  /\/\/\/\ 
 _ _ _ _ _ 
 _ _ _ _ _ 
 /\/\/\/\/\
_ _ _ _ _ _

Очевидные образцы появляются:

  • Строка _ _ _ _встречается пять раз.
  • Каждый /сопровождается \.

Заменив каждый /\, _, _ _ _ _и пространство с числом от 0 до 3, мы можем преобразовать результирующий массив из числа базового 4 до более высокой базы и сохранить полную картину в компактном виде.

Код

"Ý6TNð*¯5"303b4b  e# Convert the string from base 303 to base 4.
["/\_")"_ "4*S]f= e# Replace each resulting digit by the corresponding item of the array
                  e# ["/\" "_" "_ _ _ _ " " "].
sB/               e# Split into strings of length 11.
z                 e# Zip: transpose rows with columns.
{             }/  e# For each string:
 _W%              e#     Push a reversed copy.
    "\/"_W%er     e#     Swap slashes and backslashes.
             N    e#     Push a linefeed.

10

C 148 144 140 байт

k,r,c,d,p;f(){for(;k<187;k++){r=k/17;c=k%17;d=c+r%2*3;p=3*r+c-7<33u&3*r-c+8<33u;putchar(c==16?10:p&(d+5)%6<2?95:p&d%6==3?47:!p|d%6?32:92);}}

С пробелами, без предупреждений компилятора и перед настройкой кода для сохранения нескольких байтов:

#include <stdio.h>

int k, r, c, d, p;

void f() {
    for ( ; k < 187; k++) {
        r = k / 17;
        c = k % 17;
        d = c + 3 * (r % 2);
        p = 3 * r + c - 7 < 33u && 3 * r - c + 8 < 33u;
        putchar(
            c == 16 ? 10 :
            p && (d + 5) % 6 < 2 ? 95 :
            p && d % 6 == 3 ? 47 :
            p && d % 6 == 0 ? 92 :
            32);
    }
}

Этот подход не использует никаких таблиц символов / строк. Он перебирает все 187 (11 строк, 17 столбцов, включая переводы строк) и решает, какой символ печатать для каждой позиции, на основе комбинации условий.

Условия включают в себя проверку на наличие внутри / снаружи 4 углов, используя 4 линейных уравнения, с результатом, сохраненным в переменной p. Остальное в основном повторяется каждые 6 символов, причем нечетные строки сдвигаются на 3 символа относительно четных строк.


2
Для игры в гольф вы можете использовать implicit-int и отбросить int .
Люсер Дрог

Несколько микро-улучшений:k;f(r,c,d,p){for(;k<187;putchar(c>15?10:p&d<2&p?95:p&d<3?47:!p|d-5?32:92))r=k/17,c=k++%17,d=(5+c+r%2*3)%6,p=3*r+c-7<33u&3*r-c+8<33u;}
Денис

7

Рубин - 78 байт

(-5..5).map{|i|puts' '*(j=[i.abs*3-i/6-9,0].max)+('/  \__'*4)[j+i%2*3,16-j*2]}

Транскрипция решения xnor (69 байт):

11.times{|i|puts' '*(j=[7-i*=3,i-24,0].max)+('\__/  '*9)[i+j,16-j*2]}

1
11.timesсохраняет 2 байта
Митч Шварц

6

JavaScript (ES6), 129 130

Это чистая строка replace / replace / replace ... без использования каких-либо геометрических свойств.

Используя строки шаблона, все новые строки значимы и считаются.

Запустите фрагмент в Firefox для проверки

f=_=>`70
405
 055
9992 3051
6301`[R='replace'](/9/g,`55123
30551
`)[R](/5/g,1230)[R](/\d/g,n=>['__','/',,'\\'][n]||' '.repeat(n))

// TEST

O.innerHTML = f()
<pre id=O></pre>


6

PHP - 139 137 107 101 91 87 байт

Я не знаю, является ли это лучшим способом игры в гольф, но вот моя попытка:

30 36 46 -50 байт благодаря Исмаилу Мигелю

Проверьте это онлайн здесь

<?='       __
    __',$a='/  \__',"
 __$a$a
",$c="$a$a/  \
\__$a$a/
","$c$c   \__$a/
      \__/";

<script src="http://ideone.com/e.js/WHWEZS" type="text/javascript" ></script>

старый код:

<?php $a="/  \\__";$c=$a.$a."/  \\\n\__".$a.$a."/\n";echo "       __\n    __".$a."\n __".$a,$a."\n".$c,$c,$c."   \\__".$a."/\n      \\__/";

Добро пожаловать в Программирование головоломок и Code Golf. Ваш код PHP может быть уменьшен намного больше. Вы можете использовать <?вместо того, <?phpчтобы сохранить 3 байта. Вместо этого $c=$a.$a."/ \\\n\__".$a.$a."/\n";вы можете писать $c="$a$a/ \\\n\__.$a$a/\n";(поскольку PHP расширяет переменные в строках). Вы можете применить ту же логику к, echoчтобы еще больше уменьшить ее длину. Кроме того, вам не нужно пространство между echoстрокой и.
Исмаэль Мигель

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

Добро пожаловать. Вот решение длиной 99 байт: ideone.com/WHWEZS . Это выглядит беспорядок, но это намного короче. Вместо использования \nвы можете поставить реальный символ новой строки и сохранить 1 байт на строку.
Исмаэль Мигель

Тем временем я уменьшил его на 2 байта. Теперь у него есть 97 байтов.
Исмаэль Мигель

1
Вот один вкладыш: <?="\t __\n\t__",$a='/ \__',"\n __$a$a\n",$c="$a$a/ \\\n\__$a$a/\n","$c$c \__$a/\n\t \__/";. Не забудьте заменить \tсимвол табуляции и \nреальный перевод строки.
Исмаэль Мигель

4

Луа 146

T="       __\n    __/  \\__\n __/  \\__/  \\__\n"
S="/  \\__/  \\__/  \\\n\\__/  \\__/  \\__/\n"
B="   \\__/  \\__/\n      \\__/"
io.write(T,S,S,S,B)

(новые строки добавлены для ясности)


1
Разве этот код не длиннее желаемого вывода, потому что он содержит только вывод плюс экранирование и обработку строк?
Калеб

6
@Caleb: Я подозреваю, что вы на самом деле не посчитали и не догадались сделать этот комментарий. Согласно моему текстовому редактору, в решетке 165 символов (включая новые строки). У меня на 19 символов меньше из-за повторения Sтри раза.
Кайл Канос

2
Но вы правы в том, что экранирование и переводы строк ограничивают способность моего кода конкурировать в этой конкретной игре. Но победа также не для того, чтобы я это делал, это для удовольствия и обучения.
Кайл Канос

3

Дротик - 113

main({r:"/  \\__"}){print("       __\n    __$r\n __$r$r\n${"$r$r/  \\\n\\__$r$r/\n"*3}   \\__$r/\n      \\__/");}

Чистое решение для интерполяции строк, ничего особенного. Строковые операции, подобные «подстроке», слишком многословны, чтобы конкурировать на практике.

Запустите его на DartPad .


3

Javascript ( ES7 Draft ), 96 94 93 байта

Вдохновение взято из нескольких решений здесь ...

Изменить: -1 из edc65

f=z=>[for(x of[741e6]+36)' '.repeat(x)+'/  \\__'.repeat(4,z^=3).slice(+x+z,16-x+z)].join(`
`)

// For snippet demo:
document.write('<pre>'+f()+'</pre>');

комментарии:

f=z=>[                                 
        for(x of [741e6] + 36)        // for each character "x" in "74100000036"
            ' '.repeat(x) +           // x spaces
            '/  \\__'.repeat(4,       // build pattern string
            z ^= 3).                  // toggle z offset (3) for even lines
            slice(+x + z, 16 - x + z) // get appropriate substring
    ].join(`                          // join with newlines
    `)

Хороший. .substr(+x+z,16-x-x)-> .slice(+x+z,16-x+z)-1
edc65

@ edc65 хороший улов!
nderscore

Быстрый вопрос: почему это +xвместо просто x?
Фонд Моники иск

1
@QPaysTaxes Это приведение xк числу. Без этого он бы объединялz
nderscore

2

Питон 3, 100 87 байт

n=0x85208e08e08dd445
while n:l=n>>2&15;print(' '*(8-l)+('\__/  '*4)[n&3:n&3|l*2]);n>>=6

И читаемая версия кода ниже. Идея состоит в том, чтобы жестко закодировать интервалы (начало, длина), а затем дополнить нужным количеством пробелов для центрирования интервала.

hexagon_string = '\__/  ' * 4
for i in range(11):
    # Pick the begin and length of the i-th interval using hardcoded numbers
    b = (0x00030303111 >> 4*i) & 3   # n is a combination of these two numbers
    l = (0x25888888741 >> 4*i) & 15  #
    # Print the interval with appropriate whitespace in front of it
    spaces = ' ' * (8-l)
    print(spaces + hexagon_string[b : b+l*2])

2

Сетчатка , 66 байт

<empty line>
sss __<LF>ssa__<LF> aa__<LF>lll dau<LF>ssdu
l
/daa<LF>\aau<LF>
a
ud
u
__/
d
s\
s

Каждая строка должна идти в свой собственный файл и <LF>означает фактическую новую строку в файле. 1 байт на дополнительный файл добавляется в счетчик байтов.

Вы можете запустить код как один файл с -sфлагом, сохранив <LF>маркеры и, возможно, заменив их на новые строки в выходных данных для удобства чтения.

Алгоритм состоит из 5 простых шагов замещения (изменение содержимого нечетной строки на содержимое четной строки), начиная с пустой входной строки. Результаты после каждого шага (ограничены =с):

sss __
ssa__
 aa__
lll dau
ssdu
============
sss __
ssa__
 aa__
/daa
\aau
/daa
\aau
/daa
\aau
 dau
ssdu
============
sss __
ssud__
 udud__
/dudud
\ududu
/dudud
\ududu
/dudud
\ududu
 dudu
ssdu
============
sss __
ss__/d__
 __/d__/d__
/d__/d__/d
\__/d__/d__/
/d__/d__/d
\__/d__/d__/
/d__/d__/d
\__/d__/d__/
 d__/d__/
ssd__/
============
sss __
ss__/s\__
 __/s\__/s\__
/s\__/s\__/s\
\__/s\__/s\__/
/s\__/s\__/s\
\__/s\__/s\__/
/s\__/s\__/s\
\__/s\__/s\__/
 s\__/s\__/
sss\__/
============
       __
    __/  \__
 __/  \__/  \__
/  \__/  \__/  \
\__/  \__/  \__/
/  \__/  \__/  \
\__/  \__/  \__/
/  \__/  \__/  \
\__/  \__/  \__/
   \__/  \__/
      \__/

1

Javascript, 154 151 байт

b="\n",c="\t",d="/  \\",f="__",g="\\",h="/",a=f+d,j=a+a,i=d+j+b+g+j+f+h+b,k="   ";console.log(c+k+f+b+c+a+f+b+" "+j+f+b+i+i+i+k+g+a+f+h+b+c+"  "+g+f+h)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.