From 88fa4eaeb8f8f6f5baed469a880db291928f1e14 Mon Sep 17 00:00:00 2001 From: Gonzalo Diaz Date: Mon, 5 Aug 2024 16:18:29 -0400 Subject: [PATCH] =?UTF-8?q?[Hacker=20Rank]=20Interview=20Preparation=20Kit?= =?UTF-8?q?:=20Miscellaneous:=20Friend=20Circle=20Queries.=20Solved=20?= =?UTF-8?q?=E2=9C=85.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../miscellaneous/friend-circle-queries.md | 163 ++++++++++++++++++ .../friend_circle_queries.test.ts | 19 ++ .../friend_circle_queries.testcases.json | 34 ++++ .../miscellaneous/friend_circle_queries.ts | 73 ++++++++ 4 files changed, 289 insertions(+) create mode 100644 docs/hackerrank/interview_preparation_kit/miscellaneous/friend-circle-queries.md create mode 100644 src/hackerrank/interview_preparation_kit/miscellaneous/friend_circle_queries.test.ts create mode 100644 src/hackerrank/interview_preparation_kit/miscellaneous/friend_circle_queries.testcases.json create mode 100644 src/hackerrank/interview_preparation_kit/miscellaneous/friend_circle_queries.ts diff --git a/docs/hackerrank/interview_preparation_kit/miscellaneous/friend-circle-queries.md b/docs/hackerrank/interview_preparation_kit/miscellaneous/friend-circle-queries.md new file mode 100644 index 00000000..009b1a25 --- /dev/null +++ b/docs/hackerrank/interview_preparation_kit/miscellaneous/friend-circle-queries.md @@ -0,0 +1,163 @@ +# [Miscellaneous: Friend Circle Queries](https://www.hackerrank.com/challenges/friend-circle-queries) + +- Difficulty: `#medium` +- Category: `#Miscellaneous` + +The population of HackerWorld is $ 10^9 $. +Initially, none of the people are friends with each other. +In order to start a friendship, two persons `a` and `b` have to shake hands, +where $ 1 \leq a, b \leq 10^9 $. +The friendship relation is transitive, +that is if `a` and `b` shake hands with each other, +`a` and friends of `b` become friends with `b` and friends of `b`. + +You will be given `q` queries. After each query, +you need to report the size of the largest +friend circle (the largest group of friends) formed after considering that query. + +For example, your list of queries is: + +```text +1 2 +3 4 +2 3 +``` + +First, `1` and `2` shake hands, forming a circle of `2`. +Next, `3` and `4` do the same. Now there are two groups of `2` friends. +When `2` and `3` become friends in the next query, +both groups of friends are added together to make a circle of `4` friends. +We would print + +```text +2 +2 +4 +``` + +## Function Description + +Complete the function maxCircle in the editor below. +It must return an array of integers representing +the size of the maximum circle of friends after each query. + +maxCircle has the following parameter(s): + +- `queries`: an array of integer arrays, +each with two elements indicating a new friendship + +## Input Format + +The first line contains an integer, `q`, the number of queries to process. +Each of the next `q` lines consists of two space-separated integers +denoting the 2-D array `queries`. + +## Constraints + +- $ 1 \leq q \leq 10^5 $ +- $ 1 + \leq + queries[i][0],queries[i][1] + \leq 10^9 +$ for +$ 0 \leq i < q $ +- $ queries[i][0] \not = queries[i][1] $ + +## Output Format + +Return an integer array of size `q`, +whose value at index is the size of +largest group present after processing the $ i^{th}$ query. + +## Sample Input 0 + +```text +2 +1 2 +1 3 +``` + +## Sample Output 0 + +```text +2 +3 +``` + +## Explanation 0 + +In the first query, `1` and `2` shake hands. +So, the size of largest group of friends is `2` (as no other friendships exist). +After the second query, `1`, `2` and `3` all become friends, +as `1` shakes hand with `3`, `2` also become friends with `3` +as he was already a friend of `1`. + +## Sample Input 1 + +```text +4 +1000000000 23 +11 3778 +7 47 +11 1000000000 +``` + +## Sample Output 1 + +```text +2 +2 +2 +4 +``` + +## Explanation 1 + +After first query, person `1000000000` and person `23` become friends. +So, the largest group size is `2`. + +After the second query, person `11` and person `3778` become friends. +So, the largest group size is still . + +After the third query, person `7` and person `47` become friends. +Answer is still `2`. + +After the last query, person `11` and person `1000000000` become friends, +which means `23`, `11`, `1000000000` and `3778` all become friends. +Hence, the answer now increased to `4`. + +## Sample Input 2 + +```text +6 +1 2 +3 4 +1 3 +5 7 +5 6 +7 4 +``` + +## Sample Output 2 + +```text +2 +2 +4 +4 +4 +7 +``` + +## Explanation 2 + +Friend circles after each iteration: + +```text +1 [1,2] +2 [1,2],[3,4] +3 [1,2,3,4] +4 [1,2,3,4],[5,7] +5 [1,2,3,4],[5,7,6] +6 [1,2,3,4,5,6,7] +``` diff --git a/src/hackerrank/interview_preparation_kit/miscellaneous/friend_circle_queries.test.ts b/src/hackerrank/interview_preparation_kit/miscellaneous/friend_circle_queries.test.ts new file mode 100644 index 00000000..99989151 --- /dev/null +++ b/src/hackerrank/interview_preparation_kit/miscellaneous/friend_circle_queries.test.ts @@ -0,0 +1,19 @@ +import { describe, expect, it } from '@jest/globals'; +import { logger as console } from '../../../logger'; + +import { maxCircle } from './friend_circle_queries'; +import TEST_CASES from './friend_circle_queries.testcases.json'; + +describe('friend_circle_queries', () => { + it('maxCircle test cases', () => { + expect.assertions(4); + + TEST_CASES.forEach((test) => { + const answer = maxCircle(test.arr); + + console.debug(`luckBalance(${test.arr}) solution found: ${answer}`); + + expect(answer).toStrictEqual(test.expected); + }); + }); +}); diff --git a/src/hackerrank/interview_preparation_kit/miscellaneous/friend_circle_queries.testcases.json b/src/hackerrank/interview_preparation_kit/miscellaneous/friend_circle_queries.testcases.json new file mode 100644 index 00000000..2107217d --- /dev/null +++ b/src/hackerrank/interview_preparation_kit/miscellaneous/friend_circle_queries.testcases.json @@ -0,0 +1,34 @@ +[ + { + "title": "Sample Test case 0", + "arr": [[1, 2], [1, 3]], + "expected": [2, 3] + }, + { + "title": "Sample Test case 0", + "arr": [[1, 2], [1, 3], [1, 2], [1, 3]], + "expected": [2, 3, 3, 3] + }, + { + "title": "Sample Test case 1", + "arr": [ + [1000000000, 23], + [11, 3778], + [7, 47], + [11, 1000000000] + ], + "expected": [2, 2, 2, 4] + }, + { + "title": "Sample Test case 2", + "arr": [ + [1, 2], + [3, 4], + [1, 3], + [5, 7], + [5, 6], + [7, 4] + ], + "expected": [2, 2, 4, 4, 4, 7] + } +] diff --git a/src/hackerrank/interview_preparation_kit/miscellaneous/friend_circle_queries.ts b/src/hackerrank/interview_preparation_kit/miscellaneous/friend_circle_queries.ts new file mode 100644 index 00000000..9f562d4a --- /dev/null +++ b/src/hackerrank/interview_preparation_kit/miscellaneous/friend_circle_queries.ts @@ -0,0 +1,73 @@ +/** + * @link Problem definition [[docs/hackerrank/interview_preparation_kit/miscellaneous/friend-circle-queries.md]] + */ + +class GropingFriends { + _friendship: Record = {}; + _large_friendship: number = 0; + + constructor() { + this._friendship = {}; + this._large_friendship = 0; + } + + add(point_a: number): void { + if (!this._friendship?.[point_a]) { + this._friendship[point_a] = -1; + } + } + + find(point_a: number): number { + if (this._friendship[point_a] < 0) { + return point_a; + } + return this.find(this._friendship[point_a]); + } + + unite(point_a: number, point_b: number): boolean { + this.add(point_a); + this.add(point_b); + + let _a = this.find(point_a); + let _b = this.find(point_b); + + if (_a == _b) { + return false; + } + + if (_a > _b) { + [_a, _b] = [_b, _a]; + } + + this._friendship[_a] += this._friendship[_b]; + this._friendship[_b] = _a; + + // large group is the root node with "high" value + this._large_friendship = Math.max( + this._large_friendship, + -1 * this._friendship[_a] + ); + return true; + } + + count_groups(): number { + return this._large_friendship; + } +} + +export function maxCircle(queries: number[][]): number[] { + const result: number[] = []; + const friends = new GropingFriends(); + + queries.forEach((query) => { + // Computing friendship + friends.unite(query[0], query[1]); + + // Counting friends groups + result.push(friends.count_groups()); + }); + + return result; +} + +export default { maxCircle };