Problem
Cosine similarity compares the direction of two vectors and ignores their length. Semantic search uses it to find texts with similar embeddings:
cos(a, b) = (a · b) / (|a| × |b|), where |a| = √(a₁² + a₂² + … + aₙ²)
The result is 1 for the same direction, 0 for perpendicular vectors and -1 for opposite directions. If either vector is all zeros, return 0.
Implement cosine_similarity(a, b).
Input
a, b: Two lists of numbers with the same length.
Output
Return the cosine similarity as a decimal number.
Constraints
1 ≤ length ≤ 1,000
-1,000 ≤ each value ≤ 1,000
Examples
Input:
a = [1.0, 0.0]
b = [0.0, 1.0]
Expected output:
expected = 0.0
Input:
std::vector<double> a = {1.0, 0.0};
std::vector<double> b = {0.0, 1.0};
Expected output:
double expected = 0.0;
Input:
double[] a = new double[] {1.0, 0.0};
double[] b = new double[] {0.0, 1.0};
Expected output:
double expected = 0.0;
Explanation
The dot product is 0, so the vectors are perpendicular and the similarity is 0.
Input:
a = [1.0, 2.0, 3.0]
b = [2.0, 4.0, 6.0]
Expected output:
expected = 1.0
Input:
std::vector<double> a = {1.0, 2.0, 3.0};
std::vector<double> b = {2.0, 4.0, 6.0};
Expected output:
double expected = 1.0;
Input:
double[] a = new double[] {1.0, 2.0, 3.0};
double[] b = new double[] {2.0, 4.0, 6.0};
Expected output:
double expected = 1.0;
Explanation
b is a times 2: same direction, so the similarity is 1 even though the lengths differ.
How to approach it
Try on your own first, then open one hint at a time.
Hint 1
The score depends on direction, so first compute the dot product and both vector lengths separately.
Hint 2
If either vector has zero magnitude, the similarity is defined as zero instead of dividing by zero.
Hint 3
Use the same index across both vectors for every term, and remember the denominator is the product of magnitudes.
Expected complexity
O(n) time, O(1) extra space
References
This challenge is adapted for CodeUtility. Follow the statement and constraints above.