Гексплозивный 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

И картина продолжается аналогичным образом. Как обычно, применяются стандартные лазейки, и ответ с самым низким числом байтов будет признан победителем!

Leaderboards

Вот фрагмент стека, который генерирует как регулярную таблицу лидеров, так и обзор победителей по языкам.

Чтобы убедиться, что ваш ответ обнаружен, начните его с заголовка, используя следующий шаблон уценки:

# 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

DJMcMayhem
источник
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]с широковещательной передачей. Это означает вычисление массива двумерного массива всех попарных дополнений:

 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

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

  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-байтовой версии с for / 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 мне это нравится 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

Это выглядит довольно грязно и несколько гольф ...

Sp3000
источник
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);}}}

Ungolfed

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.
  • Переписал некоторые if, используя троичный оператор.
  • Еще троичные операторы.
  • Моарные троичные операторы! Я думаю, что я создал монстра!
  • Переписан блок if-else относительно печати.
Master_ex
источник
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-ð×ì})¦«»
Emigna
источник
2

Рубин, 87 байт

Анонимная функция принимает 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}}

Неуправляемый в тестовой программе

Ввод через стандартный ввод. Записывает всю форму в стандартный вывод. Довольно понятно.

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]
Уровень реки St
источник
1

V , 60 байтов

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

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

Это действительно слишком долго. Вот hexdump, так как он содержит непечатаемые символы:

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
DJMcMayhem
источник
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))))
rnso
источник