ASCII з'єднані шестикутниками


21

Огляд

Враховуючи ряд шестикутників, розташуйте їх у з'єднаній формі в межах графічного зображення 50 на 50 ASCII. Обрана вами форма може бути довільною - все, що ви вважаєте найбільш прихильним до гольфу - доки вона пов'язана. У ньому можуть бути отвори, якщо вони більше одного шестикутника (інакше кількість шестикутників буде неоднозначним).


Макет

Усі шестикутники повинні бути у такій формі (тільки цей розмір та орієнтація дійсні):

 __
/  \
\__/    Note there are 2 underscores per horizontal edge.

Два шестикутники безпосередньо пов'язані, якщо вони ділять ребро:

 __               __
/  \__           /  \
\__/  \          \__/
   \__/    or    /  \
                 \__/

Два шестикутники не з'єднані, якщо вони мають лише вершину:

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

Ділення половини ребра також не вважається підключеним:

 __
/  \
\__/
 /  \
 \__/

Колекція шестикутників пов'язана, якщо існує шлях від будь-якого шестикутника до будь-якого іншого, використовуючи лише безпосередньо з'єднані шестикутники.

Отвори

Отвір розміром із шестикутник у з’єднаній колекції шестикутників вважається шестикутником, так що будь-який фрагмент мистецтва ASCII має однозначне число шестикутників.

Це не вважається отвором, оскільки потенційний отвір - це один шестикутник:

    __
 __/  \__
/  \__/  \
\__/  \__/
/  \__/  \
\__/  \__/
   \__/      7 hexagons (not 6 with a hole)

Це робить підрахунок як отвір , так як він не відповідає одному шестикутника:

    __
 __/  \__
/  \__/  \__
\__/  \__/  \
/  \__   \__/
\__/  \__/  \
   \__/  \__/
      \__/      8 hexagons with a hole

Вхід і вихід

Вхідні дані

Ціле число від 1 до 255.

Вихідні дані

ASCII-рядок зображень, що представляє вхідну кількість з'єднаних шестикутників, як описано вище.

  • Кількість рядків (підрядків, розділених новим рядком) становить щонайбільше 50, плюс додатковий необов'язковий нижній рядок.
  • Рядки не повинні бути однакової довжини, але кожен повинен бути довжиною не більше 50.
  • Ряди нульової довжини можуть існувати над або нижче з'єднаної форми за умови, що загальна кількість рядків не перевищує 50.
  • Ряди, що містять лише пробіл, можуть існувати над або під з'єднаною формою, якщо загальна кількість рядків не перевищує 50.
  • Пробіли можуть з’являтися зліва від форми, якщо довжина рядків не перевищує 50 (форму не потрібно вирівнювати ліворуч).
  • Пробіли можуть з’являтися праворуч від форми, якщо довжина рядків не перевищує 50.
  • Будь-які символи, які не є частиною з'єднаної форми, повинні бути або пробілами, або новими рядками.

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

Приклади

Вхід: 6

Дійсні результати:

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

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

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

Недійсні результати:

    __
 __/  \__
/  \__/  \
\__/  \__/
/  \__/  \
\__/  \__/
   \__/      Invalid for 6 as the centre hole counts as a 7th hexagon.

 __    __    __      __
/  \__/  \__/  \    /  \
\__/  \__/  \__/    \__/
   \__/  \__/                Invalid as the 6 hexagons are not connected.

 __    __    __  __
/  \__/  \__/  \/  \
\__/  \__/  \__/\__/
   \__/  \__/           Invalid as vertex touching does not count as connected.

 __    __       __
/  \__/  \     /  \
\__/  \__/     \__/
/  \__/  \
\__/  \__/
   \__/       Invalid as the 6 connected hexagons are not the only visible characters.

Перемога

Виграє найкоротша дійсна відповідь у байтах.


Таблиця лідерів

(використовуючи фрагмент таблиць лідерів Мартіна )


Я побоююсь, що кожен використовуватиме перший зразок виводу, оскільки це, мабуть, найпростіший для реалізації.
Фаталізувати

1
@Fatalize мої приклади працюють лише для введення 6. Для введення 255горизонтального ряду шестикутників не впишеться в арт. 50 на 50 ASCII.
трихоплакс

Ви все ще можете просто повернути назад і заповнити рядки нижче кожного разу, коли ви досягнете межі 50 символів
Fatalize

1
@Fatalize Завдання полягає в тому, щоб мінімізувати кількість байтів у коді. Я не заперечую, якщо візерунки прості, просто буде цікаво побачити, що люди намагаються і що підходить для різних мов.
трихоплакс

