Sum of elements below main diagonal of matrix

You are encouraged to solve this task according to the task description, using any language you may know.
- 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]]
11l
<lang 11l>F sumBelowDiagonal(m)
V result = 0 L(i) 1 .< m.len L(j) 0 .< i result += m[i][j] R result
V 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]]
print(sumBelowDiagonal(m))</lang>
- Output:
69
Action!
<lang Action!>PROC PrintMatrix(INT ARRAY m BYTE size)
BYTE x,y INT v
FOR y=0 TO size-1 DO FOR x=0 TO size-1 DO v=m(x+y*size) IF v<10 THEN Put(32) FI PrintB(v) Put(32) OD PutE() OD
RETURN
INT FUNC SumBelowDiagonal(INT ARRAY m BYTE size)
BYTE x,y INT sum
sum=0 FOR y=1 TO size-1 DO FOR x=0 TO y-1 DO sum==+m(x+y*size) OD OD
RETURN (sum)
PROC Main()
INT sum INT ARRAY 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]
PrintE("Matrix") PrintMatrix(m,5) PutE() sum=SumBelowDiagonal(m,5) PrintF("Sum below diagonal is %I",sum)
RETURN</lang>
- Output:
Screenshot from Atari 8-bit computer
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 Sum below diagonal is 69
Ada
<lang Ada>with Ada.Text_Io; with Ada.Numerics.Generic_Real_Arrays;
procedure Sum_Below_Diagonals is
type Real is new Float;
package Real_Arrays is new Ada.Numerics.Generic_Real_Arrays (Real);
function Sum_Below_Diagonal (M : Real_Arrays.Real_Matrix) return Real with Pre => M'Length (1) = M'Length (2) is Sum : Real := 0.0; begin for Row in 0 .. M'Length (1) - 1 loop for Col in 0 .. Row - 1 loop Sum := Sum + M (M'First (1) + Row, M'First (2) + Col); end loop; end loop; return Sum; end Sum_Below_Diagonal;
M : constant Real_Arrays.Real_Matrix := (( 1.0, 3.0, 7.0, 8.0, 10.0), ( 2.0, 4.0, 16.0, 14.0, 4.0), ( 3.0, 1.0, 9.0, 18.0, 11.0), (12.0, 14.0, 17.0, 18.0, 20.0), ( 7.0, 1.0, 3.0, 9.0, 5.0)); Sum : constant Real := Sum_Below_Diagonal (M);
package Real_Io is new Ada.Text_Io.Float_Io (Real); use Ada.Text_Io, Real_Io;
begin
Put ("Sum below diagonal: "); Put (Sum, Exp => 0, Aft => 1); New_Line;
end Sum_Below_Diagonals;</lang>
- Output:
Sum below diagonal: 69.0
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
AutoHotkey
<lang AutoHotkey>matrx :=[[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]] sumA := sumB := sumD := sumAll := 0 for r, obj in matrx for c, val in obj sumAll += val ,sumA += r<c ? val : 0 ,sumB += r>c ? val : 0 ,sumD += r=c ? val : 0
MsgBox % result := "sum above diagonal = " sumA . "`nsum below diagonal = " sumB . "`nsum on diagonal = " sumD . "`nsum all = " sumAll</lang>
- Output:
sum above diagonal = 111 sum below diagonal = 69 sum on diagonal = 37 sum all = 217
AWK
<lang AWK>
- syntax: GAWK -f SUM_OF_ELEMENTS_BELOW_MAIN_DIAGONAL_OF_MATRIX.AWK
BEGIN {
arr1[++n] = "1,3,7,8,10" arr1[++n] = "2,4,16,14,4" arr1[++n] = "3,1,9,18,11" arr1[++n] = "12,14,17,18,20" arr1[++n] = "7,1,3,9,5" for (i=1; i<=n; i++) { x = split(arr1[i],arr2,",") if (x != n) { printf("error: row %d has %d elements; S/B %d\n",i,x,n) errors++ continue } for (j=1; j<i; j++) { # below main diagonal sum_b += arr2[j] cnt_b++ } for (j=i+1; j<=n; j++) { # above main diagonal sum_a += arr2[j] cnt_a++ } for (j=1; j<=i; j++) { # on main diagonal if (j == i) { sum_o += arr2[j] cnt_o++ } } } if (errors > 0) { exit(1) } printf("%5g Sum of the %d elements below main diagonal\n",sum_b,cnt_b) printf("%5g Sum of the %d elements above main diagonal\n",sum_a,cnt_a) printf("%5g Sum of the %d elements on main diagonal\n",sum_o,cnt_o) printf("%5g Sum of the %d elements in the matrix\n",sum_b+sum_a+sum_o,cnt_b+cnt_a+cnt_o) exit(0)
} </lang>
- Output:
69 Sum of the 10 elements below main diagonal 111 Sum of the 10 elements above main diagonal 37 Sum of the 5 elements on main diagonal 217 Sum of the 25 elements in the matrix
BASIC
BASIC256
<lang BASIC256>arraybase 1 dim 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}} ind = diag[?,] sumDiag = 0
for x = 1 to diag[?,] for y = 1 to diag[,?]-ind sumDiag += diag[x, y] next y ind -= 1 next x
print "Sum of elements below main diagonal of matrix is "; sumDiag end</lang>
FreeBASIC
<lang freebasic>Dim As Integer diag(1 To 5, 1 To 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}}
Dim As Integer lenDiag = Ubound(diag), ind = lenDiag Dim As Integer sumDiag = 0, x, y
For x = 1 To lenDiag
For y = 1 To lenDiag-ind sumDiag += diag(x, y) Next y ind -= 1
Next x
Print "Sum of elements below main diagonal of matrix is"; sumDiag Sleep</lang>
- Output:
Sum of elements below main diagonal of matrix is 69
GW-BASIC
<lang gwbasic>10 DATA 1,3,7,8,10 20 DATA 2,4,16,14,4 30 DATA 3,1,9,18,11 40 DATA 12,14,17,18,20 50 DATA 7,1,3,9,5 60 FOR ROW = 1 TO 5 70 FOR COL = 1 TO 5 80 READ N 90 IF ROW > COL THEN SUM = SUM + N 100 NEXT COL 110 NEXT ROW 120 PRINT SUM</lang>
- Output:
69
QBasic
<lang qbasic>DEFINT A-Z
DIM diag(1 TO 5, 1 TO 5) lenDiag = UBOUND(diag) ind = lenDiag sumDiag = 0
FOR x = 1 TO lenDiag
FOR y = 1 TO lenDiag READ diag(x, y) NEXT y
NEXT x
FOR x = 1 TO lenDiag
FOR y = 1 TO lenDiag - ind sumDiag = sumDiag + diag(x, y) NEXT y ind = ind - 1
NEXT x
PRINT "Sum of elements below main diagonal of matrix is"; sumDiag END
DATA 1, 3, 7, 8,10 DATA 2, 4,16,14, 4 DATA 3, 1, 9,18,11 DATA 12,14,17,18,20 DATA 7, 1, 3, 9, 5</lang>
True BASIC
<lang qbasic>DIM diag(5, 5) LET lenDiag = UBOUND(diag, 1) LET ind = lenDiag LET sumDiag = 0
DATA 1, 3, 7, 8,10 DATA 2, 4,16,14, 4 DATA 3, 1, 9,18,11 DATA 12,14,17,18,20 DATA 7, 1, 3, 9, 5
FOR x = 1 TO lenDiag
FOR y = 1 TO lenDiag READ diag(x, y) NEXT y
NEXT x
FOR x = 1 TO lenDiag
FOR y = 1 TO lenDiag - ind LET sumDiag = sumDiag + diag(x, y) NEXT y LET ind = ind - 1
NEXT x
PRINT "Sum of elements below main diagonal of matrix:"; sumDiag END</lang>
Yabasic
<lang yabasic>dim diag(5, 5) lenDiag = arraysize(diag(),1) ind = lenDiag sumDiag = 0
for x = 1 to lenDiag
for y = 1 to lenDiag read diag(x, y) next y
next x
for x = 1 to lenDiag
for y = 1 to lenDiag-ind sumDiag = sumDiag + diag(x, y) next y ind = ind - 1
next x
print "Sum of elements below main diagonal of matrix: ", sumDiag end
data 1, 3, 7, 8,10 data 2, 4,16,14, 4 data 3, 1, 9,18,11 data 12,14,17,18,20 data 7, 1, 3, 9, 5</lang>
BQN
<lang bqn>SumBelowDiagonal ← +´∘⥊⊢×(>⌜´)∘(↕¨≢)
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⟩⟩
SumBelowDiagonal matrix</lang>
- Output:
69
C
Interactive program which reads the matrix from a file : <lang C>
- include<stdlib.h>
- include<stdio.h>
typedef struct{ int rows,cols; int** dataSet; }matrix;
matrix readMatrix(char* dataFile){ FILE* fp = fopen(dataFile,"r"); matrix rosetta; int i,j;
fscanf(fp,"%d%d",&rosetta.rows,&rosetta.cols);
rosetta.dataSet = (int**)malloc(rosetta.rows*sizeof(int*));
for(i=0;i<rosetta.rows;i++){ rosetta.dataSet[i] = (int*)malloc(rosetta.cols*sizeof(int)); for(j=0;j<rosetta.cols;j++) fscanf(fp,"%d",&rosetta.dataSet[i][j]); }
fclose(fp); return rosetta; }
void printMatrix(matrix rosetta){ int i,j;
for(i=0;i<rosetta.rows;i++){ printf("\n"); for(j=0;j<rosetta.cols;j++) printf("%3d",rosetta.dataSet[i][j]); } }
int findSum(matrix rosetta){ int i,j,sum = 0;
for(i=1;i<rosetta.rows;i++){ for(j=0;j<i;j++){ sum += rosetta.dataSet[i][j]; } }
return sum; }
int main(int argC,char* argV[]) { if(argC!=2) return printf("Usage : %s <filename>",argV[0]);
matrix data = readMatrix(argV[1]);
printf("\n\nMatrix is : \n\n"); printMatrix(data);
printf("\n\nSum below main diagonal : %d",findSum(data));
return 0; } </lang>
Input Data file, first row specifies rows and columns :
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
And output follows :
- Output:
C:\My Projects\BGI>a.exe rosettaData.txt Matrix is : 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
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 < 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
Excel
LAMBDA
Binding the name matrixTriangle to the following lambda expression in the Name Manager of the Excel WorkBook:
(See LAMBDA: The ultimate Excel worksheet function)
<lang lisp>=LAMBDA(isUpper,
LAMBDA(matrix, LET( nCols, COLUMNS(matrix), nRows, ROWS(matrix), ixs, SEQUENCE(nRows, nCols, 0, 1), x, MOD(ixs, nCols), y, QUOTIENT(ixs, nRows), IF(nCols=nRows, LET( p, LAMBDA(x, y, IF(isUpper, x > y, x < y) ), IF(p(x, y), INDEX(matrix, 1 + y, 1 + x), 0 ) ), "Matrix not square" ) ) )
)</lang>
- Output:
The formulae in cells B2 and B9 define and populate the matrices which fill the ranges B2:F6 and B9:F12
(The formula in B9 differs from that in B2 only in the first (Boolean) argument)
fx | =matrixTriangle(FALSE)(B16#) | ||||||
---|---|---|---|---|---|---|---|
A | B | C | D | E | F | ||
1 | |||||||
2 | Lower triangle: | 0 | 0 | 0 | 0 | 0 | |
3 | 2 | 0 | 0 | 0 | 0 | ||
4 | 3 | 1 | 0 | 0 | 0 | ||
5 | 12 | 14 | 17 | 0 | 0 | ||
6 | 7 | 1 | 3 | 9 | 0 | ||
7 | Sum | 69 | |||||
8 | |||||||
9 | Upper triangle: | 0 | 3 | 7 | 8 | 10 | |
10 | 0 | 0 | 16 | 14 | 4 | ||
11 | 0 | 0 | 0 | 18 | 11 | ||
12 | 0 | 0 | 0 | 0 | 20 | ||
13 | 0 | 0 | 0 | 0 | 0 | ||
14 | Sum | 111 | |||||
15 | |||||||
16 | Full matrix | 1 | 3 | 7 | 8 | 10 | |
17 | 2 | 4 | 16 | 14 | 4 | ||
18 | 3 | 1 | 9 | 18 | 11 | ||
19 | 12 | 14 | 17 | 18 | 20 | ||
20 | 7 | 1 | 3 | 9 | 5 |
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 both upper and lower triangle of a square matrix:
<lang haskell>----------------- UPPER OR LOWER TRIANGLE ----------------
matrixTriangle :: Bool -> a -> Either String a matrixTriangle upper matrix
| upper = go drop id | otherwise = go take pred where go f g | isSquare matrix = (Right . snd) $ foldr (\xs (n, rows) -> (pred n, f n xs : rows)) (g $ length matrix, []) matrix | otherwise = Left "Defined only for a square matrix."
isSquare :: a -> Bool isSquare rows = all ((n ==) . length) rows
where n = length rows
TEST -------------------------
main :: IO () main =
mapM_ putStrLn $ zipWith ( flip ((<>) . (<> " triangle:\n\t")) . either id (show . sum . concat) ) ( [matrixTriangle] <*> [False, True] <*> [ [ [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] ] ] ) ["Lower", "Upper"]</lang>
- Output:
Lower triangle: 69 Upper triangle: 111
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
jq
Works with gojq, the Go implementation of jq <lang jq> def add(s): reduce s as $x (null; . + $x);
- input: a square matrix
def sum_below_diagonal:
add( range(0;length) as $i | .[$i][:$i][] ) ;
</lang> The task: <lang jq> [[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
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
Mathematica/Wolfram Language
<lang Mathematica>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}}; Total[LowerTriangularize[m, -1], 2]</lang>
- Output:
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
Perl
<lang perl>#!/usr/bin/perl
use strict; use warnings; use List::Util qw( sum );
my $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]];
my $lowersum = sum map @{ $matrix->[$_] }[0 .. $_ - 1], 1 .. $#$matrix; print "lower sum = $lowersum\n";</lang>
- Output:
lower sum = 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 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
R
R has lots of native matrix support, so this is trivial. <lang R>mat <- rbind(c(1,3,7,8,10),
c(2,4,16,14,4), c(3,1,9,18,11), c(12,14,17,18,20), c(7,1,3,9,5))
print(sum(mat[lower.tri(mat)]))</lang>
- Output:
[1] 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 that might not properly show the true value of an element).
<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 #; parse var $ @..j $ /*obtain a number of the array (list). */ w= max(w, length(@..j)) /*examine each element for its width. */ end /*j*/ /* [↑] this is aligning matrix elements*/
s= 0; z= 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; z= z + 1; @.z= @..z /*get a number of the " " */ _= _ right(@.z, w) /*build a row of elements for display. */ if c<r then s= s + @.z /*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...
Ruby
<lang ruby>arr = [
[ 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]
] p arr.each_with_index.sum {|row, x| row[0, x].sum} </lang>
- Output:
69
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