From 69fa96b187ea061056273cdea7c5e26cf46e656f Mon Sep 17 00:00:00 2001 From: Adrian Mejia Date: Mon, 21 Sep 2020 20:53:16 -0400 Subject: [PATCH] chore: new exercise --- jest-all.config.js | 4 ++++ lab/exercises/10-mixed/document-distance.js | 23 +++++++++++++++++++ .../10-mixed/document-distance.spec.js | 20 ++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 jest-all.config.js create mode 100644 lab/exercises/10-mixed/document-distance.js create mode 100644 lab/exercises/10-mixed/document-distance.spec.js diff --git a/jest-all.config.js b/jest-all.config.js new file mode 100644 index 00000000..d7ad87ae --- /dev/null +++ b/jest-all.config.js @@ -0,0 +1,4 @@ +module.exports = { + name: 'dsa.js', + // testPathIgnorePatterns: ['/node_modules/', '/dist/', '/lab/', '/benchmarks/', '/coverage/'], +}; diff --git a/lab/exercises/10-mixed/document-distance.js b/lab/exercises/10-mixed/document-distance.js new file mode 100644 index 00000000..4c0ca542 --- /dev/null +++ b/lab/exercises/10-mixed/document-distance.js @@ -0,0 +1,23 @@ + +// npx jest lab/exercises/10-mixed/document-distance.spec.js --watch -c 'jest-all.config.js' + +/** + * Find the distance between two documents. + * + * Convert files into vectors of words where the value is the frequency. + * Calculate the angle of the two vectors: cos α = v1 · v2 / |v1| * |v2| + * @param {string} file1 - String of words separated by whitespace + * @param {string} file2 - String of words separated by whitespace + */ +function documentDistance(file1, file2) { + // 0. slip words + // 1. calculate freq of each word per file + const byCounter = (map, w) => map.set(w, 1 + (map.get(w) || 0)); + const f1 = file1.split(' ').reduce(byCounter, new Map()); + const f2 = file2.split(' ').reduce(byCounter, new Map()); + // 2. multiply each occurence and divide it + const dotProd = (m1, m2) => [...new Set([...m1.keys(), ...m2.keys()])].reduce((sum, w) => sum + (m1.get(w) || 0) * (m2.get(w) || 0), 0); + return Math.acos(dotProd(f1, f2) / Math.sqrt(dotProd(f1, f1) * dotProd(f2, f2))); +} + +module.exports = { documentDistance }; diff --git a/lab/exercises/10-mixed/document-distance.spec.js b/lab/exercises/10-mixed/document-distance.spec.js new file mode 100644 index 00000000..67adfb70 --- /dev/null +++ b/lab/exercises/10-mixed/document-distance.spec.js @@ -0,0 +1,20 @@ +const { documentDistance } = require('./document-distance'); + +describe('documentDistance', () => { + it('should work with different files', () => { + const file1 = 'This is a cat.'; + const file2 = 'This is a dog.'; + expect(documentDistance(file1, file2)).toBeCloseTo(0.722); + }); + + it('should work with different files', () => { + const file1 = 'This is a cat.'; + const file2 = 'Occaecat irure enim sint cupidatat id cillum cupidatat ipsum officia ea reprehenderit eiusmod voluptate. Est in laboris esse anim tempor sit in labore eiusmod consectetur aliqua. Quis nulla sunt incididunt magna velit in reprehenderit officia ut esse. Duis proident aute sint laborum consectetur eu reprehenderit amet et esse esse deserunt.'; + expect(documentDistance(file1, file2)).toBeCloseTo(1.57); + }); + + it('should work with equal files', () => { + const file1 = 'This is a cat.'; + expect(documentDistance(file1, file1)).toEqual(0); + }); +});