Crea una matriz piramidal

23

Una matriz piramidal es una matriz cuadrada donde todos los números aumentan o disminuyen desde el punto central, como las dos matrices a continuación:

1  1  1  1  1
1  2  2  2  1
1  2  3  2  1
1  2  2  2  1
1  1  1  1  1

O:

3  3  3  3  3
3  2  2  2  3
3  2  1  2  3
3  2  2  2  3
3  3  3  3  3

Dado un número entero distinto de cero n, cree una matriz piramidal donde los números vayan 1a norden creciente (si n <0) o orden decreciente (si n> 0) desde el centro. Si nes par, entonces habrá 4 números centrales (ver los ejemplos).

Como siempre:

  • Formato opcional de entrada y salida
    • El número de espacios, delimitador, etc. es opcional.

Casos de prueba:

1
1

-1
1

5
1  1  1  1  1  1  1  1  1
1  2  2  2  2  2  2  2  1
1  2  3  3  3  3  3  2  1
1  2  3  4  4  4  3  2  1
1  2  3  4  5  4  3  2  1
1  2  3  4  4  4  3  2  1
1  2  3  3  3  3  3  2  1
1  2  2  2  2  2  2  2  1
1  1  1  1  1  1  1  1  1

-5
5  5  5  5  5  5  5  5  5
5  4  4  4  4  4  4  4  5
5  4  3  3  3  3  3  4  5
5  4  3  2  2  2  3  4  5
5  4  3  2  1  2  3  4  5
5  4  3  2  2  2  3  4  5
5  4  3  3  3  3  3  4  5
5  4  4  4  4  4  4  4  5
5  5  5  5  5  5  5  5  5

2
1  1  1  1
1  2  2  1
1  2  2  1
1  1  1  1

-2
2  2  2  2
2  1  1  2
2  1  1  2
2  2  2  2

-4
4  4  4  4  4  4  4  4
4  3  3  3  3  3  3  4
4  3  2  2  2  2  3  4
4  3  2  1  1  2  3  4
4  3  2  1  1  2  3  4
4  3  2  2  2  2  3  4
4  3  3  3  3  3  3  4
4  4  4  4  4  4  4  4
Stewie Griffin
fuente
10
¿Por qué el caso par es diferente del caso impar? No hay ninguna razón por la cual las matrices no puedan seguir exactamente el mismo patrón.
Greg Martin
2
Debido a que se suponía que la entrada era la longitud de la pared lateral, en cuyo caso hay una diferencia entre pares e impares. Decidí ir por el valor máximo, pero mantuve la diferencia impar y par allí. Puede parecer extraño, y puede que no sea una buena explicación, pero es la explicación de por qué hay una diferencia. :-)
Stewie Griffin
2
Podemos asumir -10 < n < 10?
Tito
2
Está bien si no parece un cuadrado perfecto, siempre que sea numéricamente hablando. Si las filas con muchos 10 son más anchas que aquellas con pocos 10, entonces está bien ...
Stewie Griffin

Respuestas:

5

Jalea , 18 17 bytes

|1ŒḄfR«þ`
AÇạẋ¡CG

Pruébalo en línea! o verificar todos los casos de prueba .

Cómo funciona

|1ŒḄfR«þ`  Helper link. Argument: k (positive integer)

