MATL , 30 28 27 байт
t:P"@:s:@/Xk&+@+8MPt&(]30+c
Попробуйте онлайн!
Бонусные возможности:
Для 26 байтов следующая модифицированная версия производит графический вывод :
t:P"@:s:@/Xk&+@+8MPt&(]1YG
Попробуйте это в MATL Online!
Изображение требует цвета и стоит всего 7 байт:
t:P"@:s:@/Xk&+@+8MPt&(]1YG59Y02ZG
Попробуйте это в MATL Online!
Или используйте более длинную версию (37 байт), чтобы увидеть, как постепенно строится матрица символов :
t:P"@:s:@/Xk&+@+8MPt&(t30+cD9&Xx]30+c
Попробуйте это в MATL Online!
Пример выходов
Для ввода 8
ниже показаны базовая версия, графический вывод и цветной графический вывод.
объяснение
Общая процедура
Числовая матрица строится от внешнего к внутренним слоям N
поэтапно, где N
вводится. Каждый шаг перезаписывает внутреннюю (верхнюю левую) часть предыдущей матрицы. В конце числа в полученной матрице изменяются на символы.
пример
Для ввода 4
первая матрица
10 10 9 9 9 9 8 8 8 8
10 10 9 9 9 9 8 8 8 8
9 9 8 8 8 8 7 7 7 7
9 9 8 8 8 8 7 7 7 7
9 9 8 8 8 8 7 7 7 7
9 9 8 8 8 8 7 7 7 7
8 8 7 7 7 7 6 6 6 6
8 8 7 7 7 7 6 6 6 6
8 8 7 7 7 7 6 6 6 6
8 8 7 7 7 7 6 6 6 6
В качестве второго шага матрица
7 7 7 6 6 6
7 7 7 6 6 6
7 7 7 6 6 6
6 6 6 5 5 5
6 6 6 5 5 5
6 6 6 5 5 5
перезаписывается в верхнюю половину последнего. Затем то же самое делается с
6 5 5
5 4 4
5 4 4
и наконец с
3
Полученная матрица
3 5 5 6 6 6 8 8 8 8
5 4 4 6 6 6 8 8 8 8
5 4 4 6 6 6 7 7 7 7
6 6 6 5 5 5 7 7 7 7
6 6 6 5 5 5 7 7 7 7
6 6 6 5 5 5 7 7 7 7
8 8 7 7 7 7 6 6 6 6
8 8 7 7 7 7 6 6 6 6
8 8 7 7 7 7 6 6 6 6
8 8 7 7 7 7 6 6 6 6
Наконец, 30
добавляется к каждой записи, и результирующие числа интерпретируются как кодовые точки и преобразуются в символы (начиная с 33
, соответственно !
).
Построение промежуточных матриц
Для ввода N
рассмотрим уменьшение значений k
от N
до 1
. Для каждого генерируется k
вектор целых чисел от 1
до k*(k+1)
, а затем каждая запись делится на k
и округляется в большую сторону . Как пример, для k=4
этого дает (все блоки имеют размер, k
кроме последнего):
1 1 1 1 2 2 2 2 3 3
тогда как для k=3
результата будет (все блоки имеют размер k
):
1 1 1 2 2 2
Этот вектор добавляется поэлементно с трансляцией к транспонированной копии самого себя; и затем k
добавляется к каждой записи. За k=4
это дает
6 6 6 6 7 7 7 7 8 8
6 6 6 6 7 7 7 7 8 8
6 6 6 6 7 7 7 7 8 8
6 6 6 6 7 7 7 7 8 8
7 7 7 7 8 8 8 8 9 9
7 7 7 7 8 8 8 8 9 9
7 7 7 7 8 8 8 8 9 9
7 7 7 7 8 8 8 8 9 9
8 8 8 8 9 9 9 9 10 10
8 8 8 8 9 9 9 9 10 10
Это одна из промежуточных матриц, показанных выше, за исключением того, что она перевернута горизонтально и вертикально. Таким образом, все, что остается, - это перевернуть эту матрицу и записать ее в верхний левый угол «накопленной» матрицы до сих пор, инициализированной в пустую матрицу для первого ( k=N
) шага.
Код
t % Implicitly input N. Duplicate. The first copy of N serves as the
% initial state of the "accumulated" matrix (size 1×1). This will be
% extended to size N*(N+1)/2 × N*(N+1)/2 in the first iteration
:P % Range and flip: generates vector [N, N-1, ..., 1]
" % For each k in that vector
@: % Push vector [1, 2, ..., k]
s % Sum of this vector. This gives 1+2+···+k = k*(k+1)/2
: % Range: gives vector [1, 2, ..., k*(k+1)/2]
@/ % Divide each entry by k
Xk % Round up
&+ % Add vector to itself transposed, element-wise with broadcast. Gives
% a square matrix of size k*(k+1)/2 × k*(k+1)/2
@+ % Add k to each entry of the this matrix. This is the flipped
% intermediate matrix
8M % Push vector [1, 2, ..., k*(k+1)/2] again
Pt % Flip and duplicate. The two resulting, equal vectors are the row and
% column indices where the generated matrix will be written. Note that
% flipping the indices has the same effect as flipping the matrix
% horizontally and vertically (but it's shorter)
&( % Write the (flipped) intermediate matrix into the upper-left
% corner of the accumulated matrix, as given by the two (flipped)
% index vectors
] % End
30+ % Add 30 to each entry of the final accumulated matrix
c % Convert to char. Implicitly display