Гексплозивний ASCII-мистецтво виклик


20

У стратегічній грі "Hexplode" гравці по черзі розміщують жетони на шестикутній дошці. Після того, як кількість жетонів дорівнює кількості сусідніх плиток, ця плитка шексплодується і переміщує всі жетони на неї до оточуючих сусідів. Грати в гру онлайн можна тут .

Мені подобається ця гра, але іноді важко точно знати, скільки жетонів йде на конкретній плитці; Я завжди рахую кількість сусідів. Було б дуже зручно, якби у мене було мистецтво ASCII, яке допоможе мені запам'ятати, скільки жетонів знаходиться на кожній плитці.

Ви повинні написати програму або функцію , яка приймає ціле позитивне число в якості вхідних даних і виробляє це ASCII уявлення шестигранник розміру N . Кожна плитка буде такою кількістю сусідів, яку має плитка. Оскільки 1 - дивний кутовий випадок із нульовими сусідами, вам потрібно обробляти лише входи, більші за 1.

Ви можете приймати цей номер у будь-якому розумному форматі, наприклад, STDIN, аргументи функції, аргументи командного рядка, з файлу тощо. Вихід також може бути у будь-якому розумному форматі, наприклад, друк у STDOUT, запис у файл, повернення список рядків, рядок, розділений на новий рядок, і т.д.

Ось кілька вибіркових результатів для перших 5 входів:

2)

 3 3
3 6 3
 3 3


3)

  3 4 3
 4 6 6 4
3 6 6 6 3
 4 6 6 4
  3 4 3


4)

   3 4 4 3
  4 6 6 6 4
 4 6 6 6 6 4
3 6 6 6 6 6 3
 4 6 6 6 6 4
  4 6 6 6 4
   3 4 4 3

5)

    3 4 4 4 3
   4 6 6 6 6 4
  4 6 6 6 6 6 4
 4 6 6 6 6 6 6 4
3 6 6 6 6 6 6 6 3
 4 6 6 6 6 6 6 4
  4 6 6 6 6 6 4
   4 6 6 6 6 4
    3 4 4 4 3

6)

     3 4 4 4 4 3
    4 6 6 6 6 6 4
   4 6 6 6 6 6 6 4
  4 6 6 6 6 6 6 6 4
 4 6 6 6 6 6 6 6 6 4
3 6 6 6 6 6 6 6 6 6 3
 4 6 6 6 6 6 6 6 6 4
  4 6 6 6 6 6 6 6 4
   4 6 6 6 6 6 6 4
    4 6 6 6 6 6 4
     3 4 4 4 4 3

І схема продовжується аналогічно. Як завжди, застосовуються стандартні лазівки, і відповідь з найнижчою кількістю байтів увінчається переможцем!

Табло лідерів

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

Щоб переконатися, що ваша відповідь відображається, будь ласка, почніть свою відповідь із заголовка, використовуючи наступний шаблон Markdown:

# Language Name, N bytes

де Nрозмір вашого подання. Якщо ви покращите свій рахунок, ви можете зберегти старі бали у заголовку, прокресливши їх. Наприклад:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Якщо ви хочете включити у свій заголовок декілька чисел (наприклад, тому що ваш результат - це сума двох файлів або ви хочете окремо перерахувати штрафні санкції для перекладача), переконайтесь, що фактичний результат - це останнє число у заголовку:

# Perl, 43 + 2 (-p flag) = 45 bytes

Ви також можете зробити ім'я мови посиланням, яке потім з’явиться у фрагменті таблиць лідерів:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes


1
Пов'язані (але запитання про процес, а не про кількість сусідів).
трихоплакс

1
Мені спокуса пізнати Гексагонію саме заради цього завдання. ;)
Кевін Кройсейсен

Відповіді:


11

MATL , 39 37 байт

4*3-:!G:+o~YRtP*!tPw4LY)vtI5&lZ+47+*c

Спробуйте в Інтернеті! Або перевірити всі тестові випадки .

Пояснення

Я знову користуюся згорткою!

Розглянемо вхід n = 3. Код спочатку будує матрицю розміру 4*n-3× nшляхом додавання вектора стовпця [1; 2; ...; 9]до вектору рядків [1, 2, 3]з широкомовною трансляцією. Це означає обчислити 2D масив масивів усіх попарно доданих:

 2  3  4
 3  4  5
 4  5  6
 5  6  7
 6  7  8
 7  8  9
 8  9 10
 9 10 11
10 11 12

Заміна парних чисел 1і непарних чисел 0дає шаблон шаблону

