Erstellen Sie eine Pyramidenmatrix


23

Eine Pyramidenmatrix ist eine quadratische Matrix, bei der alle Zahlen vom Mittelpunkt aus zunehmen oder abnehmen, wie die beiden folgenden Matrizen:

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

Oder:

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

Bei einer ganzen Zahl ungleich Null n, schafft eine pyramidale Matrix , wobei die Zahlen aus gehen 1zu nentweder in ansteigender Reihenfolge (wenn n <0) oder absteigende Reihenfolge (wenn n> 0) von der Mitte. Wenn gerade nist, gibt es 4 Zentrumsnummern (siehe Beispiele).

Wie immer:

  • Optionales Eingabe- und Ausgabeformat
    • Anzahl der Leerzeichen, Trennzeichen usw. ist optional

Testfälle:

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
Warum unterscheidet sich der gerade Fall vom ungeraden Fall? Es gibt keinen Grund, warum die Matrizen nicht alle genau dem gleichen Muster folgen können.
Greg Martin

2
Weil die Eingabe die Länge der Seitenwand sein sollte, gibt es in diesem Fall einen Unterschied zwischen gerade und ungerade. Ich entschied mich stattdessen für den Maximalwert, behielt aber die ungeraden und geraden Unterschiede bei. Es mag seltsam erscheinen und keine gute Erklärung sein, aber es ist die Erklärung, warum es einen Unterschied gibt. :-)
Stewie Griffin

2
Können wir annehmen -10 < n < 10?
Titus

2
Es ist in Ordnung, wenn es nicht wie ein perfektes Quadrat aussieht , solange es numerisch gesehen eins ist. Wenn Reihen mit vielen Zehnern breiter sind als solche mit wenigen Zehnern, dann ist das
Stewie Griffin

Antworten:


5

Jelly , 18 17 Bytes

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

Probieren Sie es online! oder überprüfen Sie alle Testfälle .

Wie es funktioniert

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

Online ausprobieren *

Hinweis: Diese Antwort verwendet die R1C1-Notation. Wenn du das selbst probierst. Sie müssen dies in den Excel-Optionen aktivieren.

Die angegebene Formel muss in jeder Zelle jenseits von (2,2) vorhanden sein. Geben Sie Ihre gewünschte Pyramidengröße in (1,1) ein.

Schnelles Screen-Cap der Formel in Aktion:
Bildbeschreibung hier eingeben

Hier ist ein zusätzliches Bild von etwas Spaß beim bedingten Formatieren!

* Die Aktualisierung dauert derzeit sehr lange.


Dies behandelt die negativen Fälle oder die geraden Fälle nicht richtig. Sie können auch den Code auf =MAX(MIN(MIN(ROW()-1,COLUMN()-1),MIN(((ABS(A1)-1)*2+3)-ROW(),((ABS(A1)-1)*2+3)-COLUMN())),0)92 Byte verkürzen . Die Fälle werden jedoch immer noch nicht behandelt, und die Formel kann nicht verschoben werden, da der Zellverweis nicht gesperrt ist.
Gtwebb

1
Mehr Golf gleiche Probleme. =MEDIAN(MIN(ROW()-1,COLUMN()-1),ABS(A1)*2+1-MAX(ROW(),COLUMN()),0)
Gtwebb

@gtwebb danke, dass du es mir erzählt hast. Ich muss reparieren

-1. Das geht nicht. Negative Eingaben werden nicht verarbeitet. Es verarbeitet nicht einmal Eingaben. Wenn Sie diese Formel in jede zutreffende Zelle Rangeeinfügen , benötigen Sie entweder eine oder eine Menge mehr als 126 Bytes.
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]

Erstelle Liste

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

und ein wenig damit spielen.


edit: neue art liste zu erstellen + danke lynn für zwei bytes


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

@ Rod Nein, wird es nicht. Was bringt dich dazu, so zu denken?
Pacholik

3
Dies ist eine der Regeln
Rod

@ Rod Oh. Vor ein paar Minuten. Bearbeitet
Pacholik

2
Es ist nicht neu, nur nicht hervorgehoben: c
Rod

6

MATL , 26 24 Bytes

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

Probieren Sie es online! Oder überprüfen Sie alle Testfälle (leicht modifizierter Code als Testsuite).

Erläuterung

Der Code erstellt zuerst das Ausgabearray unter der Annahme einer positiven Eingabe n. Das Array wird 1für ungerade Eingaben oder für gerade Eingaben als leeres Array initialisiert (dies wird als Identitätsmatrix mit einer Größe erstellt, die der Parität der Eingabe entspricht). Das Folgende wird dann nfür gerade Eingaben und n-1für ungerade Eingaben wiederholt : Erweitern Sie das Array mit einem Rahmen 0, 1der alle Elemente enthält , und fügen Sie ihn hinzu .

Die Eingabeschritte nlauten beispielsweise:

  • Anfangsarray:

    1
    
  • Mit Rahmen verlängern:

    0 0 0
    0 1 0
    0 0 0
    
  • Hinzufügen 1:

    1 1 1
    1 2 1
    1 1 1
    
  • Mit Rahmen verlängern:

    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
    
  • Hinzufügen 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
    

Dies gibt den korrekten Ausgang für den positiven Eingang. Wenn die Eingabe negativ ist, muss das Array geändert werden, indem das Minus der Eingabe hinzugefügt 1und der absolute Wert verwendet wird:

    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

Sie können das Anwachsen des Arrays (modifizierter Code, um Zwischenschritte anzuzeigen ) bei MATL Online beobachten! Der Dolmetscher ist noch eine Beta. Wenn es nicht funktioniert, klicken Sie erneut auf "Ausführen" oder laden Sie die Seite neu.