@Fatalize: Я не знаю, якщо це буде коротко чи ні, але більш "цікавий" відповідь може зробити фактичний пошук, щоб побачити, де він може розмістити шестикутники, і таким чином отримати більш цікавий результат.
Alex Van Liew

Відповіді:


13

CJam, 64 57 55 байт

" __
/  \
\__/"N/{_SS/\+_47>S3*f{\+}_2>\@?}q~(*]:..e>N*

Тестуйте це тут.

Це призведе до створення наступного шаблону в стовпцях :

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

Пояснення

Це ґрунтується на чудовій підказці Денніса , яка використовує .e>для збирання арт-результатів ASCII з декількох творів. За його словами, .e>мається на увазі стихійний максимум двох масивів (або рядків), і оскільки пробіли мають найменший код символів, ми можемо використовувати це для накладення будь-яких інших символів на рядковій сітці. Крім того, якщо два масиви не мають однакової довжини, сторонні елементи довшого масиву просто копіюються без змін. Це означає, що різні візерунки навіть не повинні бути однакового розміру. Щоб застосувати це до двовимірних масивів (оскільки ми не хочемо вставляти нові рядки до самого кінця), застосовуємо .e>попарно до рядків, що дає ..e>.

Основна ідея коду - генерувати Nкопії одного шестикутника, переміщеного у потрібне положення. Ми «переміщуємо» шестикутник вертикально, попередньо додаючи порожні лінії, а по горизонталі - попередньо пробіли. Як тільки ми :..e>закінчимо, ми складаємо всі копії разом, використовуючи прекрасні (напевно, найдовший оператор, який я коли-небудь використовував у програмі CJam).

Ось код:

" __
/  \
\__/"N/    e# Get a 2D character grid of the hexagon.
{          e# Read input N, repeat this block N-1 times.
  _        e#   Make a copy, so we leave the last hexagon on the stack.
  SS/\+    e#   Prepend two empty lines.
  _47>     e#   Make a copy and discard the first 47 lines.
  S3*f{\+} e#   Prepend 3 spaces to each line. This copy has been moved back to
           e#   the top and one column to the right.
  _2>      e#   Make a copy and discard another two lines.
  \@?      e#   If any lines were left after that, pick the copy in the next column,
           e#   otherwise, stay in the same column.
}q~(*      
]:..e>     e# Wrap all the hexagons in an array and fold them into a single grid.
N*         e# Join them with newline characters.

Людина, я дійсно повинен вивчити одну з цих мов для гольфу.
Alex Van Liew

@AlexVanLiew Ви повинні! :) Але не тому, що це покращує ваші шанси на виграш у гольф-коді, а тому, що CJam - це прекрасна мова, яку цікаво програмувати, і я не знаю жодної іншої мови, на якій вищезгадане рішення (що, на мою думку, є досить елегантним) мав би сенс. ;)
Мартін Ендер

Я б, мабуть, навчився Піту чи обом; вони обоє майже одне і те ж чи одна краща за решту?
Alex Van Liew

@AlexVanLiew Я не знаю багато Pyth, але я знаю, що вони далеко не те саме. CJam - мова, що базується на стеках, в той час як Pyth виникла як скорочення Python (але тепер має власний набір вбудованих модулів). Pyth, можливо, трохи має перевагу, коли справа стосується гольфу, але мені особисто дуже подобається програмування в іншій парадигмі, тому я буду дотримуватися CJam.
Мартін Ендер

Ага, бачу. Я добре знаю Python, тому я хотів би вивчити Pyth, але якщо я знайду час, можливо, я теж спробую CJam!
Alex Van Liew

7

Пітон 2, 219 207 символів

b=bytearray(' ');h=['__ ','/  \\','\\__/'];k=range;x=input();g=[b*50for _ in k(50)]
for i in k(x):
 c=i*3%48+1;r=(i*3+1)/48*2+i%2
 for m in k(i>15,3):n=m==0;g[r+m][c+n:c+4-n]=h[m]
print"\n".join(map(str,g))

Здійснює введення на stdin.

В основному просто створюється сітка розміром 50x50 пробілів і розміщує шестикутники, де це доречно. Після 16 - го шестикутника, мені не потрібен перший ряд h(шестикутник в якості 2D масиву) , так що я використовувати i>15для запуску діапазону на 1 замість 0. c=i*3%48+1;r=(i*3+1)/48*2+i%2обчислює з olumn і г вл мені потрібно почати с. nє булевим, але використовується як ціле число для встановлення меж (оскільки h[0]всього лише 3 символи, щоб уникнути перезапису матеріалів).