1 0 1
0 1 0
1 0 1
0 1 0
1 0 1
0 1 0
1 0 1
0 1 0
1 0 1

Це буде використано для генерації (частини) шестикутної сітки. Оні представлятимуть точки в сітці, а нулі представлятимуть пробіли.

Правий верхній кут видаляється зануленням усіх записів над головною "діагоналлю" матриці:

1 0 0
0 1 0
1 0 1
0 1 0
1 0 1
0 1 0
1 0 1
0 1 0
1 0 1

Елементне множення цієї матриці на вертикально перевернуту версію себе також видаляє нижній правий кут. Транспонування тоді дає

1 0 1 0 1 0 1 0 1
0 1 0 1 0 1 0 1 0
0 0 1 0 1 0 1 0 0

Це починає виглядати як шестикутник. За допомогою симетрії сітку розширюють для отримання верхньої половини:

0 0 1 0 1 0 1 0 0
0 1 0 1 0 1 0 1 0
1 0 1 0 1 0 1 0 1
0 1 0 1 0 1 0 1 0
0 0 1 0 1 0 1 0 0

Тепер нам потрібно замінити кожен запис, рівний одиниці, за кількістю сусідів. Для цього ми використовуємо згортку з сусідством 3 × 5 (тобто ядро ​​є матрицею 3 × 5). Результат,

2 3 4 5 5 5 4 3 2
4 5 7 7 8 7 7 5 4
4 6 7 8 7 8 7 6 4
4 5 7 7 8 7 7 5 4
2 3 4 5 5 5 4 3 2

є два питання (які будуть вирішені пізніше):

  1. Значення були обчислені для всіх позицій, тоді як нам вони потрібні лише у позиціях тих, що знаходяться в сітці нуль-один.
  2. Для кожної з цих позицій сусідський рахунок включає в себе саму крапку, тому вона вимикається 1.

Код тепер додає 47до кожного обчисленого значення. Це відповідає відніманню 1для вирішення питання (2) та додаванню 48(ASCII для '0'), яке перетворює кожне число в кодову точку відповідного його знака.

Потім отримана матриця множиться на копію сітки нуль-один. Це вирішує питання (1) вище, встановлюючи точки, які не є частиною шестикутної сітки, знову дорівнюють нулю:

 0  0 51  0 52  0 51  0  0
 0 52  0 54  0 54  0 52  0
51  0 54  0 54  0 54  0 51
 0 52  0 54  0 54  0 52  0
 0  0 51  0 52  0 51  0  0

Нарешті, цей масив чисел передається масиву char. Нульові символи відображаються як простір, що дає кінцевий результат:

  3 4 3  
 4 6 6 4 
3 6 6 6 3
 4 6 6 4 
  3 4 3  

15

JavaScript (ES6), 118 117 байт

n=>[...Array(m=n+--n)].map((_,i,a)=>a.map((_,j)=>(k=j-(i>n?i-n:n-i))<0?``:k&&++j<m?i/2%n?6:4:3+!i%n).join` `).join`\n`

Де \nпредставляє буквальний символ нового рядка. Пояснення: Припустимо n=4. Почнемо з наступного розрізненого пробілом цифри:

0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0

Перші |n-i| 0s видаляються, але пробіли залишаються:

   0 0 0 0
  0 0 0 0 0
 0 0 0 0 0 0
0 0 0 0 0 0 0
 0 0 0 0 0 0
  0 0 0 0 0
   0 0 0 0

Миттєвий шестикутник! Потім достатньо обчислити відповідне значення замість кожного 0, перевіривши, чи ми знаходимося в першому чи останньому рядку та / або стовпчику. Редагувати: Збережено 1 байт завдяки @Arnauld.


Використовуючи частину вашої формули, я прийшов до версії 107 байт з для / console.log ():n=>{for(i=n+--n;i--;)console.log(' '.repeat(l=i>n?i-n:n-i)+(j=3+!l%n)+` ${l-n?6:4}`.repeat(2*n-l-1)+' '+j)}
Arnauld

@Arnauld Мені це подобається 3+!i%n!
Ніл

7

Python 2, 125 123 байт

def h(n):m=n-1;t=[' '*(m-r)+' '.join(('46'[r>0]*(r+m-1)).join('34'[r%m>0]*2))for r in range(n)];print'\n'.join(t+t[-2::-1])

Тести на ideone

Проходить через верхівку до середніх рядів, будуючи for r in range(n)рядки:
- виготовлення двох кутів або двох ребер '34'[r%m>0]*2,;
- заповнення шляхом з'єднання їх з повторений '6'або '4', '46'[r>0]*(r+m-1);
- з'єднання кутів і країв з ' ';
- попередньо пробілами ' '*(m-r);

