Sum of elements below main diagonal of matrix: Difference between revisions
Not a robot (talk | contribs) (Add C++) |
(→{{header|JavaScript}}: Added a version in JavaScript.) |
||
Line 239: | Line 239: | ||
sum_below_diagonal mat |
sum_below_diagonal mat |
||
69</pre> |
69</pre> |
||
=={{header|JavaScript}}== |
|||
Defining the lower triangle of a square matrix. |
|||
<lang javascript>(() => { |
|||
"use strict"; |
|||
// -------- LOWER TRIANGLE OF A SQUARE MATRIX -------- |
|||
// lowerTriangle :: [[a]] -> Either String [[a]] |
|||
const lowerTriangle = matrix => |
|||
// Either a message, if the matrix is not square, |
|||
// or the lower triangle of the matrix. |
|||
isSquare(matrix) ? ( |
|||
Right( |
|||
matrix.reduce( |
|||
([n, rows], xs) => [ |
|||
1 + n, |
|||
rows.concat([xs.slice(0, n)]) |
|||
], |
|||
[0, []] |
|||
)[1] |
|||
) |
|||
) : Left("Not a square matrix"); |
|||
// isSquare :: [[a]] -> Bool |
|||
const isSquare = rows => { |
|||
// True if the length of every row in the matrix |
|||
// matches the number of rows in the matrix. |
|||
const n = rows.length; |
|||
return rows.every(x => n === x.length); |
|||
}; |
|||
// ---------------------- TEST ----------------------- |
|||
const main = () => |
|||
either( |
|||
msg => `Lower triangle undefined :: ${msg}` |
|||
)( |
|||
rows => sum([].concat(...rows)) |
|||
)( |
|||
lowerTriangle([ |
|||
[1, 3, 7, 8, 10], |
|||
[2, 4, 16, 14, 4], |
|||
[3, 1, 9, 18, 11], |
|||
[12, 14, 17, 18, 20], |
|||
[7, 1, 3, 9, 5] |
|||
]) |
|||
); |
|||
// --------------------- GENERIC --------------------- |
|||
// Left :: a -> Either a b |
|||
const Left = x => ({ |
|||
type: "Either", |
|||
Left: x |
|||
}); |
|||
// Right :: b -> Either a b |
|||
const Right = x => ({ |
|||
type: "Either", |
|||
Right: x |
|||
}); |
|||
// either :: (a -> c) -> (b -> c) -> Either a b -> c |
|||
const either = fl => |
|||
// Application of the function fl to the |
|||
// contents of any Left value in e, or |
|||
// the application of fr to its Right value. |
|||
fr => e => e.Left ? ( |
|||
fl(e.Left) |
|||
) : fr(e.Right); |
|||
// sum :: [Num] -> Num |
|||
const sum = xs => |
|||
// The numeric sum of all values in xs. |
|||
xs.reduce((a, x) => a + x, 0); |
|||
// MAIN --- |
|||
return main(); |
|||
})();</lang> |
|||
{{Out}} |
|||
<pre>69</pre> |
|||
=={{header|Julia}}== |
=={{header|Julia}}== |
Revision as of 17:19, 22 July 2021
- Task
Find and display the sum of elements that are below the main diagonal of a matrix.
The matrix should be a square matrix.
- ─── Matrix to be used: ───
[[1,3,7,8,10], [2,4,16,14,4], [3,1,9,18,11], [12,14,17,18,20], [7,1,3,9,5]]
ALGOL 68
<lang algol68>BEGIN # sum the elements below the main diagonal of a matrix #
# returns the sum of the elements below the main diagonal # # of m, m must be a square matrix # OP LOWERSUM = ( [,]INT m )INT: IF 1 LWB m /= 2 LWB m OR 1 UPB m /= 2 UPB m THEN # the matrix isn't square # print( ( "Matrix must be suare for LOWERSUM", newline ) ); stop ELSE # have a square matrix # INT sum := 0; FOR r FROM 1 LWB m + 1 TO 1 UPB m DO FOR c FROM 1 LWB m TO r - 1 DO sum +:= m[ r, c ] OD OD; sum FI; # LOWERSUM # # task test case # print( ( whole( LOWERSUM [,]INT( ( 1, 3, 7, 8, 10 ) , ( 2, 4, 16, 14, 4 ) , ( 3, 1, 9, 18, 11 ) , ( 12, 14, 17, 18, 20 ) , ( 7, 1, 3, 9, 5 ) ) , 0 ) , newline ) )
END</lang>
- Output:
69
ALGOL W
One of the rare occasions where the lack of lower/upper bound operators in Algol W actually simplifies things, assuming the programmer gets things right... <lang algolw>begin % sum the elements below the main diagonal of a matrix %
% returns the sum of the elements below the main diagonal % % of m, m must have bounds lb :: ub, lb :: ub % integer procedure lowerSum ( integer array m ( *, * ) ; integer value lb, ub ) ; begin integer sum; sum := 0; for r := lb + 1 until ub do begin for c := lb until r - 1 do sum := sum + m( r, c ) end for_r; sum end lowerSum ; begin % task test case % integer array m ( 1 :: 5, 1 :: 5 ); integer r, c; r := 1; c := 0; for v := 1, 3, 7, 8, 10 do begin c := c + 1; m( r, c ) := v end; r := 2; c := 0; for v := 2, 4, 16, 14, 4 do begin c := c + 1; m( r, c ) := v end; r := 3; c := 0; for v := 3, 1, 9, 18, 11 do begin c := c + 1; m( r, c ) := v end; r := 4; c := 0; for v := 12, 14, 17, 18, 20 do begin c := c + 1; m( r, c ) := v end; r := 5; c := 0; for v := 7, 1, 3, 9, 5 do begin c := c + 1; m( r, c ) := v end; write( i_w := 1, lowerSum( m, 1, 5 ) ) end
end.</lang>
- Output:
69
APL
<lang apl>sum_below_diagonal ← +/(∊⊢×(>/¨⍳∘⍴))</lang>
- Output:
matrix ← 5 5⍴1 3 7 8 10 2 4 16 14 4 3 1 9 18 11 12 14 17 18 20 7 1 3 9 5 sum_below_diagonal matrix 69
C++
<lang cpp>#include <iostream>
- include <vector>
template<typename T> T sum_below_diagonal(const std::vector<std::vector<T>>& matrix) {
T sum = 0; for (std::size_t y = 0; y < matrix.size(); y++) for (std::size_t x = 0; x < y && matrix[y].size() && x < y; x++) sum += matrix[y][x]; return sum;
}
int main() {
std::vector<std::vector<int>> matrix = { {1,3,7,8,10}, {2,4,16,14,4}, {3,1,9,18,11}, {12,14,17,18,20}, {7,1,3,9,5} }; std::cout << sum_below_diagonal(matrix) << std::endl; return 0;
}</lang>
- Output:
69
F#
<lang fsharp> // Sum below leading diagnal. Nigel Galloway: July 21st., 2021 let _,n=[[ 1; 3; 7; 8;10];
[ 2; 4;16;14; 4]; [ 3; 1; 9;18;11]; [12;14;17;18;20]; [ 7; 1; 3; 9; 5]]|>List.fold(fun(n,g) i->let i,_=i|>List.splitAt n in (n+1,g+(i|>List.sum)))(0,0) in printfn "%d" n
</lang>
- Output:
69
Factor
<lang factor>USING: kernel math math.matrices prettyprint sequences ;
- sum-below-diagonal ( matrix -- sum )
dup square-matrix? [ "Matrix must be square." throw ] unless 0 swap [ head sum + ] each-index ;
{
{ 1 3 7 8 10 } { 2 4 16 14 4 } { 3 1 9 18 11 } { 12 14 17 18 20 } { 7 1 3 9 5 }
} sum-below-diagonal .</lang>
- Output:
69
Go
<lang go>package main
import (
"fmt" "log"
)
func main() {
m := [][]int{ {1, 3, 7, 8, 10}, {2, 4, 16, 14, 4}, {3, 1, 9, 18, 11}, {12, 14, 17, 18, 20}, {7, 1, 3, 9, 5}, } if len(m) != len(m[0]) { log.Fatal("Matrix must be square.") } sum := 0 for i := 1; i < len(m); i++ { for j := 0; j < i; j++ { sum = sum + m[i][j] } } fmt.Println("Sum of elements below main diagonal is", sum)
}</lang>
- Output:
Sum of elements below main diagonal is 69
Haskell
Defining the lower triangle:
<lang haskell>---------------------- LOWER TRIANGLE --------------------
lowerTriangle :: a -> Either String a lowerTriangle matrix
| isSquare matrix = (Right . snd) $ foldr (\xs (n, rows) -> (pred n, take n xs : rows)) (pred $ length matrix, []) matrix | otherwise = Left "Not a square matrix."
isSquare :: a -> Bool isSquare [] = True isSquare rows = all ((n ==) . length) rows
where n = length rows
TEST -------------------------
main :: IO () main =
either putStrLn (print . sum . concat) (lowerTriangle testMatrix)
testMatrix :: Integer testMatrix =
[ [1, 3, 7, 8, 10], [2, 4, 16, 14, 4], [3, 1, 9, 18, 11], [12, 14, 17, 18, 20], [7, 1, 3, 9, 5] ]</lang>
- Output:
69
J
<lang j>sum_below_diagonal =: [:+/@,[*>/~@i.@#</lang>
- Output:
mat 1 3 7 8 10 2 4 16 14 4 3 1 9 18 11 12 14 17 18 20 7 1 3 9 5 sum_below_diagonal mat 69
JavaScript
Defining the lower triangle of a square matrix.
<lang javascript>(() => {
"use strict";
// -------- LOWER TRIANGLE OF A SQUARE MATRIX --------
// lowerTriangle :: a -> Either String a const lowerTriangle = matrix => // Either a message, if the matrix is not square, // or the lower triangle of the matrix. isSquare(matrix) ? ( Right( matrix.reduce( ([n, rows], xs) => [ 1 + n, rows.concat([xs.slice(0, n)]) ], [0, []] )[1] ) ) : Left("Not a square matrix");
// isSquare :: a -> Bool const isSquare = rows => { // True if the length of every row in the matrix // matches the number of rows in the matrix. const n = rows.length;
return rows.every(x => n === x.length); };
// ---------------------- TEST ----------------------- const main = () => either( msg => `Lower triangle undefined :: ${msg}` )( rows => sum([].concat(...rows)) )( lowerTriangle([ [1, 3, 7, 8, 10], [2, 4, 16, 14, 4], [3, 1, 9, 18, 11], [12, 14, 17, 18, 20], [7, 1, 3, 9, 5] ]) );
// --------------------- GENERIC ---------------------
// Left :: a -> Either a b const Left = x => ({ type: "Either", Left: x });
// Right :: b -> Either a b const Right = x => ({ type: "Either", Right: x });
// either :: (a -> c) -> (b -> c) -> Either a b -> c const either = fl => // Application of the function fl to the // contents of any Left value in e, or // the application of fr to its Right value. fr => e => e.Left ? ( fl(e.Left) ) : fr(e.Right);
// sum :: [Num] -> Num const sum = xs => // The numeric sum of all values in xs. xs.reduce((a, x) => a + x, 0);
// MAIN --- return main();
})();</lang>
- Output:
69
Julia
The tril function is part of Julia's built-in LinearAlgebra package. tril(A) includes the main diagonal and the components of the matrix A to the left and below the main diagonal. tril(A, -1) returns the lower triangular elements of A excluding the main diagonal. The excluded elements of the matrix are set to 0. <lang julia>using LinearAlgebra
A = [ 1 3 7 8 10;
2 4 16 14 4; 3 1 9 18 11; 12 14 17 18 20; 7 1 3 9 5 ]
@show tril(A)
@show tril(A, -1)
@show sum(tril(A, -1)) # 69
</lang>
- Output:
tril(A) = [1 0 0 0 0; 2 4 0 0 0; 3 1 9 0 0; 12 14 17 18 0; 7 1 3 9 5] tril(A, -1) = [0 0 0 0 0; 2 0 0 0 0; 3 1 0 0 0; 12 14 17 0 0; 7 1 3 9 0] sum(tril(A, -1)) = 69
MiniZinc
<lang MiniZinc> % Sum below leading diagnal. Nigel Galloway: July 22nd., 2021 array [1..5,1..5] of int: N=[|1,3,7,8,10|2,4,16,14,4|3,1,9,18,11|12,14,17,18,20|7,1,3,9,5|]; int: res=sum(n,g in 1..5 where n>g)(N[n,g]); output([show(res)]) </lang>
- Output:
69 ----------
Nim
We use a generic definition for the square matrix type. The compiler insures that the matrix we provide is actually square.
<lang Nim>type SquareMatrix[T: SomeNumber; N: static Positive] = array[N, array[N, T]]
func sumBelowDiagonal[T, N](m: SquareMatrix[T, N]): T =
for i in 1..<N: for j in 0..<i: result += m[i][j]
const M = [[ 1, 3, 7, 8, 10],
[ 2, 4, 16, 14, 4], [ 3, 1, 9, 18, 11], [12, 14, 17, 18, 20], [ 7, 1, 3, 9, 5]]
echo sumBelowDiagonal(M)</lang>
- Output:
69
Phix
constant M = {{ 1, 3, 7, 8, 10}, { 2, 4, 16, 14, 4}, { 3, 1, 9, 18, 11}, {12, 14, 17, 18, 20}, { 7, 1, 3, 9, 5}} atom res = 0 integer height = length(M) for row=1 to height do integer width = length(M[row]) if width!=height then crash("not square") end if for col=1 to row-1 do res += M[row][col] end for end for ?res
You could of course start row from 2 and get the same result, for row==1 the col loop iterates zero times.
Without the checks for square M expect (when not square) wrong/partial answers for height<=width+1, and (still human readable) runtime crashes for height>width+1.
- Output:
69
PL/M
This can be compiled with the original 8080 PL/M compiler and run under CP/M or an emulator/clone. <lang pli>100H: /* SUM THE ELEMENTS BELOW THE MAIN DIAGONAL OF A MATRIX */
/* CP/M BDOS SYSTEM CALL, IGNORE THE RETURN VALUE */ BDOS: PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GOTO 5; END; PR$STRING: PROCEDURE( S ); DECLARE S ADDRESS; CALL BDOS( 9, S ); END; PR$NUMBER: PROCEDURE( N ); /* PRINTS A NUMBER IN THE MINIMUN FIELD WIDTH */ DECLARE N ADDRESS; DECLARE V ADDRESS, N$STR ( 6 )BYTE, W BYTE; V = N; W = LAST( N$STR ); N$STR( W ) = '$'; N$STR( W := W - 1 ) = '0' + ( V MOD 10 ); DO WHILE( ( V := V / 10 ) > 0 ); N$STR( W := W - 1 ) = '0' + ( V MOD 10 ); END; CALL PR$STRING( .N$STR( W ) ); END PR$NUMBER;
/* RETURNS THE SUM OF THE ELEMENTS BELOW THE MAIN DIAGONAL OF MX */ /* MX WOULD BE DECLARED AS ( UB, UB )ADDRESS IF PL/M SUPPORTED */ /* 2-DIMENSIONAL ARRAYS, IT DOESN'T SO MX MUST ACTULLY BE DECLARED */ /* ( UB * UB )ADDRESS - EXCEPT THE BOUND MUST BE A CONSTANT, NOT AN */ /* EXPRESSION */ /* NOTE ADDRESS MEANS UNSIGNED 16-BIT QUANTITY, WHICH CAN BE USED FOR */ /* OTHER PURPOSES THAN JUST POINTERS */ LOWER$SUM: PROCEDURE( MX, UB )ADDRESS; DECLARE ( MX, UB ) ADDRESS; DECLARE ( SUM, R, C, STRIDE, R$PTR ) ADDRESS; DECLARE M$PTR ADDRESS, M$VALUE BASED M$PTR ADDRESS; SUM = 0; STRIDE = UB + UB; R$PTR = MX + STRIDE; /* ADDRESS OF ROW 1 ( THE FIRST ROW IS 0 ) */ DO R = 1 TO UB - 1; M$PTR = R$PTR; DO C = 0 TO R - 1; SUM = SUM + M$VALUE; M$PTR = M$PTR + 2; END; R$PTR = R$PTR + STRIDE; /* ADDRESS OF THE NEXT ROW */ END; RETURN SUM; END LOWER$SUM ;
/* TASK TEST CASE */ DECLARE T ( 25 )ADDRESS INITIAL( 1, 3, 7, 8, 10 , 2, 4, 16, 14, 4 , 3, 1, 9, 18, 11 , 12, 14, 17, 18, 20 , 7, 1, 3, 9, 5 ); CALL PR$NUMBER( LOWER$SUM( .T, 5 ) );
EOF</lang>
- Output:
69
Python
<lang python>from numpy import array, tril, sum
A = [[1,3,7,8,10],
[2,4,16,14,4], [3,1,9,18,11], [12,14,17,18,20], [7,1,3,9,5]]
print(sum(tril(A, -1))) # 69</lang>
Or, defining the lower triangle for ourselves:
<lang python>Lower triangle of a matrix
from itertools import chain, islice from functools import reduce
def lowerTriangle(matrix):
Either None, if the matrix is not square, or the rows of the matrix, each containing only those values that form part of the lower triangle. def go(n_rows, xs): n, rows = n_rows return 1 + n, rows + [list(islice(xs, n))]
return reduce( go, matrix, (0, []) )[1] if isSquare(matrix) else None
- isSquare :: a -> Bool
def isSquare(matrix):
True if all rows of the matrix share the length of the matrix itself. n = len(matrix) return 0 == n or ( all([n == len(x) for x in matrix]) )
- ------------------------- TEST -------------------------
- main :: IO ()
def main():
Sum of integers in the lower triangle of a matrix. rows = lowerTriangle([ [1, 3, 7, 8, 10], [2, 4, 16, 14, 4], [3, 1, 9, 18, 11], [12, 14, 17, 18, 20], [7, 1, 3, 9, 5] ])
print( "Not a square matrix." if None is rows else ( sum(chain(*rows)) ) )
- MAIN ---
if __name__ == '__main__':
main()</lang>
- Output:
69
Raku
<lang perl6>sub lower-triangle-sum (@matrix) { sum flat (1..@matrix).map( { @matrix[^$_]»[^($_-1)] } )»[*-1] }
say lower-triangle-sum [
[ 1, 3, 7, 8, 10 ], [ 2, 4, 16, 14, 4 ], [ 3, 1, 9, 18, 11 ], [ 12, 14, 17, 18, 20 ], [ 7, 1, 3, 9, 5 ]
];</lang>
- Output:
69
REXX
version 1
<lang rexx>/* REXX */ ml ='1 3 7 8 10 2 4 16 14 4 3 1 9 18 11 12 14 17 18 20 7 1 3 9 5' Do i=1 To 5
Do j=1 To 5 Parse Var ml m.i.j ml End End
l= Do i=1 To 5
Do j=1 To 5 l=l right(m.i.j,2) End Say l l= End
sum=0 Do i=2 To 5
Do j=1 To i-1 sum=sum+m.i.j End End
Say 'Sum below main diagonal:' sum</lang>
1 3 7 8 10 2 4 16 14 4 3 1 9 18 11 12 14 17 18 20 7 1 3 9 5 Sum below main diagonal: 69
version 2
This REXX version makes no assumption about the size of the matrix, and it determines the maximum width of any
matrix element (instead of assuming a width).
<lang rexx>/*REXX pgm finds & shows the sum of elements below the main diagonal of a square matrix.*/
$= '1 3 7 8 10 2 4 16 14 4 3 1 9 18 11 12 14 17 18 20 7 1 3 9 5'; #= words($)
do siz=1 while siz*siz<#; end /*determine the size of the matrix. */
w= 0 /*W: the maximum width any any element*/
do j=1 for #; w= max(w,length(word($,j))) /*examine each element for its width. */ end /*j*/ /* [↑] this is aligning matrix elements*/
s= 0 /*initialize the sum [S] to zero. */
do r=1 for siz; _= left(, 12) /*_: contains a row of matrix elements*/ do c=1 for siz; parse var $ x $ /*get an element of the " " */ _= _ right(x, w) /*build a row of elements for display. */ if c<r then s=s + x /*add a "lower element" to the sum. */ end /*r*/ say _ /*display a row of the matrix to term. */ end /*c*/
say 'sum of elements below main diagonal is: ' s /*stick a fork in it, we're all done. */</lang>
- output when using the internal default input:
1 3 7 8 10 2 4 16 14 4 3 1 9 18 11 12 14 17 18 20 7 1 3 9 5 sum of elements below main diagonal is: 69
Ring
<lang ring> see "working..." + nl see "Sum of elements below main diagonal of matrix:" + nl diag = [[1,3,7,8,10],
[2,4,16,14,4], [3,1,9,18,11], [12,14,17,18,20], [7,1,3,9,5]]
lenDiag = len(diag) ind = lenDiag sumDiag = 0
for n=1 to lenDiag
for m=1 to lenDiag-ind sumDiag += diag[n][m] next ind--
next
see "" + sumDiag + nl see "done..." + nl </lang>
- Output:
working... Sum of elements below main diagonal of matrix: 69 done...
Wren
<lang ecmascript>var m = [
[ 1, 3, 7, 8, 10], [ 2, 4, 16, 14, 4], [ 3, 1, 9, 18, 11], [12, 14, 17, 18, 20], [ 7, 1, 3, 9, 5]
] if (m.count != m[0].count) Fiber.abort("Matrix must be square.") var sum = 0 for (i in 1...m.count) {
for (j in 0...i) { sum = sum + m[i][j] }
} System.print("Sum of elements below main diagonal is %(sum).")</lang>
- Output:
Sum of elements below main diagonal is 69.
XPL0
<lang XPL0>int Mat, X, Y, Sum; [Mat:= [[1,3,7,8,10],
[2,4,16,14,4], [3,1,9,18,11], [12,14,17,18,20], [7,1,3,9,5]];
Sum:= 0; for Y:= 0 to 4 do
for X:= 0 to 4 do if Y > X then Sum:= Sum + Mat(Y,X);
IntOut(0, Sum); ]</lang>
- Output:
69