Мені хочеться соти


39

Напишіть найкоротшу програму, яка друкує цей художній розділ ASCII шестикутної черепиці або сот :

       __
    __/  \__
 __/  \__/  \__
/  \__/  \__/  \
\__/  \__/  \__/
/  \__/  \__/  \
\__/  \__/  \__/
/  \__/  \__/  \
\__/  \__/  \__/
   \__/  \__/
      \__/
  • Не слід брати жодної інформації.
  • Вихід у stdout або найближча альтернатива вашої мови.
  • Замість програми ви можете записати іменовану функцію, яка не приймає жодних параметрів і нормально друкує результат або повертає його як рядок.
  • Вихід може мати будь-яку кількість провідних та / або кінцевих нових рядків, і кожен рядок у виводі може мати будь-яку кількість провідних та / або проміжних пробілів (до тих пір, поки шаблон буде лінійно належним чином.)
  • Виграє найкоротший код у байтах.

13
Ви багато граєте в катан?
користувач3490

@ user3490 Насправді я роблю ^^
захоплення Кальвіна

2
Наступного тижня на PCG: написати генератор плати Catan?
користувач3490

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

Пітон 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 .

Ідея

Права половина кожного рядка - це зворотна копія лівої половини з напущеними косою рисою та зворотними косими рисами. Тому достатньо закодувати ліву половину соти:

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

Замість того, щоб аналізувати цей шаблон за рядком, ми можемо аналізувати його колонку за стовпцем:

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

Виявляються чіткі закономірності:

  • Рядок _ _ _ _виникає п'ять разів.
  • За кожним /слід a \.

Замінивши кожен /\, _, _ _ _ _і простір з числом від 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 та drop int .
luser droog

Кілька мікрополіпшень: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

Це чистий рядок заміни / заміни / заміни ..., не використовуючи жодної геометричної властивості.

Використовуючи рядки шаблону, всі нові рядки є значущими та рахуються.

Запустіть фрагмент у 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      \\__/";

Ласкаво просимо до головоломки програмування та коду для гольфу. Ваш 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
об'єднався

2

Python 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 простих етапів заміщення (зміна вмісту непарних рядків на парний вміст рядка), починаючи з порожнього рядка введення. Результати після кожного кроку (відмежовані ='s):

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.