Потім друкує це, і це відображення в середньому ряду, з'єднане новими рядками, print'\n'.join(t+t[-2::-1])


4

Python 2, 96 байт

n=input();m=n-1
while n+m:n-=1;j=abs(n);c='34'[0<j<m];print' '*j+c+' '+'46  '[j<m::2]*(2*m+~j)+c

Це виглядає досить безладно і дещо пограбно ...


3

Java, 375 363 361 339 329 317 293 байт

interface J{static void main(String[]r){int i=0,k,h=Integer.decode(r[0]),a=1,l,n=0;for(;i++<h*2-1;n+=a){if(n==h-1)a=-1;String s="";for(k=0;k<n+h;k++,s+=" ")s+=n==0?k==0||k==n+h-1?3:4:k!=0&&k!=n+h-1?6:n==h-1?3:4;l=(h*4-3-s.trim().length())/2;System.out.printf((l==0?"%":"%"+l)+"s%s\n","",s);}}}

Безумовно

interface J {
    static void main(String[] r) {
        int i = 0, k, h = Integer.decode(r[0]), a = 1, l, n = 0;
        for (; i++ < h * 2 - 1; n += a) {
            if (n == h - 1) {
                a = -1;
            }
            String s = "";
            for (k = 0; k < n + h; k++, s += " ") {
                s += n == 0 ? k == 0 || k == n + h - 1 ? 3 : 4 : k != 0 && k != n + h - 1 ? 6 : n == h - 1 ? 3 : 4;
            }
            l = (h * 4 - 3 - s.trim().length()) / 2;
            System.out.printf((l == 0 ? "%" : "%" + l) + "s%s\n", "", s);
        }
    }
}

Використання :

$ java J 5
    3 4 4 4 3     
   4 6 6 6 6 4    
  4 6 6 6 6 6 4   
 4 6 6 6 6 6 6 4  
3 6 6 6 6 6 6 6 3 
 4 6 6 6 6 6 6 4  
  4 6 6 6 6 6 4   
   4 6 6 6 6 4    
    3 4 4 4 3

Я впевнений, що жахливий вкладений блок if-else може бути переписаний на менший розмір, але наразі не можу це зрозуміти. Будь-які пропозиції вітаються :-)

Оновлення

  • Дотримуючись пропозиції Кевіна Круїссена і використовував декодування замість parseInt.
  • Перепишіть деякі ifs, використовуючи потрійний оператор.
  • Більше потрійних операторів.
  • Поглинайтеся потрійними операторами! Я думаю, що я створив монстра!
  • Перепишіть блок if-else щодо друку.

1
Я не так прискіпливо придивився до методу, яким ви користуєтесь самі, але деякі невеликі поради щодо гольфу для вашого поточного коду: Integer.parseIntможна пограти в гольф Integer.decode. l=(h*4-3-s.trim().length())/2;if(l==0)можна в гольф if((l=(h*4-3-s.trim().length())/2)==0). Крім того, цілком прийнятно просто розміщувати метод без класу (якщо в питанні не вказано інше), тож void f(int i){...use i...}замість цього interface J{static void main(String[]r){...i=Integer.decode(r[0])...use i...}, це також може заощадити вам досить багато байтів. Коли у мене буде більше часу, я буду шукати далі.
Кевін Кройсейсен

@KevinCruijssen: Дякую за ваші пропозиції. l=(h*4-3-s.trim().length())/2;if(l==0)насправді однакова довжина if((l=(h*4-3-s.trim().length())/2)==0).
Master_ex

2

05AB1E , 44 байти

FN_i4ë6}ð«¹ÍN+×ðìN_N¹<Q~i3ë4}.ø¹<N-ð×ì})¦«»

Пояснення

У міру дзеркального відображення верхньої та нижньої частини шестикутника нам потрібно лише створити верхню частину.
Отже, для введення X нам потрібно генерувати X рядків. Саме це і робить головний цикл.

F                                        }

Потім робимо центральну частину рядів.
Це 4 для першого ряду і 6 для решти (оскільки ми робимо лише верхню частину).
Ми поєднуємо це число з пробілом, оскільки для візерунка буде потрібно інтервал між числами.

N_i4ë6}ð«

Потім ми повторюємо цей рядок X-2 + N разів, де N - поточний рядок, індексований 0, і додаємо пробіл зліва.

¹ÍN+×ðì

Після цього настає час для кутів. Їх буде 3 для першого та останнього ряду та 4 для середнього ряду.

N_N¹<Q~i3ë4}.ø