Я дуже задоволений цим, я поголив близько 50 байт з початкової версії, особливо коли згадав a[x:y]=bсинтаксис.

Вихід (n = 30):

  __    __    __    __    __    __    __    __
 /  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__
 \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \
 /  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/
 \__/  \__/  \__/  \__/  \__/  \__/  \__/  \
    \__/  \__/  \__/  \__/  \__/  \__/  \__/
(plus 44 lines of spaces each 50 wide)

Оскільки дозволені рядки пробілів дозволені, я змінив створення gпросто створити 50 bytearrayс замість 3+(x>1)+x/16*2, що є точною кількістю необхідних рядків, відчепивши 12 байт.


6

Swift 2.0, 601 591 байт

import Cocoa
var a=Int(Process.arguments[1])!,b="/  \\__".join([String](count:9,repeatedValue:""))+"/",c="\\__/  ".join([String](count:9,repeatedValue:""))+"\\",d=c.startIndex,e=c.endIndex,j=[c.stringByReplacingOccurencesOfString("\\",withString:" ").stringByReplacingOccurencesOfString("/",withString:" ").substringToIndex(advance(d,3*a,e)),b.substringToIndex(advance(d,3*a+a%2,advance(e,-1)))]
while a>0{j+=[c.substringToIndex(advance(d,3*a+1,e)),b.substringToIndex(advance(d,3*a+(a+1)%2,e)]
a<=16 ?j+=[" "+j.removeLast().substringFromIndex(advance(d,1))]:()
a-=16}
for l in j{print(l)}

Бігти: swift hexagons.swift 21

Вихід:

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

Свіфт substringToIndexі stringByReplacingOccurencesOfStringвізьме так багато символів ...


Я взагалі не знаю Свіфта, але хіба немає способу побудувати цю повторювану рядок із меншим кодом?
Рето Коради

Єдиний спосіб, з якого я знаю повторити рядок, - це stringByPaddingToLength, проте в цьому випадку це буде на 11 символів довше, ніж вводити повний рядок.
Девід Скрундц

6
Я бачу, що Apple дуже любить занадто багатослівне з'єднання рядків. Не так вже й погано, як stringByAppendingStringв Objective-C, але все ж ...
Підписати

Поза кодом гольфу, це дійсно приємно, хоча це полегшує пошук методу.
JustSid

4

C, 238 байт

#define h(A) c[m+A/4][n+A%4]
i,m,n;
f(a)
{
    char c[50][51];
    for(i=0;i<50;i++)for(m=0;m<51;m++)c[i][m]=m-50?32:0;
    for(;a;)
        m=a/12*2,n=a%12*3,a--%2?m=a/12*2+1,n=a%12*3+3:0,
        h(1)=h(2)=h(9)=h(10)=95,h(4)=h(11)=47,h(7)=h(8)=92;
    for(;i;)puts(c-i--+50);
}

Для підрахунку символів враховуються лише необхідні пробіли та нові рядки.

Він просто створює матрицю символів, заповнює їх у зворотному порядку, а потім друкує всю справу.


2

JavaScript (ES6), 265 байт

A=Array;f='forEach';U=x=1;y=0;a=A.from(A(51),_=>A.from(A(51),_=>' '));d=h=>(` __
/  \\
\\__/`.split`
`[f]((l,i)=>[...l][f]((c,j)=>{if('_/\\'.indexOf(a[x+i][y+j])<0)a[x+i][y+j]=c})),(x+=U*-2+1),(U=!U),(C-y<=3?((U=x+=2),y=0):y+=3),--h?d(h):a.map(d=>d.join``).join`
`)

Шестикутники тесселятів підряд, зліва направо, чергуючись вгору та вниз - як сота - до кінця ряду.

Безголовка з описом (працює у firefox):

'use strict';
const CAP = 51;
var a = Array.from(Array(51), () => Array.from(Array(51),() => ' '))

function draw (hexagons, x, y, a, up) {
  // x, y (row, col) represents the current position of the cursor
  /*
  
    Here's a map of the first three iterations:
    
            01234567
     0        __
     1     __/  \__
     2    /  \__/  \
     3    \__/  \__/

    For the first 17 iterations, the cursor will be at:
    
      # | x | y
      ----------
      1 | 1 | 0
      2 | 0 | 3
      3 | 1 | 6
      4 | 0 | 9
      5 | 1 | 12
      6 | 0 | 15
      7 | 1 | 18
      8 | 0 | 21
      9 | 1 | 24
     10 | 0 | 27
     11 | 1 | 30
     12 | 0 | 33
     13 | 1 | 36
     14 | 0 | 39
     15 | 1 | 42
     16 | 0 | 45
     17 | 3 | 0      <- moves back to the first row

  */
` __
/  \\
\\__/`
  // split the hexagon into three lines
  .split('\n').forEach((line, index) => {
    // and for each line
    ;[...line].forEach((char, j) => {
      // if the cursor position (x, y) translated
      // by (index, j) is not already part of a hexagon
      // then replace it with the current (index, j) piece
      // of the hexagon
      /*
         0123
       0  __
       1 /  \
       2 \__/
       
      */
      if ('_/\\'.indexOf(a[x + index][y + j]) < 0)
        a[x + index][y + j] = char
    })
  })
  
  // `up` represents the next hexagon
  // if true, the next hexagon will be drawn attached to
  // the top right edge of the current hexagon
  if (up) {
    x -= 1
  // otherwise, it'll be drawn attached to the bottom right edge
  } else {
    x += 1
  }

  // move three columns to the right
  y += 3
  // change directions
  up = !up

  // if within the right boundary of the 51x51 matrix,
  // move back to the left edge and down 2 rows
  // and draw the next hexagon as an `up` hexagon
  if (51 - y <= 3) {
    y = 0
    x += 2
    up = true
  }

  // if hexagons > 0, then recurse and draw the next hexagon
  // otherwise, return the array (join the columns in each row, then join each row
  // by a new line)
  return --hexagons ?
    draw(hexagons, x, y, a, up)
    : a.map(d => d.join('')).join('\n')
}

var n = parseInt(prompt('Number to draw:'))
var r = draw(n, 1, 0, a, true)
document.write('<pre>' + r.replace(/\n/g, '<br>') + '</pre>')


2

Рубі, 120

->n{a=(1..50).map{' '*50}
n.times{|i|x=i%16*3
3.times{|j|a[47-i/16*2-x/3+j][x..x+3]=[' __ ','/  \\','\__/'][j]}}
puts a}

створює масив з 50 рядків з 50 пробілів, а потім замінює 4 символи в 3 рядках, щоб додати шестикутники:

" __ "
"/  \"
"\__/"

Оскільки перший рядок містить пробіли, після накреслення шестикутника ми не можемо побудувати інший під ним, оскільки пробіли перезаписали б попередні шестикутники.

Тому шестикутники додаються у вигляді ромба 16х16 (спотворений прямокутник) знизу вгору і косий знизу зліва вгору праворуч.

Потім рядок " __ "буде перезаписано додатковими \та /там, де це необхідно.

Ungolfed в тестовій програмі

g=->n{
  a=(1..50).map{' '*50}              #make an array of 50 strings of 50 spaces
  n.times{|i|                        #loop through all hexagons
    x=i%16*3                         #x coordinate of top left corner of hexagon, 16 per row
    3.times{|j|                      #loop through 3 lines to print hexagon.
      a[47-i/16*2-x/3+j][x..x+3]=    #47-i/16*2 : start at the bottom and work up. each row is 2 lines high and contains 16 hexagons. x/3 : slant upwards as the row moves right. 
       [' __ ','/  \\','\__/'][j]    #These are the symbols for each of the 3 lines required for a hexagon. [x..x+3] defines which characters have to be replaced in each string.
    }      
  }
  puts a                             #print to stdout
}

N=gets.to_i
g.call(N) 

Типовий вихід (n = 250)

Тут має бути ще кілька рядків пробілів на вершині, щоб їх було 50, але я не знаю, чи є спосіб отримати Stackexchange у формат, щоб включити їх.

                                              __  
                                           __/  \ 
                                        __/  \__/ 
                                     __/  \__/  \ 
                            __    __/  \__/  \__/ 
                         __/  \__/  \__/  \__/  \ 
                      __/  \__/  \__/  \__/  \__/ 
                   __/  \__/  \__/  \__/  \__/  \ 
                __/  \__/  \__/  \__/  \__/  \__/ 
             __/  \__/  \__/  \__/  \__/  \__/  \ 
          __/  \__/  \__/  \__/  \__/  \__/  \__/ 
       __/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
    __/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
 __/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/    
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/       
\__/  \__/  \__/  \__/  \__/  \__/  \__/          
/  \__/  \__/  \__/  \__/  \__/  \__/             
\__/  \__/  \__/  \__/  \__/  \__/                
/  \__/  \__/  \__/  \__/  \__/                   
\__/  \__/  \__/  \__/  \__/                      
/  \__/  \__/  \__/  \__/                         
\__/  \__/  \__/  \__/                            
/  \__/  \__/  \__/                               
\__/  \__/  \__/                                  
/  \__/  \__/                                     
\__/  \__/                                        
/  \__/                                           
\__/                                              
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.