Bookshop Blurb Match

Easylinear algebraAlso known as Cosine Similarity

A second-hand bookshop wants a "you might also like" shelf on its website. An embedding model has turned every book's back-cover blurb into a list of numbers. Blurbs about similar things point in similar directions, even if one blurb is long and gushing and the other is short and dry.

To compare two books, the shop wants a score that only cares about direction: 1 for the same direction, 0 for unrelated, -1 for opposite. Retrieval systems for language models rank documents with the same score.

Your task

Write blurbSimilarity(a, b). Return the cosine similarity of the two vectors: their dot product divided by the product of their lengths.

  • Dot product: a[0]·b[0] + a[1]·b[1] + …
  • Length of a: √(a[0]² + a[1]² + …)

If either vector is all zeros it has no direction, so return 0.

blurbSimilarity(a: float[], b: float[]) → float Numbers are accepted within 1e-6.

Examples

Example 1
Input
a = [1, 2, 0]
b = [2, 4, 0]
Output
1
Why

The dot product is 1·2 + 2·4 + 0·0 = 10. The lengths are √5 and √20, and √5 · √20 = √100 = 10. So the score is 10 / 10 = 1: the second vector is just the first one doubled, same direction.

Example 2
Input
a = [3, 0]
b = [0, 5]
Output
0
Why

The dot product is 3·0 + 0·5 = 0, so the score is 0. One book is all about the first feature, the other all about the second: unrelated.

Example 3
Input
a = [1, 1]
b = [-2, -2]
Output
-1
Why

The dot product is -4. The lengths are √2 and √8, whose product is 4. Score -4 / 4 = -1: exactly opposite directions.

Constraints

  • 1 ≤ a.length = b.length ≤ 1,000
  • -1,000 ≤ a[i], b[i] ≤ 1,000
  • Answers within 0.000001 of the expected value are accepted.
Start with brute force

A natural first version normalises both vectors first: compute each length, build two new vectors divided by their lengths, then take the dot product of those. It is correct, but it makes three passes and two extra lists.

The tempting wrong shortcut is the raw dot product. It ranks long, wordy blurbs above short ones about the same topic, because longer vectors give bigger dot products. You get the same answer as the normalised version in one pass by keeping three sums at once.

Hints

0 of 4 shown

Walkthrough and solution

Unlocks when you pass every test. Stuck for a while? Looking is fine too, as long as you then close it and write the code yourself.

Ctrl+Enter runs

Run your code to see results here. Run checks the examples. Submit checks every test, including hidden edge cases.

Write code