Тепер нам потрібно переконатися, що рядки вишиковуються правильно, додаючи пробіли на передній частині кожного ряду. Кількість доданих пробілів буде X-1-N .

¹<N-ð×ì

Тепер, коли ми виконали верхню частину сітки, ми додаємо рядки до списку, створюємо зворотну копію та видаляємо перший елемент із цієї копії (як центральний рядок нам потрібен лише один раз), потім об'єднуємо ці 2 списки разом і друк.

)¦«»

Спробуйте в Інтернеті!

Додаткове рішення, також 44 байти:

ÍÅ10.øvN_i4ë6}ð«¹ÍN+×ðìyi4ë3}.ø¹<N-ð×ì})¦«»

2

Рубі, 87 байт

Функція Anonymous приймає n як аргумент і повертає масив рядків.

->n{(1-n..n-=1).map{|i|j=i.abs
" "*j+(e=j%n>0?"4 ":"3 ")+["6 ","4 "][j/n]*(2*n-1-j)+e}}

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

Введення через stdin. Виписує всю фігуру до stdout. Досить пояснюючи себе.

f=->n{
  (1-n..n-=1).map{|i|            #reduce n by 1 and iterate i from -n to n
    j=i.abs;                     #absolute magnitude of i
    " "*j+                       #j spaces +
    (e=j%n>0?"4 ":"3 ")+         #start the string with 3 or 4 +
    ["6 ","4 "][j/n]*(2*n-1-j)+  #2*n-1-j 6's or 4`s as appropriate +
    e                            #end the string with another 3 or 4
  }
}

puts f[gets.to_i]

1

V , 60 байт

Àé x@aA4 xr3^.òhYpXa 6^òkyHç^/:m0
Pç 3.*6/^r4$.
òÍ6 4./6

Спробуйте в Інтернеті!

Це дійсно занадто довго. Ось гекс-дамп, оскільки він містить недруковані символи:

0000000: c0e9 2078 4061 4134 201b 7872 335e 2ef2  .. x@aA4 .xr3^..
0000010: 6859 7058 6120 361b 5ef2 6b79 48e7 5e2f  hYpXa 6.^.kyH.^/
0000020: 3a6d 300a 50e7 2033 2e2a 362f 5e72 3424  :m0.P. 3.*6/^r4$
0000030: 2e0a f2cd 3620 9334 852e 2f36            ....6 .4../6

1

Ракетка, 487 байт

(λ(n c e o)(let((sp(append(range(- n 1)-1 -1)(reverse(range(- n 1)0 -1))))
(mm(append(range(- n 2)(-(+ n(- n 1))2))(range(-(+ n(- n 1))2)(-(- n 1)2)-1)))
(r""))(for((i sp)(j mm))(define str"")(for((ss i))(set! str(string-append str" ")))
(set! str(string-append str(if(or(= i 0)(= i(- n 1))(= i(* 2(- n 1))))c e)" "))
(for((jj j))(set! str(string-append str(if(= j(- n 2))e o)" ")))(set! r(if(or(= i 0)
(= i(- n 1))(= i(* 2(- n 1))))c e))(set! str(string-append str r))(displayln str))))

Тестування:

(f 4 "3" "4" "6") 

   3 4 4 3
  4 6 6 6 4
 4 6 6 6 6 4
3 6 6 6 6 6 3
 4 6 6 6 6 4
  4 6 6 6 4
   3 4 4 3

(f 5 "o" "*" "-") 

    o * * * o
   * - - - - *
  * - - - - - *
 * - - - - - - *
o - - - - - - - o
 * - - - - - - *
  * - - - - - *
   * - - - - *
    o * * * o

Детальна версія:

(define(f1 n c e o)
  (let ((sp(append(range(sub1 n) -1 -1)
                  (reverse(range(sub1 n) 0 -1))))
        (mm(append(range(- n 2)(-(+ n(sub1 n)) 2))
                  (range(-(+ n(sub1 n)) 2)(-(sub1 n)2) -1) ))
        (r ""))
    (for((i sp)(j mm))
      (define str "")
      (for((ss i))(set! str(string-append str " ")))
      (set! str(string-append str
                              (if(or(= i 0)(= i(sub1 n))
                                    (= i(* 2(sub1 n)))) c e)
                              " "))
      (for((jj j))
        (set! str(string-append str
                                (if(= j(- n 2)) e o)
                                " ")))
      (set! r(if(or(= i 0)
                   (= i(sub1 n))
                   (= i(* 2(sub1 n)))) c e))
      (set! str(string-append str r))
      (displayln str))))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.