You are given 2 arrays of same size,
@a
and@b
.Write a script to implement
Dot Product
.
@a = (1, 2, 3);
@b = (4, 5, 6);
$dot_product = (1 * 4) + (2 * 5) + (3 * 6) => 4 + 10 + 18 => 32
There is nothing difficult about this challenge. We just have to pairwise multiply the coordinates, and sum them, as the dot product of two vectors is defined as:
\[ v_a \bullet v_b = \sum_{i=1}^n a_i \cdot b_i, \:\text{where } v_a = (a_1, \ldots, a_n) \:\text{and } v_b = (b_1, \ldots, b_n) \]
We will be assuming we have two lines of input, each line having the coordinates of one vector. The coordinates will be separated by a space, and we will assume both vectors have the same number of coordinates.
For some languages, we will assume the coordinates are integers.
Math::Matrix
has many useful operations on matrices (and vectors
are just one-dimensional matrices), including
dotproduct
, which, as
the name suggests, returns the dot product of two vectors.
Which leads to the following simple program:
use Math::Matrix;
say Math::Matrix:: -> new ([split ' ' => scalar <>]) -> dot_product
(Math::Matrix:: -> new ([split ' ' => scalar <>]));
Find the full program on GitHub.
Here we define a recursive function to calculate the dot product:
(define (dotproduct a b)
(if (null? a) 0
(+ (* (car a) (car b))
(dotproduct (cdr a) (cdr b)))))
This defines a method dotproduct
which takes arguments a
and b
,
which we assume are lists of equal length. Lists in Scheme are
implemented as (nested)
pairs.
car
gets the first element of a pair — so the first element of a list.
cdr
gets the second element of a pair, hence, all but the first element
of a list. So, dotproduct
first checks the length of this: if the list
is empty (null?
), we return 0
. Else, we multiply the first elements
of the input lists, and add this to the recursive call to dotproduct
with the remainders (cdr
) of the input lists.
We read input using read-line
, which we split on spaces (string-split
),
and convert the results to numbers using string->number
. This gives
the following code:
(display (dotproduct (map string->number (string-split (read-line) #\ ))
(map string->number (string-split (read-line) #\ ))))
(newline)
Find the full program on GitHub.
Here, we use simple iteration over lists to calculate the wanted result. First, we use list comprehension to read the input, and turn it in into lists of integers:
a = [int (x) for x in input () . split (" ")]
b = [int (x) for x in input () . split (" ")]
Now it's a simple loop:
sum = 0
for i in range (len (a)):
sum = sum + a [i] * b [i]
print (sum)
Find the full program on GitHub.
R actually has an operator to calculate the dot product (%*%
).
readLines
read input, strsplit
splits a string, while
as.numeric
transforms strings into numbers. This gives us the
following compact program:
stdin <- file ('stdin', 'r')
cat (as.numeric (strsplit (readLines (stdin, n = 1), " ") [[1]]) %*%
as.numeric (strsplit (readLines (stdin, n = 1), " ") [[1]]), "\n")
Find the full program on GitHub.
In our Pascal solution, we first read all the integers from the input, putting them all in a single array:
var
n, size, j, half, sum: integer;
numbers: array of integer;
begin
size := 0;
while not eof do begin
read (n);
inc (size);
setlength (numbers, size);
numbers [size - 1] := n;
end;
We then calculate the dot product by treating the first half of the array as the first vector, and the second half of the array as the second vector:
sum := 0;
half := (size - 1) div 2;
for j := 0 to half do begin
sum := sum + numbers [j] * numbers [half + j];
end;
writeln (sum);
end.
Find the full program on GitHub.
We also have implementations in:
AWK, Bash, bc, C, Go, Java, Lua, Node.js, Ruby, and Tcl