Kommentierter Code

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

Sie haben den Code aus der Animationsfrage wiederverwendet. Genial! Komischerweise würde dieser Code in dieser Frage auch noch gewinnen, obwohl er länger ist als Ihre andere Version;).
Magic Octopus Urn

1
@ carusocomputing Ja, es ist ähnlich: duplizieren, anzeigen, 1 Sekunde pausieren, Ausgabe löschen :-)
Luis Mendo

Ich weiß auch nicht warum, aber alle Eingaben über 14 hören bei 14 auf. Heben Sie das auf, es ist eine Einschränkung der Online-Konsole "Operation timed out".
Magic Octopus Urn

@carusocomputing Der Fehler besagt "Operation Timeout". Ich denke, es dauert dem Dolmetscher einfach zu lange. Versuchen Sie , die Pause auf .2Sekunden zu
verkürzen

@carusocomputing Ja, das ist die Zeitüberschreitung beim Online-Dolmetscher. Wir begrenzen derzeit Aufträge auf 30 Sekunden. Wie Luis vorschlägt, können Sie die Pausenzeit
verkürzen

3

Python 2.7: 123 122 120 Bytes

Probs können noch ein paar Bytes sparen ...

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)um 1 Byte zu speichern

edit2: (i+1)*(n>0)or-n-ium 2 Bytes zu speichern


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]

Gibt die Matrix als Liste von Listen mit ganzen Zahlen zurück, zum Beispiel: f 2-> [[1,1,1,1],[1,2,2,1],[1,2,2,1],[1,1,1,1]].

Wie es funktioniert:

            [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 Bytes

Beinhaltet 1 Byte für -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;

;

(Es gibt eine nachgestellte Zeile, die ich nicht mit dem Markdown anzeigen kann, aber Sie brauchen sie).

Bedürfnisse -psowie -M5.010oder -Ezu laufen:

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

Verdammt, das ist zu lang ... Ich werde einige andere Ansätze ausprobieren, wenn ich etwas Zeit habe.


Warum benutzt du eval?
Titus

@Titus Da y///nicht interpoliert, verwenden Sie die doppelten Anführungszeichen, um zu interpolieren $wund $kdann evalauszuführen 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]

2

J, 29 26 Bytes

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

Verwendung

   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

Erläuterung

Der Bereich i.verb gibt [0, 1, ..., n-1]für positiv nund [n-1, n-2, ..., 0]für negativ aus, nwas hier nützlich ist.

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 Bytes

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

Erläuterung

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

Erstelle eine Anfangsmatrix: 1x1 wenn ungerade, 2x2 wenn gerade.

Range[Abs@#-1]

Erzeugen Sie eine Liste von 1 bis abs (Eingabe) - 1.

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

Füllen Sie das ursprüngliche Array mit der oben genannten Liste auf.

... +1~Min~-#

Addiere 1 oder -input, je nachdem, welcher Wert kleiner ist.

Abs

Wenden Sie den absoluten Wert auf die gesamte Matrix an.


1

PHP, 177 157 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"
";}

renn mit php -r '<code>

Durchläuft Zeilen und Spalten und druckt die Werte in Abhängigkeit vom Abstand zur Mitte.

  • $n=abs($z)+1: Das +1spart ein paar+1 und -1in späteren Ausdrücken
  • Schleifen gehen von -$n+1(Vorinkrement in der Bedingung!) bis $n-1( -abs($z)bisabs($z) )
  • Zeile / Spalte 0 (und für ungerade $n: 1) werden übersprungen
    ( $n&1gilt hier für gerade Spalten!+1 ?)
  • Das Drucken für positive $ z profitiert auch von der +1.

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

Verwendung:

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]

Danke an nimi für 2 10 20 24 Bytes!


1
negateist (0-)
nimi

1
Sie können ändern , fzu [id!id,tail!init]!!mod n 2und dann inline es in gund die Verwendung 1<2Wache ein Zwischenergebnis der Branche zu binden: g n| ... |q<-r<$>a n=([id!id,tail!init]!!mod n 2)q$a n. Sie brauchen keinen Namen für die Hauptfunktion.
Nimi

1
Oh, Sie können Inline a, auch (und wechseln Sie wieder auf die 1<2Wache): 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
Letzte für heute: m=mapin !: ...(++).m yund 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)))

list die Größe des Arrays. Das n<0?-n-j:j+1scheint umständlich, aber ich kann nichts besseres finden.


1

Vim, 152 143 Bytes

Ich bin mir sicher, dass man mehr Golf spielen könnte, vor allem in den letzten beiden Zeilen, aber mein Gehirn ist verrückt.

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

Probieren Sie es online!

Hier ist es im xxd-Format mit nicht druckbaren Zeichen:

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

Erläuterung

Es baut die Pyramide von der Mitte aus und umgibt die Zentrumsnummer mit xes:

x x x
x 5 x
x x x

Dann ersetzt es die xes durch die nächste Zahl und umgibt sie erneut mit xes:

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

...und so weiter. Bei geraden Zahlen geschieht das Gleiche, jedoch mit einer 2x2-Basis.

Hier ist der Code "ungolfed". Es ist insofern etwas unkonventionell, als ich ein Makro "aufzeichne", indem ich es in einen Puffer (daher alle <C-v>s) schreibe und dann in ein Register lösche. Dies ist der beste Weg, ein Makro zu erstellen, ohne die Tastenanschläge tatsächlich auszuführen.

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

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

Benötigt eine Ganzzahl nim Arbeitsbereich, andernfalls werden n=scan()zusätzliche 8 Byte benötigt.

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.