Matrix-Trace für jede Matrix durch… Bresenhams Linienrasterung

12

Davon inspiriert .

Agatha Stephendale, eine Anfängerin, die sich wirklich für Rastergrafiken interessiert, hat einen Kurs in linearer Algebra belegt. Jetzt stellt sie sich Matrizen als Rechtecke vor, aber in ihrem künstlerischen Denken fügt sie diagonale Linien zu diesen Rechtecken hinzu und versucht, Spuren entlang dieser zu berechnen. Tatsächlich möchte sie die Spuren aller Matrizen berechnen, nicht nur der quadratischen.

Da Agatha Künstlerin ist, kann sie in ihrem bevorzugten Bildbearbeitungsprogramm Linien zeichnen. Letzteres verwendet den Bresenham-Algorithmus , um Linien zu zeichnen. Sie überprüfte sogar Wikipedia und fand den Pseudocode:

Bildbeschreibung hier eingeben

 function line(x0, y0, x1, y1)
     real deltax := x1 - x0
     real deltay := y1 - y0
     real deltaerr := abs(deltay / deltax)    // Assume deltax != 0 (line is not vertical),
           // note that this division needs to be done in a way that preserves the fractional part
     real error := 0.0 // No error at start
     int y := y0
     for x from x0 to x1 
         plot(x,y)
         error := error + deltaerr
         while error ≥ 0.5 then
             y := y + sign(deltay) * 1
             error := error - 1.0

(Beachten Sie, dass dieser Pseudocode nur für Steigungen unter 1 funktioniert. Bei hohen Gittern sollte eine ähnliche Behandlung durchgeführt werden, jedoch mit einer Schleife y. Siehe diesen Abschnitt für die beiden Fälle.)

Agatha stellt sich eine Matrix als Rechteck vor, zeichnet eine diagonale Linie darin und Bresenhams Algorithmus bestimmt, welche Elemente einer Matrix zur Diagonale gehören. Dann nimmt sie ihre Summe und dies ist es, was sie in so wenigen Bytes wie möglich implementieren möchte, weil sie ein armer Student ist und sich keine Festplatten mit hoher Kapazität leisten kann, um ihren Code zu speichern.

Aufgabe

Geben Sie bei einer Matrix A die Summe der Elemente zurück, die auf der gerasterten Hauptdiagonale liegen (von links oben nach rechts unten), wobei letztere durch den Bresenhamschen Linienalgorithmus bestimmt wird. Das heißt, unter der Annahme, dass die Matrix ein m × n- Gitter darstellt, zeichnen Sie auf diesem Gitter eine Linie von A [1, 1] bis A [m, n] unter Verwendung des Bresenham-Algorithmus und nehmen Sie die Summe aller Elemente auf der Linie. Beachten Sie, dass für 1 × N- und N × 1- Matrizen die gesamte Matrix zu einer eigenen Diagonale wird (da auf diese Weise eine Linie vom ersten Element der ersten Zeile zum letzten Element der letzten Zeile gezogen wird).

Eingabe: Eine reelle Matrix (kann eine 1 × 1- Matrix, eine Zeilenmatrix, eine Spaltenmatrix oder eine rechteckige Matrix sein). Ausgabe: eine Zahl.

Beachten Sie, dass einige Quellen (z. B. der obige Pseudocode der Wikipedia) die Bedingungsprüfung verwenden error≥0.5, während andere Quellen diese verwenden error>0.5. Sie sollten die ursprünglich veröffentlichte ( error≥0.5) verwenden. Wenn die Alternative error>0.5in Ihrem Code jedoch kürzer ist, können Sie sie implementieren (da dies Code Golf ist), erwähnen Sie sie jedoch ausdrücklich . Siehe Testfall 4.

Herausforderungsregeln

  • E / A-Formate sind flexibel. Eine Matrix kann aus mehreren Zeilen von durch Leerzeichen getrennten Zahlen bestehen, die durch Zeilenumbrüche voneinander getrennt sind, oder aus einem Array von Zeilenvektoren oder einem Array von Spaltenvektoren usw.
  • Das ist , also gewinnt die kürzeste Antwort in Bytes.
  • Für Ihre Antwort gelten Standardregeln. Daher dürfen Sie STDIN / STDOUT, Funktionen / Methoden mit den richtigen Parametern und vollständige Programme vom Rückgabetyp verwenden.
  • Standardlücken sind verboten.

Testfälle

  1. [[1,2,3],[4,5,6],[7,8,9]]1+5+9→ Ausgang: 15.

Testfall 1

  1. [[1,2,3,4],[5,6,7,8]]1+2+7+8→ Ausgang: 18.

Testfall 2

  1. [[1,2,3,4,5,6],[7,8,9,10,11,12],[13,14,15,16,17,18],[19,20,21,22,23,24]]1+8+9+16+17+24→ Ausgang: 75.

Testfall 3

  1. [[1,2,3,4,5],[6,7,8,9,10]]1+2+8+9+10(unter Verwendung der Fehlerbedingung) → Ausgang: 30.

Testfall 4

Wenn es jedoch kürzer wäre, die strenge Ungleichung >in Ihrem Code zu verwenden, ist die Ausgabe zulässig. 1+2+3+9+10=25Sie sollten sie jedoch separat erwähnen.

