From 2caa0f6eecab2c1edcf43f3b0436e7e0aa2f15c7 Mon Sep 17 00:00:00 2001 From: Gonzalo Diaz Date: Tue, 30 Jul 2024 23:36:28 -0400 Subject: [PATCH 1/3] [BUGFIX] [Hacker Rank] Interview Preparation Kit: Dictionaries and Hashmaps: Frequency Queries. * Fixed result. Fails due time out in big cases. * Basic test cases added. --- ...s => frequency_queries_bruteforce.test.ts} | 24 ++----- ...ies.ts => frequency_queries_bruteforce.ts} | 20 +++--- .../frequency_queries_testcases.json | 68 +++++++++++++++++++ 3 files changed, 82 insertions(+), 30 deletions(-) rename src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/{frequency_queries.test.ts => frequency_queries_bruteforce.test.ts} (61%) rename src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/{frequency_queries.ts => frequency_queries_bruteforce.ts} (75%) create mode 100644 src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_testcases.json diff --git a/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries.test.ts b/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_bruteforce.test.ts similarity index 61% rename from src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries.test.ts rename to src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_bruteforce.test.ts index b8cb7a10..89bb5deb 100644 --- a/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries.test.ts +++ b/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_bruteforce.test.ts @@ -1,30 +1,14 @@ import { describe, expect, it } from '@jest/globals'; import { logger as console } from '../../../logger'; -import { freqQuery } from './frequency_queries'; - -const TEST_CASES = [ - { - title: 'Sample Test Case 0', - input: [ - [1, 5], - [1, 6], - [3, 2], - [1, 10], - [1, 10], - [1, 6], - [2, 5], - [3, 2] - ], - expected: [0, 1] - } -]; +import { freqQuery } from './frequency_queries_bruteforce'; +import SMALL_TEST_CASES from './frequency_queries_testcases.json'; describe('frequency_queries', () => { it('freqQuery test cases', () => { - expect.assertions(1); + expect.assertions(4); - TEST_CASES.forEach((value) => { + SMALL_TEST_CASES.forEach((value) => { const answer = freqQuery(value.input); console.debug(`freqQuery(${value.input}) solution found: ${answer}`); diff --git a/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries.ts b/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_bruteforce.ts similarity index 75% rename from src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries.ts rename to src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_bruteforce.ts index 09b08488..513a7764 100644 --- a/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries.ts +++ b/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_bruteforce.ts @@ -12,6 +12,9 @@ export function freqQuery(queries: number[][]): number[] { const __DELETE__ = 2; const __SELECT__ = 3; + const __NOT_FOUND__ = 0; + const __FOUND__ = 1; + queries.forEach((query) => { const [operation, data] = query; @@ -24,18 +27,15 @@ export function freqQuery(queries: number[][]): number[] { case __DELETE__: data_map[data] = Math.max(0, current - 1); break; - case __SELECT__: - for (const [key, value] of Object.entries(data_map)) { - console.log(key, value); - if (value == data) { - result.push(1); - break; - } - } - if (result.length == 0) { - result.push(0); + case __SELECT__: { + const uniqueDatavalues = new Set(Object.values(data_map)); + if (uniqueDatavalues.has(data)) { + result.push(__FOUND__); + } else { + result.push(__NOT_FOUND__); } break; + } default: throw new Error('Invalid operation'); } diff --git a/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_testcases.json b/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_testcases.json new file mode 100644 index 00000000..658efdfb --- /dev/null +++ b/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_testcases.json @@ -0,0 +1,68 @@ +[ + { + "title": "Sample Test Case 0", + "input": [ + [1, 5], + [1, 6], + [3, 2], + [1, 10], + [1, 10], + [1, 6], + [2, 5], + [3, 2] + ], + "expected": [0, 1] + }, + { + "title": "Sample Test Case 1", + "input": [ + [3, 4], + [2, 1003], + [1, 16], + [3, 1] + ], + "expected": [0, 1] + }, + { + "title": "Sample Test Case 2", + "input": [ + [1, 3], + [2, 3], + [3, 2], + [1, 4], + [1, 5], + [1, 5], + [1, 4], + [3, 2], + [2, 4], + [3, 2] + ], + "expected": [0, 1, 1] + }, + { + "title": "Sample Test Case 3", + "input": [ + [1, 3], + [1, 38], + [2, 1], + [1, 16], + [2, 1], + [2, 2], + [1, 64], + [1, 84], + [3, 1], + [1, 100], + [1, 10], + [2, 2], + [2, 1], + [1, 67], + [2, 2], + [3, 1], + [1, 99], + [1, 32], + [1, 58], + [3, 2] + ], + "expected": [1, 1, 0] + } +] From 0ee698539278b4bcae640ebd535b4bc8a1f93450 Mon Sep 17 00:00:00 2001 From: Gonzalo Diaz Date: Tue, 30 Jul 2024 23:45:37 -0400 Subject: [PATCH 2/3] =?UTF-8?q?[REFACTOR]=20[Hacker=20Rank]=20Interview=20?= =?UTF-8?q?Preparation=20Kit:=20Dictionaries=20and=20Hashmaps:=20Frequency?= =?UTF-8?q?=20Queries.=20Solved=20=E2=9C=85.=20Solve=20all=20test=20cases.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frequency_queries_optimized.test.ts | 27 ++++++ .../frequency_queries_optimized.ts | 89 +++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_optimized.test.ts create mode 100644 src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_optimized.ts diff --git a/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_optimized.test.ts b/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_optimized.test.ts new file mode 100644 index 00000000..e792985f --- /dev/null +++ b/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_optimized.test.ts @@ -0,0 +1,27 @@ +import { describe, expect, it } from '@jest/globals'; +import { logger as console } from '../../../logger'; + +import { freqQuery } from './frequency_queries_optimized'; +import TEST_CASES from './frequency_queries_testcases.json'; + +describe('frequency_queries', () => { + it('freqQuery test cases', () => { + expect.assertions(4); + + TEST_CASES.forEach((value) => { + const answer = freqQuery(value.input); + + console.debug(`freqQuery(${value.input}) solution found: ${answer}`); + + expect(answer).toStrictEqual(value.expected); + }); + }); + + it('freqQuery border case', () => { + expect.assertions(1); + + expect(() => { + freqQuery([[4, 1]]); + }).toThrow('Invalid operation'); + }); +}); diff --git a/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_optimized.ts b/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_optimized.ts new file mode 100644 index 00000000..2d250c5d --- /dev/null +++ b/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_optimized.ts @@ -0,0 +1,89 @@ +/** + * @link Problem definition [[docs/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency-queries.md]] + */ + +export function updateFrequency( + frequencyMap: Record, + data: number, + currentFreq: number, + newFreq: number +): Record { + const freqMap = frequencyMap; + + if (newFreq > 0) { + if (freqMap?.[newFreq]) { + freqMap[newFreq].push(data); + } else { + freqMap[newFreq] = [data]; + } + } + + if (freqMap?.[currentFreq]) { + freqMap[currentFreq] = freqMap[currentFreq].filter( + (f: number) => f !== data + ); + + if (freqMap[currentFreq].length === 0) { + delete freqMap?.[currentFreq]; + } + } + + return freqMap; +} + +export function freqQuery(queries: number[][]): number[] { + const result: number[] = []; + const dataMap: Record = {}; + const freqMap: Record = {}; + + const __INITIAL__ = 0; + const __INSERT__ = 1; + const __DELETE__ = 2; + const __SELECT__ = 3; + + const __NOT_FOUND__ = 0; + const __FOUND__ = 1; + + queries.forEach((query) => { + const [operation, data] = query; + + const currentFreq = dataMap?.[data] ?? __INITIAL__; + let newFreq = currentFreq + 1; + + switch (operation) { + case __INSERT__: + // map of values + dataMap[data] = currentFreq + 1; + + // map of frequencies + newFreq = currentFreq + 1; + break; + case __DELETE__: + // map of values + dataMap[data] = Math.max(0, currentFreq - 1); + + // map of frequencies + newFreq = currentFreq - 1; + + break; + case __SELECT__: { + if (freqMap?.[data]) { + result.push(__FOUND__); + } else { + result.push(__NOT_FOUND__); + } + break; + } + default: + throw new Error('Invalid operation'); + } + + if (operation === __INSERT__ || operation === __DELETE__) { + updateFrequency(freqMap, data, currentFreq, newFreq); + } + }); + + return result; +} + +export default { freqQuery }; From 610f6a79afac0a2484f08e4eadb5fab05fc351d5 Mon Sep 17 00:00:00 2001 From: Gonzalo Diaz Date: Tue, 30 Jul 2024 23:49:38 -0400 Subject: [PATCH 3/3] [REFACTOR] [Hacker Rank] Interview Preparation Kit: Dictionaries and Hashmaps: Frequency Queries. New solution notes document added. --- .../frequency-queries-solution-notes.md | 27 +++++++++++++++++++ .../frequency_queries_bruteforce.ts | 1 + .../frequency_queries_optimized.ts | 1 + 3 files changed, 29 insertions(+) create mode 100644 docs/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency-queries-solution-notes.md diff --git a/docs/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency-queries-solution-notes.md b/docs/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency-queries-solution-notes.md new file mode 100644 index 00000000..bc9d88fd --- /dev/null +++ b/docs/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency-queries-solution-notes.md @@ -0,0 +1,27 @@ +# [Dictionaries and Hashmaps: Frequency Queries](https://www.hackerrank.com/challenges/frequency-queries) + +- Difficulty: `#medium` +- Category: `#ProblemSolvingIntermediate` `#DictionariesAndHashmaps` + +## First solution + +The first solution is based on the idea of ​​storing the values +​​of insert and delete operations in a dictionary. + +For the "select" operation, a search loop is made to find the expected frequency, +which in the best case is cut off when the value is found, +but in the worst case it goes through the entire dictionary. + +## Optimized solution + +The optimized solution tries to reduce the worst case problem above, +reducing the select operation to direct access to the expected frequency. + +To achieve this, it is necessary to maintain an "inverted" dictionary +where the frequency values ​​are the keys and the values ​​of each element +are stored in a list of values ​​that have the same frequency. + +To maintain this structure, any operation that alters the data (insert, delete), +must update "in which frequency group" the element will be. + +This solution transfers the cost of the search to the data update operations. diff --git a/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_bruteforce.ts b/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_bruteforce.ts index 513a7764..05b67778 100644 --- a/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_bruteforce.ts +++ b/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_bruteforce.ts @@ -1,5 +1,6 @@ /** * @link Problem definition [[docs/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency-queries.md]] + * @see Solution Notes: [[docs/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency-queries-solution-notes.md]] */ // Complete the freqQuery function below. diff --git a/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_optimized.ts b/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_optimized.ts index 2d250c5d..13a86325 100644 --- a/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_optimized.ts +++ b/src/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency_queries_optimized.ts @@ -1,5 +1,6 @@ /** * @link Problem definition [[docs/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency-queries.md]] + * @see Solution Notes: [[docs/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/frequency-queries-solution-notes.md]] */ export function updateFrequency(