Crea una matrice piramidale


23

Una matrice piramidale è una matrice quadrata in cui tutti i numeri aumentano o diminuiscono dal punto centrale, come le due matrici seguenti:

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

Dato un numero intero diverso da zero n, creare una matrice piramidale in cui i numeri vanno da 1a nin ordine crescente (se n <0) o in ordine decrescente (se n> 0) dal centro. Se nè pari, ci saranno 4 numeri centrali (vedi gli esempi).

Come sempre:

  • Formato di input e output opzionale
    • Il numero di spazi, delimitatore ecc. È facoltativo

Casi test:

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

10
Perché il caso pari è diverso dal caso dispari? Non vi è alcun motivo per cui le matrici non possano seguire esattamente lo stesso schema.
Greg Martin,

2
Poiché l'ingresso doveva essere la lunghezza della parete laterale, nel qual caso c'è una differenza tra pari e dispari. Ho deciso di optare per il valore massimo, ma ho mantenuto la differenza pari e dispari. Potrebbe sembrare strano e potrebbe non essere una buona spiegazione, ma è la spiegazione del perché c'è una differenza. :-)
Stewie Griffin,

2
Possiamo supporre -10 < n < 10?
Tito,

2
Va bene se non sembra un quadrato perfetto, purché sia ​​numericamente parlando. Se le file con molti 10 sono più larghe di quelle con pochi 10, allora va bene ...
Stewie Griffin,

Risposte:


5

Gelatina , 18 17 byte

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

Provalo online! o verifica tutti i casi di test .

Come funziona

|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.

7

EXCEL: 126 byte

=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)

Provalo online *

Nota: questa risposta utilizza la notazione R1C1. Se hai intenzione di provarlo tu stesso. devi attivarlo nelle opzioni di Excel.

la formula data deve essere presente in ogni cellula presente oltre (2,2). Inserisci la dimensione della piramide desiderata in (1,1).

rapido screen-cap della formula in azione:
inserisci qui la descrizione dell'immagine

Ecco un'immagine aggiuntiva di un po 'di divertimento con la formattazione condizionale!

* Al momento l'aggiornamento richiede molto tempo.


Questo non gestisce correttamente i casi negativi o pari. Inoltre è possibile abbreviare il codice a =MAX(MIN(MIN(ROW()-1,COLUMN()-1),MIN(((ABS(A1)-1)*2+3)-ROW(),((ABS(A1)-1)*2+3)-COLUMN())),0)92 byte. Tuttavia non gestisce ancora i casi e la formula non può essere trascinata poiché il riferimento di cella non è bloccato.
gtwebb,

1
Più golf stessi problemi però. =MEDIAN(MIN(ROW()-1,COLUMN()-1),ABS(A1)*2+1-MAX(ROW(),COLUMN()),0)
gtwebb,

@gtwebb grazie per avermelo detto. Dovrò risolvere

-1. Questo non funziona Non gestisce input negativi. Non gestisce nemmeno l'input. Se stai inserendo questa formula in ogni cella applicabile, hai bisogno di un Rangeo hai bisogno di un diavolo di molto più di 126 byte.
AdmBorkBork,

7

Python 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]

Crea un elenco

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

e giocaci un po '.


modifica: nuovo modo di creare lista + thx Lynn per due byte


If n is even, then there will be 4 center numbers
Rod,

@Rod No non lo farà. Cosa te lo fa pensare?
Pacholik,

3
questa è una delle regole
Rod,

@Rod Oh. Solo pochi minuti fa. Modificato.
Pacholik,

2
Non è nuovo, semplicemente non evidenziato: c
Rod

6

MATL , 26 24 byte

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

Provalo online! Oppure verifica tutti i casi di test (codice leggermente modificato per fungere da suite di test).

Spiegazione

Il codice crea innanzitutto l'array di output assumendo input positivi n. L'array viene inizializzato come 1per l'input dispari o come l'array vuoto per l'input pari (questo viene creato come una matrice di identità con dimensioni uguali alla parità dell'input). Quindi si ripetono i seguenti ntempi per l'input pari e i n-1tempi per l'input dispari: estendere l'array con un frame contenente 0e aggiungere1 a tutti gli elementi.

Ad esempio, i passaggi per l'input nsono:

  • Matrice iniziale:

    1
    
  • Estendi con cornice:

    0 0 0
    0 1 0
    0 0 0
    
  • Aggiungi 1:

    1 1 1
    1 2 1
    1 1 1
    
  • Estendi con cornice:

    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
    
  • Aggiungi 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
    

Ciò fornisce l'output corretto per input positivo. Se l'input è negativo, l'array deve essere modificato aggiungendo l'input meno 1e prendendo il valore assoluto:

    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

Puoi vedere l'array crescere (codice modificato per mostrare passaggi intermedi) su MATL Online!L'interprete è ancora una beta. Se non funziona, premere nuovamente "Esegui" o ricaricare la pagina.

Codice commentato

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