|1         Take the bitwise OR with 1. This increments k if it is even.
  ŒḄ       Bounce; yield [1, 2, ..., k | 1, ..., 2, 1].
    fR     Filter range; remove elements not in [1, ..., k] from the array.
           This results in [1, 2, ..., k, ..., 2, 1] if k is odd and in
           [1, 2, ..., k, k, ..., 2, 1] if k is even.
        `  Pass the last return value as left and right argument to:
      «þ     Minimum table; take the minimum of each pair of elements in the
             generated array, returning a 2D array.


AÇạẋ¡CG      Main link. Argument: n

A            Take the absolute value of n.
 Ç           Call the helper link on the result.
     C       Complement; yield 1 - n.
    ¡        Conditional application:
   ẋ           If repeating the return value of Ç 1 - n times results in a non-
               empty array, i.e., if n < 1:
  ạ              Take the absolute differences of the generated integers and 1 - n.
      G      Grid; join columns by spaces, rows by linefeeds.
Dennis
fuente
7

EXCEL: 126 bytes

=MAX(MIN(MIN(CELL("row",RC)-1,CELL("col",RC)-1),MIN(((ABS(R1C1)-1)*2+3)-CELL("row",RC),((ABS(R1C1)-1)*2+3)-CELL("col",RC))),0)

Pruébalo en línea *

Nota: esta respuesta utiliza la notación R1C1. Si vas a probar esto tú mismo. necesitas activar eso en las opciones de Excel.

la fórmula dada debe estar en cada célula presente más allá de (2,2). Pon el tamaño de tu pirámide deseado en (1,1).

tapa de pantalla rápida de la fórmula en acción:
ingrese la descripción de la imagen aquí

¡Aquí hay una imagen adicional de diversión con formato condicional!

* La actualización lleva mucho tiempo, actualmente.


fuente
Esto no maneja los casos negativos o los casos pares correctamente. También puede acortar el código a =MAX(MIN(MIN(ROW()-1,COLUMN()-1),MIN(((ABS(A1)-1)*2+3)-ROW(),((ABS(A1)-1)*2+3)-COLUMN())),0)92 bytes. Sin embargo, todavía no maneja los casos y la fórmula no se puede arrastrar ya que la referencia de celda no está bloqueada.
gtwebb
1
Sin embargo, más problemas con el golf. =MEDIAN(MIN(ROW()-1,COLUMN()-1),ABS(A1)*2+1-MAX(ROW(),COLUMN()),0)
gtwebb
@gtwebb gracias por decirme. Tendré que arreglarlo
-1. Esto no funciona No maneja la entrada negativa. No maneja ni siquiera la entrada. Si está poniendo esta fórmula en cada celda aplicable, necesita un Rangeo necesita mucho más de 126 bytes.
AdmBorkBork
7

Pitón 2, 109 99 98

n=input()
r=range(1,abs(n)+1)
l=r+r[~n|-2::-1]
for j in l:print[abs((n<0)*~-n+min(i,j))for i in l]

Crear lista

l = [1,2,3,4,5,4,3,2,1]

y juega un poco con eso.


editar: nueva forma de crear lista + thx Lynn para dos bytes

pacholik
fuente
If n is even, then there will be 4 center numbers
Rod
@ Rod No, no lo habrá. ¿Qué te hace pensar eso?
pacholik
3
esta es una de las reglas
Rod
@ Rod Oh. Hace solo unos minutos. Editado
pacholik
2
No es nuevo, simplemente no está resaltado: c
Rod
6

MATL , 26 24 bytes

oXyG|to-:"TTYaQ]G0<?G+q|

Pruébalo en línea! O verifique todos los casos de prueba (código ligeramente modificado para servir como conjunto de pruebas).

Explicación

El código primero construye la matriz de salida suponiendo una entrada positiva n. La matriz se inicializa como 1entrada impar o como matriz vacía para entrada par (esto se crea como una matriz de identidad con un tamaño igual a la paridad de la entrada). Luego, lo siguiente se repite nveces para entradas pares y n-1veces para entradas impares: extienda la matriz con un marco que contenga 0y agregue 1a todos los elementos.

Por ejemplo, los pasos para la entrada nson:

  • Matriz inicial:

    1
    
  • Extender con marco:

    0 0 0
    0 1 0
    0 0 0
    
  • Añadir 1:

    1 1 1
    1 2 1
    1 1 1
    
  • Extender con marco:

    0 0 0 0 0
    0 1 1 1 0
    0 1 2 1 0
    0 1 1 1 0
    0 0 0 0 0
    
  • Añadir 1:

    1 1 1 1 1
    1 2 2 2 1
    1 2 3 2 1
    1 2 2 2 1
    1 1 1 1 1
    

Esto proporciona la salida correcta para la entrada positiva. Si la entrada es negativa, la matriz debe modificarse agregando la entrada menos 1y tomando el valor absoluto:

    3 3 3 3 3
    3 2 2 2 3
    3 2 1 2 3
    3 2 2 2 3
    3 3 3 3 3

¡Puedes ver cómo crece la matriz (código modificado para mostrar pasos intermedios) en MATL Online! El intérprete sigue siendo beta. Si no funciona, presione "Ejecutar" nuevamente o vuelva a cargar la página.

Código comentado

o        % Take input implicitly and push 0 if even or 1 if odd
Xy       % Identity matrix of that size. Gives either 1 or empty array
G|       % Absolute value of input
to-      % Subtract 1 if odd
:"       % For loop: repeat that many times
  TTYa   %   Add a frame of zeros in the two dimensions
  Q      %   Add 1 to all elements
]        % End for
G        % Push input again
0>       % is it negative?
?        % If so
  G      %   Push input again
  +      %   Add
  q      %   Subtract 1
  |      %   Absolute value
         % End if implicitly
         % Display implicitly
Luis Mendo
fuente
Veo que reutilizaste el código de la pregunta de animación. ¡Increíble! La parte divertida es que este código también ganaría en esa pregunta, aunque sea más largo que su otra versión;).
Urna de pulpo mágico
1
@carusocomputing Sí, es similar: duplicar, mostrar, pausar 1 segundo, salida clara :-)
Luis Mendo
Además, no estoy seguro de por qué, pero cualquier entrada por encima de 14 se detiene en 14. Cancele eso, es una limitación de la consola en línea "Operación agotada".
Urna de pulpo mágico
@carusocomputing El error dice "tiempo de espera de operación". Supongo que al intérprete le lleva demasiado tiempo. Trate de reducir la pausa para decir .2segundos
Luis Mendo
@carusocomputing Sí, ese es el tiempo de espera del intérprete en línea. Actualmente limitamos los trabajos a 30 segundos. Como sugiere Luis, puede disminuir el tiempo de pausa
Suever
3

Python 2.7: 123 122 120 bytes

los problemas aún pueden guardar algunos bytes ...

from numpy import*
n=input()
N=abs(n)
e=N*2-N%2
a=ones([e,e])
for i in range(N):a[i:e-i,i:e-i]=(i+1)*(n>0)or-n-i
print a

edit1: N=abs(n)para guardar 1 byte

edit2: (i+1)*(n>0)or-n-ipara guardar 2 bytes

Aaron
fuente
3

Haskell, 119 113 110 104 102 101 bytes

f x|(h,t)<-splitAt(mod x 2)$[x,x-1..1]++[1.. -x]=foldl(\m n->(n#)<$>(n<$m)#m)[[y]|y<-h]t
x#y=x:y++[x]

Devuelve la matriz como una lista de listas de enteros, por ejemplo: f 2-> [[1,1,1,1],[1,2,2,1],[1,2,2,1],[1,1,1,1]].

Cómo funciona:

            [x,x-1..1]++[1.. -x]      -- make list from x down to 1 followed by
                                      -- 1 to (-x). One of the sublists will be
                                      -- empty. The resulting list contains the
                                      -- numbers of the pyramid from inside to out.
   (h,t)<-splitAt(mod x 2)            -- bind h to the first element if x is odd
                                      -- or to the empty list if x is even
                                      -- bind t to the rest (tail or full list)

foldl (     ) [[y]|y<-h] t            -- fold the following function into t with a
                                      -- starting value of [] if x is even or
                                      -- [[h]] if x is odd

   \m n ->                            -- the current matrix m with the next number
                                      -- n is transformed into a new matrix:

               (n#)<$>(n<$m)#m        -- prepend and append a n to 
                                      -- m prepended and append by a line of n's

x#y=x:y++[x]                          -- helper function to prepend and append an
                                      -- element x to a list y
nimi
fuente
2

Perl, 175 bytes

Incluye 1 bytes para -p.

($t,$v,$w)=($_,(abs)x2);$k=$_.$k for 1..$v;map{$r.=$_ for(@v=1..$_-1),$_ x(2*$v---$w%2),reverse@v;$r.=$/}1..$v;$_=$r.~~reverse$r;eval"y/1-$w/$k/"if$t<0;$w%2&&s/

.*//||s;

;

(Hay una nueva línea final que no sé cómo mostrar con la rebaja, pero la necesita).

Necesidades -pasí como -M5.010o -Epara correr:

perl -pE '($t,$v,$w)=($_,(abs)x2);$k=$_.$k for 1..$v;map{$r.=$_ for(@v=1..$_-1),$_ x(2*$v---$w%2),reverse@v;$r.=$/}1..$v;$_=$r.~~reverse$r;eval"y/1-$w/$k/"if$t<0;$w%2&&s/

.*//||s;

;
' <<< 5

Maldición, esto es demasiado largo ... Intentaré otros enfoques cuando tenga algo de tiempo.

Dada
fuente
¿Por qué lo usas eval?
Tito
@Titus Debido a y///que no se interpola, entonces se usan comillas dobles para interpolar $wy $kluego evalejecutar y///.
Dada
2

Python 2, 109 bytes

n=input()
a=abs(n)
s=a*2-a%2
r=range(s)
for y in r:print[(min,max)[n<0](x+1,s-x,y+1,s-y)-(n<0)*s/2for x in r]
Lynn
fuente
2

J, 29 26 bytes

1+**[:<./~**i.,2&|1&}.i.@-

Uso

   f =: 1+**[:<./~**i.,2&|1&}.i.@-
   f 1
1
   f _1
1
   f 2
1 1 1 1
1 2 2 1
1 2 2 1
1 1 1 1
   f _2
2 2 2 2
2 1 1 2
2 1 1 2
2 2 2 2
   f 3
1 1 1 1 1
1 2 2 2 1
1 2 3 2 1
1 2 2 2 1
1 1 1 1 1
   f _3
3 3 3 3 3
3 2 2 2 3
3 2 1 2 3
3 2 2 2 3
3 3 3 3 3

Explicación

El i.verbo de rango produce resultados [0, 1, ..., n-1]positivos ny [n-1, n-2, ..., 0]negativos, lo ncual es útil aquí.

1+**[:<./~**i.,2&|1&}.i.@-  Input: integer n
                         -  Negate n
                      i.@   Creates range for -n
               2&|          Take n modulo 2, returns 0 or 1
                  1&}.      If n is odd, drop the first value from the range for -n
                            Else do nothing and pass it unmodified
              ,             Append it to
            i.              The range for n
          *                 Get the sign of n
           *                Multiply elementwise with the joined ranges
    [:<./~                  Form a table of the minimum values of the range
  *                         Get the sign of n
   *                        Multiply elementwise with the joined ranges
1+                          Add 1 to each and return
millas
fuente
2

Mathematica, 78 bytes

Abs[Fold[ArrayPad[#,1,#2]&,Table[0,#,#]&@Mod[#,2,1],Range[Abs@#-1]]+1~Min~-#]&

Explicación

Table[0,#,#]&@Mod[#,2,1]

Haga la matriz inicial: 1x1 si es impar, 2x2 si es par.

Range[Abs@#-1]

Genere una lista de 1 a abs (entrada) - 1.

Fold[ArrayPad[#,1,#2]&, ..., ...]

Rellene la matriz inicial utilizando la lista mencionada anteriormente.

... +1~Min~-#

Agregue 1 o entrada, lo que sea más pequeño.

Abs

Aplicar valor absoluto a toda la matriz.

JungHwan Min
fuente
1

PHP, 177157 bytes

for($y=-$n=abs($z=$argv[1])+1;++$y<$n;)if($y&&($n&1||$y-1)){for($x=-$n;++$x<$n;)if($x&&($n&1||$x-1)){$v=max(abs($x),abs($y));echo$z<0?$v:$n-$v," ";}echo"
";}

corre con php -r '<code>

recorre filas y columnas, imprime los valores en función de su distancia al centro.

  • $n=abs($z)+1: El +1guarda un par de +1y -1en expresiones posteriores
  • los bucles van de -$n+1(¡pre-incremento en la condición!) a $n-1( -abs($z)a abs($z))
  • la línea / columna 0 (y para impar $n: 1) se omiten
    $n&1es cierto para las columnas pares aquí! ¿Recuerda el +1?)
  • La impresión por $ z positivo también se beneficia de la +1.
Titus
fuente
1

Haskell, 191 183 173 169 168 bytes

r=reverse;m=map
x!y=(((++)<*>(x.r)).).zipWith(++).m y
g n|n<0=m(m$abs.((n-1)+)).g$abs n|1<2=[id!id,tail!init]!!mod n 2=<<m r$r$m(\x->(x<$[1..x])++[x+1..n])[1..n]
g.(0-)

Uso:

mapM_ print $ (g.(0-)) 3

[1,1,1,1,1]
[1,2,2,2,1]
[1,2,3,2,1]
[1,2,2,2,1]
[1,1,1,1,1]

Gracias a nimi por 2 10 20 24 bytes!

Alondra
fuente
1
negatees (0-)
nimi
1
Puede cambiar fa [id!id,tail!init]!!mod n 2y luego en línea gy el uso de la 1<2guardia para unirse a un resultado intermedio de la rama: g n| ... |q<-r<$>a n=([id!id,tail!init]!!mod n 2)q$a n. No necesita un nombre para la función principal.
nimi
1
Oh, puede inline a, también (y volver a la 1<2guardia): g n| ... |1<2=[id!id,tail!init]!!mod n 2=<<map r$r$(\x->(x<$[1..x])++[x+1..n])<$>[1..n].
nimi
1
Último para hoy: m=mapen !: ...(++).m yy g: g n|n<0=m(m(abs.((n-1)+)))$g$abs n|1<2=[id!id,tail!init]!!mod n 2=<<m r$r$m(\x->(x<$[1..x])++[x+1..n])[1..n].
nimi
1

JavaScript (ES6), 107 bytes

(n,l=Math.abs(n+n-n%2))=>[...Array(l--)].map((_,i,a)=>a.map((_,j)=>(j=Math.min(i,l-i,j,l-j),n<0?-n-j:j+1)))

les el tamaño de la matriz. El n<0?-n-j:j+1parece torpe, pero no puedo encontrar nada mejor.

Neil
fuente
1

Vim, 152 143 bytes

Estoy seguro de que esto podría jugar más, especialmente esas dos últimas líneas, pero mi cerebro está frito.

D:let@z=@-/abs(@-)
a"nywYp:s/\d/x/g<C-v>
YggP:%s/.*/x \0 x<C-v>
:%s/x\+/\=@n-@z/g<C-v>
<Esc>v0"qda<C-r>=@z<0?1:@-*@z
<Esc>@=@-%2?"":"YPJYp"
@=@-*@z-1.(@-*@z>1?"@q":"")

Pruébalo en línea!

Aquí está en formato xxd con caracteres no imprimibles:

0000000: 443a 6c65 7440 7a3d 402d 2f61 6273 2840  D:let@z=@-/abs(@
0000010: 2d29 0a61 226e 7977 5970 3a73 2f5c 642f  -).a"nywYp:s/\d/
0000020: 782f 6716 0a59 6767 503a 2573 2f2e 2a2f  x/g..YggP:%s/.*/
0000030: 7820 5c30 2078 160a 3a25 732f 785c 2b2f  x \0 x..:%s/x\+/
0000040: 5c3d 406e 2d40 7a2f 6716 0a1b 7630 2271  \=@n-@z/g...v0"q
0000050: 6461 123d 407a 3c30 3f31 3a40 2d2a 407a  da.=@z<0?1:@-*@z
0000060: 0a1b 403d 402d 2532 3f22 223a 2259 504a  ..@=@-%2?"":"YPJ
0000070: 5970 220a 403d 402d 2a40 7a2d 312e 2840  Yp".@=@-*@z-1.(@
0000080: 2d2a 407a 3e31 3f22 4071 223a 2222 29    -*@z>1?"@q":"")

Explicación

Construye la pirámide desde el centro hacia afuera, rodeando el número del centro con xes:

x x x
x 5 x
x x x

Luego reemplaza el xes con el siguiente número y lo rodea con xes nuevamente:

x x x x x
x 4 4 4 x
x 4 5 4 x
x 4 4 4 x
x x x x x

...y así. Para números pares, hace lo mismo pero comienza con una base de 2x2.

Aquí está el código "sin golf". Es algo poco convencional en el sentido de que "grabo" una macro escribiéndola en un búfer (de ahí todos los <C-v>s) y luego eliminándola en un registro, que es la mejor manera que encontré para componer una macro sin ejecutar realmente las pulsaciones de teclas.

D:let@z=@-/abs(@-)<CR>       " Delete the input (into @-) and set @z to -1 if @- is negative; otherwise 1
a                            " Enter insert mode to compose the macro
  "nyw                         " Copy the number under the cursor to @n
  Yp                           " Copy this line and paste it below
  :s/\d/x/g<C-v><CR>           " Replace digits in the copy with 'x'
  YggP                         " Copy this line and paste it at the top of the buffer
  :%s/.*/x \0 x<C-v><CR>       " Add an 'x' before and after each line
  :%s/x\+/\=@n-@z/g<C-v><CR>   " Replace all 'x'es (and 'xx'es etc.) with the next number
<Esc>v0"qd                   " Done composing macro; delete it into @q (buffer is now empty)
a<C-r>=@z<0?1:@-*@z          " Append the center number (1 or abs(@-)) to the buffer
<Esc>@=@-%2?"":"YPJYp"       " If the input is even, make a 2x2 square
@=@-*@z-1.(@-*@z>1?"@q":"")  " Execute the macro abs(@-)-1 times if it's > 1
Jordán
fuente
0

PHP, 215 bytes

for($i=0;$i<$m=($r=($s=abs($n=$argv[1]))*2-$s%2)**2;){$i%$r?:print"\n";$l=min(($x=$i%$r+1)<$s?$x:$x=$r-$x+1,($z=1+floor($i++/$r))<$s?$z:$z=$r-$z+1);$o=($n>0)?$l:$s+1-$l;echo str_pad(" ",1+strlen($s)-strlen($o)).$o;}
Jörg Hülsermann
fuente
0

R, 112 bytes

k=abs(n);l=2*k;m=diag(l);for(i in 1:k){m[i:(l+1-i),i:(l+1-i)]=i};if(n%%2==1){m=m[-k,-k]};if(n<0){m=abs(m-1+n)};m

Necesita un entero nen el espacio de trabajo; de lo contrario, ejecute n=scan()8 bytes adicionales.

k=abs(n)
l=2*k
m=diag(l)                    # Initialize quadratic 2*|n| matrix
for(i in 1:k){
    m[i:(l+1-i),i:(l+1-i)]=i # Assign values to matrix elements according
                             # to their index
}
if(n%%2==1){
   m=m[-k,-k]                # If n is odd, delete middle row and column
}
if(n<0){
    m=abs(m-1+n)             # If n < 0, flip values
}
m                            # Print matrix
Choque de cabeza
fuente