MATL , 30 28 27 bytes
t:P"@:s:@/Xk&+@+8MPt&(]30+c
Experimente online!
Recursos bônus:
Para 26 bytes , a seguinte versão modificada produz saída gráfica :
t:P"@:s:@/Xk&+@+8MPt&(]1YG
Experimente no MATL Online!
A imagem está implorando por alguma cor e custa apenas 7 bytes:
t:P"@:s:@/Xk&+@+8MPt&(]1YG59Y02ZG
Experimente no MATL Online!
Ou use uma versão mais longa (37 bytes) para ver como a matriz de caracteres é construída gradualmente :
t:P"@:s:@/Xk&+@+8MPt&(t30+cD9&Xx]30+c
Experimente no MATL Online!
Saídas de exemplo
Para entrada 8
, o seguinte mostra a versão básica, saída gráfica e saída gráfica em cores.
Explicação
Procedimento geral
Uma matriz numérica é construída das camadas externa para interna em N
etapas, onde N
está a entrada. Cada etapa substitui uma parte interna (superior esquerda) da matriz anterior. No final, os números na matriz obtida são alterados para caracteres.
Exemplo
Para entrada, 4
a primeira matriz é
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
Como um segundo passo, a matriz
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
é sobrescrito na metade superior do último. Então o mesmo é feito com
6 5 5
5 4 4
5 4 4
e finalmente com
3
A matriz resultante é
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
Por fim, 30
é adicionado a cada entrada e os números resultantes são interpretados como pontos de código e convertidos em caracteres (começando em 33
, correspondendo a !
).
Construção das matrizes intermediárias
Para entrada N
, considere diminuir valores de k
de N
para 1
. Para cada k
um, é gerado um vetor de números inteiros de 1
a k*(k+1)
e, em seguida, cada entrada é dividida k
e arredondada. Como exemplo, para k=4
isso é fornecido (todos os blocos têm tamanho, k
exceto o último):
1 1 1 1 2 2 2 2 3 3
enquanto que para k=3
o resultado seria (todos os blocos têm tamanho k
):
1 1 1 2 2 2
Esse vetor é adicionado, elemento a elemento com transmissão, a uma cópia transposta de si mesma; e depois k
é adicionado a cada entrada. Para k=4
isso dá
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
Essa é uma das matrizes intermediárias mostradas acima, exceto que é invertida horizontal e verticalmente. Então, tudo o que resta é inverter essa matriz e escrevê-la no canto superior esquerdo da matriz "acumulada" até agora, inicializada em uma matriz vazia para a primeira k=N
etapa ( ).
Código
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