Testfall 5

  1. [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]1+5+8+12→ Ausgang: 26.

Testfall 5

  1. [[-0.3,0.5]]→ Ausgang: 0.2.

  2. [[3.1],[2.9]]→ Ausgang: 6.

  3. [[-5]]→ Ausgang: -5.

Weitere Informationen zum Bresenham-Algorithmus

Andreï Kostyrka
quelle
Angeforderte Testfall: [[1,2,3,4,5],[6,7,8,9,10]].
user202729
@ user202729 Wurde hinzugefügt, um Mehrdeutigkeiten aufzulösen.
Andreï Kostyrka
Können wir einen Testfall bekommen, der größer als breit ist? Like[[1,2],[3,4],[5,6],[7,8],[9,10]]
Giuseppe
@ Giuseppe Fang. Siehe jetzt Fall 5. Für Ihr Beispiel sollte die Antwort 28(mit der erwarteten Implementierung) oder 27 (mit >der optionalen Implementierung) sein.
lauten
Kann das Programm nur Matrizen bis zu einer festen Größe (z. B. 500 × 500) unterstützen?
user202729

Antworten:

3

Gelee , 25 Bytes

ZXL>LƲ¡µLḶ÷’Ɗ×XL’Ɗær0ị"OS

Probieren Sie es online!

user202729
quelle
Wenn in Jelly 1 oder 2 Byte auf die nächste integrierte Ganzzahl gerundet wären, wäre diese Antwort 23 oder 24 Byte.
User202729
3

SmileBASIC, 101 99 Bytes

DEF D A,W,H
GCLS
GTRI.,0,0,0,W-1,H-1FOR I=0TO W*H-1=I MOD W
S=S+A[I/W,M]*!!GSPOIT(M,I/W)NEXT?S
END

Ursprünglich dachte ich daran, die GLINE-Funktion zum Zeichnen einer Linie zu verwenden, aber anscheinend wird nicht der richtige Algorithmus verwendet. Allerdings GTRI nicht zu funktionieren scheint,

Testfall 4 Ausgänge 30.

Die Eingabe ist ein 2D-Array in der Form [Y, X] zusammen mit der Breite / Höhe (es gibt keine Möglichkeit, die Abmessungen eines Arrays zu überprüfen, nur die Gesamtzahl der Elemente).

12Me21
quelle
1

JavaScript (ES6), 110 103 Byte

Ausgänge 25für den 4. Testfall.

a=>(X=a[x=y=0].length-1,Y=1-a.length,g=e=>a[y][x]+(x-X|y+Y&&g(e+(e*2>Y&&++x&&Y)+(e*2<X&&++y&&X))))(X+Y)

Probieren Sie es online!

Oder 88 Bytes, wenn die Dimensionen der Matrix als Eingabe zulässig sind.

Arnauld
quelle
1

Python 3.X, 269 Bytes

Bei Eingabe als durch Kommas getrennte Zeilen mit durch Leerzeichen getrennten Zahlen.

import math;c=math.ceil;a=[[float(k)for k in q.split(" ")]for q in input().split(",")];_=len;m=lambda f,t,x,y,e,d:sum(x[0]for x in a)if 2>_(a[0])else m(*[0]*4,*[(_(a)-1)/(_(a[0])-1)]*2)if f else m(f,t+a[y][x],x+1,y+c(e-0.5),e+d-c(e-0.5),d)if x<_(a[0])else t;m(1,*[0]*5)

Vor dem Golfen:

def line(a):
   if len(a[0])<2: return sum([x[0] for x in a])
   e = d = abs((len(a)-1)/(len(a[0])-1))
   y=t=0
   for x in range(len(a[0])): 
       t += a[y][x]
       f = ceil(e-0.5)
       y += f
       e += d-f
   return t
Budd
quelle
Es sieht so aus, als würde c=math.ceildas Programm länger werden ...
user202729
Außerdem brauchst du das nicht []zwischen den sum(..). a if c else bkann oft sein c and a or b.
user202729
input("")kann sein input().
user202729
Auch ... was ist das Eingabe- / Ausgabeformat? Auf Bildschirm drucken?
user202729
1

FMSLogo , 136 Bytes

make 1 rl
setxy -1+count :1 -1+count last :1
pu home
make 9 0
foreach :1[foreach ?[if
0=last pixel[make 9 :9+?]fd 1]setxy xcor+1 0]pr :9

Vollständiges Programm: Fordern Sie den Benutzer zur Eingabe auf (Popup-Dialogfeld) und drucken Sie die Ausgabe auf dem Bildschirm aus.

Zeichnen Sie einfach eine Linie auf dem Bildschirm und berechnen Sie die Ausgabe. Verwenden Sie eine strikte Ungleichung.


Dies unterstützt nur Matrixgrößen bis zur Leinwandgröße von FMSLogo (ca. 500 × 500).

Ungolfed-Code:

Make "input ReadList
SetXY (-1+Count :input) (-1+Count Last :input)
PenUp
Home
Make "sum 0
ForEach :input[
    ForEach ?[
        If 0=Last Pixel[
            Make "sum :sum+?
        ]
        Forward 1
    ]
    SetXY XCor+1 0
]
Print :sum
user202729
quelle