Vedo che hai riutilizzato il codice dalla domanda sull'animazione. Eccezionale! La parte divertente è che questo codice vincerebbe anche in quella domanda, anche se è più lungo dell'altra versione;).
Magic Octopus Urn,

1
@carusocomputing Sì, è simile: duplica, visualizza, metti in pausa 1 secondo, cancella output :-)
Luis Mendo

Inoltre, non so perché, ma qualsiasi input sopra 14 si ferma a 14. Annullalo, è una limitazione della console online "Operazione scaduta".
Magic Octopus Urn,

@carusocomputing L'errore dice "timeout operazione". Immagino ci voglia troppo tempo per l'interprete. Prova a ridurre la pausa per dire .2secondi
Luis Mendo,

@carusocomputing Sì, questo è il timeout sull'interprete online. Al momento limitiamo i lavori a 30 secondi. Come suggerisce Luis, puoi ridurre il tempo di pausa
Suever,

3

Python 2.7: 123 122 120 byte

i probi possono ancora salvare qualche byte ...

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)per salvare 1 byte

edit2: (i+1)*(n>0)or-n-iper salvare 2 byte


3

Haskell, 119 113 110 104 102 101 byte

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]

Restituisce la matrice come un elenco di elenchi di numeri interi, ad esempio: f 2-> [[1,1,1,1],[1,2,2,1],[1,2,2,1],[1,1,1,1]].

Come funziona:

            [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

2

Perl, 175 byte

Include 1 byte per -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;

;

(C'è una nuova riga finale che non so mostrare con il markdown, ma ne hai bisogno).

Bisogni -pcosì come -M5.010o -Eper l'esecuzione:

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

Dannazione, è troppo lungo ... Proverò altri approcci quando avrò del tempo.


Perchè si usa eval?
Tito,

@Titus Perché y///non interpola, quindi usa le virgolette doppie per interpolare $we $k, quindi, evalper eseguire y///.
Dada,

2

Python 2, 109 byte

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]

2

J, 29 26 byte

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

Spiegazione

Il i.verbo di intervallo produce [0, 1, ..., n-1]positivo ne [n-1, n-2, ..., 0]negativo nche è utile qui.

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

2

Mathematica, 78 byte

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

Spiegazione

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

Crea matrice iniziale: 1x1 se dispari, 2x2 se pari.

Range[Abs@#-1]

Genera un elenco da 1 a abs (input) - 1.

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

Riempi l'array iniziale usando l'elenco di cui sopra.

... +1~Min~-#

Aggiungi 1 o -input, qualunque sia il più piccolo.

Abs

Applica valore assoluto all'intera matrice.


1

PHP, 177 157 byte

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"
";}

Corri con php -r '<code>

scorre attraverso righe e colonne, stampa i valori in base alla loro distanza dal centro.

  • $n=abs($z)+1: +1Salva un paio di +1e-1 nelle espressioni più tardi
  • i cicli vanno da -$n+1(pre-incremento nella condizione!) a $n-1( -abs($z)a abs($z))
  • la riga / colonna 0 (e per dispari $n: 1) vengono saltate
    ( $n&1è vero per le colonne pari qui! Ricorda +1?)
  • Anche la stampa per $ z positivi beneficia del +1.

1

Haskell, 191 183 173 169 168 byte

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]

Grazie a nimi per 2 10 20 24 byte!


1
negateè (0-)
nimi il

1
È possibile modificare fa [id!id,tail!init]!!mod n 2e quindi in linea in ge utilizzare la 1<2guardia per associare un risultato intermedio del ramo: g n| ... |q<-r<$>a n=([id!id,tail!init]!!mod n 2)q$a n. Non è necessario un nome per la funzione principale.
nimi,

1
Oh, è possibile inline a, troppo (e tornare alla 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
Ultimo uno per oggi: m=mapin !: ...(++).m ye 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 byte

(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)))

lè la dimensione dell'array. La n<0?-n-j:j+1sembra imbarazzante, ma non riesco a trovare niente di meglio.


1

Vim, 152 143 byte

Sono sicuro che questo potrebbe essere giocato di più, specialmente quelle ultime due righe, ma il mio cervello è impazzito.

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":"")

Provalo online!

Eccolo in formato xxd con caratteri non stampabili:

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":"")

Spiegazione

Costruisce la piramide dal centro, circondando il numero centrale con xes:

x x x
x 5 x
x x x

Quindi sostituisce xes con il numero successivo e lo circonda di xnuovo con es:

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

...e così via. Per i numeri pari fa la stessa cosa ma inizia con una base 2x2.

Ecco il codice "ungolfed". È in qualche modo non convenzionale il fatto che io "registri" una macro digitandola in un buffer (quindi tutti gli <C-v>s) e quindi eliminandola in un registro, che è il modo migliore che ho trovato per comporre una macro senza eseguire effettivamente i tasti.

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

0

PHP, 215 byte

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;}

0

R, 112 byte

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

Ha bisogno di un numero intero nnell'area di lavoro, altrimenti viene eseguito n=scan()per altri 8 byte.

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.