diff --git a/docs/hackerrank/interview_preparation_kit/sort/ctci-comparator-sorting.md b/docs/hackerrank/interview_preparation_kit/sort/ctci-comparator-sorting.md new file mode 100644 index 00000000..ac14bb86 --- /dev/null +++ b/docs/hackerrank/interview_preparation_kit/sort/ctci-comparator-sorting.md @@ -0,0 +1,86 @@ +# [Sorting: Comparator](https://www.hackerrank.com/challenges/ctci-comparator-sorting) + +Write a Comparator for sorting elements in an array. + +- Difficulty: `#medium` +- Category: `#ProblemSolvingBasic` `#sorting` + +Comparators are used to compare two objects. +In this challenge, you'll create a comparator and use it to sort an array. +The Player class is provided in the editor below. It has two fields: + +1. `name`: a string. +2. `score`: an integer. + +Given an array of `n` Player objects, +write a comparator that sorts them in order of decreasing score. + +If `2` or more players have the same score, +sort those players alphabetically ascending by name. +To do this, you must create a Checker class that +implements the Comparator interface, +then write an int compare(Player a, Player b) method implementing the +[Comparator.compare(T o1, T o2)](https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html#compare(T,%20T)) +method. +In short, when sorting in ascending order, +a comparator function returns `-1` if `a < b`, +`0` if `a = b`, and `1` if `a > b`. + +Declare a Checker class that implements the comparator method as described. + +It should sort first descending by score, +then ascending by name. +The code stub reads the input, +creates a list of Player objects, +uses your method to sort the data, and prints it out properly. + +## Example + +`n = 3` +`data = [[Smith, 20], [Jones, 15], [Jones, 20]]` + +Sort the list as $ data_{sorted} $ = `[Jones, 20], [[Smith, 20], [Jones, 15]]`. +Sort first descending by score, then ascending by name. + +## Input Format + +The first line contains an integer, `n`, the number of players. +Each of the next `n` lines contains a player's `name` and `score`, +a string and an integer. + +## Constraints + +- $ 0 \leq score \leq 1000 $ +- Two or more players can have the same name. +- Player names consist of lowercase English alphabetic letters. + +## Output Format + +You are not responsible for printing any output to stdout. +Locked stub code in Solution will instantiate a Checker object, +use it to sort the Player array, and print each sorted element. + +## Sample Input + +```text +5 +amy 100 +david 100 +heraldo 50 +aakansha 75 +aleksa 150 +``` + +## Sample Output + +```text +aleksa 150 +amy 100 +david 100 +aakansha 75 +heraldo 50 +``` + +## Explanation + +The players are first sorted descending by score, then ascending by name. diff --git a/src/hackerrank/interview_preparation_kit/sort/ctci_comparator_sorting.Player.js b/src/hackerrank/interview_preparation_kit/sort/ctci_comparator_sorting.Player.js new file mode 100644 index 00000000..6d62acb9 --- /dev/null +++ b/src/hackerrank/interview_preparation_kit/sort/ctci_comparator_sorting.Player.js @@ -0,0 +1,22 @@ +// Start Given code + +export class Player { + name = ''; + + score = 0; + + toString() { + // Given code + this.name.toString(); + return ''; + } + + comparator(bPlayer) { + // Given code + return 0 * this.score * bPlayer.score; + } +} + +// End Given code + +export default { Player }; diff --git a/src/hackerrank/interview_preparation_kit/sort/ctci_comparator_sorting.js b/src/hackerrank/interview_preparation_kit/sort/ctci_comparator_sorting.js new file mode 100644 index 00000000..7a5ada7f --- /dev/null +++ b/src/hackerrank/interview_preparation_kit/sort/ctci_comparator_sorting.js @@ -0,0 +1,51 @@ +/** + * @link Problem definition [[docs/hackerrank/interview_preparation_kit/sort/ctci-comparator-sorting.md]] + */ + +import { Player } from './ctci_comparator_sorting.Player.js'; + +export class SortablePlayer extends Player { + name = ''; + + score = 0; + + constructor(name, score) { + super(); + + this.name = name; + this.score = score; + } + + toString() { + return `${this.name} ${this.score}`; + } + + comparator(bPlayer) { + if (this.score > bPlayer.score) { + return -1; + } + if (this.score < bPlayer.score) { + return 1; + } + if (this.name < bPlayer.name) { + return -1; + } + if (this.name > bPlayer.name) { + return 1; + } + + return 0; + } +} + +export function comparatorSorting(players) { + const sortedPlayers = [...players].sort((a, b) => a.comparator(b)); + + return sortedPlayers.map((player) => player.toString()); +} + +export function comparatorSortingPrint(players) { + console.log(comparatorSorting(players)?.join('\n')); +} + +export default { Player, SortablePlayer, comparatorSorting }; diff --git a/src/hackerrank/interview_preparation_kit/sort/ctci_comparator_sorting.test.js b/src/hackerrank/interview_preparation_kit/sort/ctci_comparator_sorting.test.js new file mode 100644 index 00000000..a626de19 --- /dev/null +++ b/src/hackerrank/interview_preparation_kit/sort/ctci_comparator_sorting.test.js @@ -0,0 +1,42 @@ +import { describe, expect, it } from '@jest/globals'; + +import { Player } from './ctci_comparator_sorting.Player.js'; + +import { + SortablePlayer, + comparatorSorting, + comparatorSortingPrint +} from './ctci_comparator_sorting.js'; +import TEST_CASES from './ctci_comparator_sorting.testcases.json'; + +describe('comparatorSorting', () => { + it('test_player', () => { + expect.assertions(2); + + const aPlayer = new Player(); + const aPlayerAsString = aPlayer.toString(); + const aExpected = ''; + + expect(aExpected).toStrictEqual(aPlayerAsString); + + const bPlayer = new Player(); + const comparatorAnswerExpected = 0; + + expect(aPlayer.comparator(bPlayer)).toStrictEqual(comparatorAnswerExpected); + }); + + it('test_comparator_sorting', () => { + expect.assertions(8); + + TEST_CASES.forEach((test) => { + const players = []; + + for (const player of test.input) { + players.push(new SortablePlayer(player.name, player.score)); + } + + expect(comparatorSorting(players)).toStrictEqual(test.sorted); + expect(comparatorSortingPrint(players)).toBeUndefined(); + }); + }); +}); diff --git a/src/hackerrank/interview_preparation_kit/sort/ctci_comparator_sorting.testcases.json b/src/hackerrank/interview_preparation_kit/sort/ctci_comparator_sorting.testcases.json new file mode 100644 index 00000000..795c4247 --- /dev/null +++ b/src/hackerrank/interview_preparation_kit/sort/ctci_comparator_sorting.testcases.json @@ -0,0 +1,86 @@ +[ + { + "title": "Sample Test Case 0", + "input": [ + { + "name": "amy", + "score": 100 + }, + { + "name": "david", + "score": 100 + }, + { + "name": "heraldo", + "score": 50 + }, + { + "name": "aakansha", + "score": 75 + }, + { + "name": "aleksa", + "score": 150 + } + ], + "sorted": ["aleksa 150", "amy 100", "david 100", "aakansha 75", "heraldo 50"], + "expected": "aleksa 150\namy 100\ndavid 100\naakansha 75\nheraldo 50" + }, + { + "title": "Sample Test Case 6", + "input": [ + { + "name": "smith", + "score": 20 + }, + { + "name": "jones", + "score": 15 + }, + { + "name": "jones", + "score": 20 + } + ], + "sorted": ["jones 20", "smith 20", "jones 15"], + "expected": "jones 20\nsmith 20\njones 15" + }, + { + "title": "Sample Test Case 7", + "input": [ + { + "name": "davis", + "score": 15 + }, + { + "name": "davis", + "score": 20 + }, + { + "name": "davis", + "score": 10 + }, + { + "name": "edgehill", + "score": 15 + } + ], + "sorted": ["davis 20", "davis 15", "edgehill 15", "davis 10"], + "expected": "davis 20\ndavis 15\nedgehill 15\ndavis 10" + }, + { + "title": "Edge case: draw", + "input": [ + { + "name": "kurt", + "score": 100 + }, + { + "name": "kurt", + "score": 100 + } + ], + "sorted": ["kurt 100", "kurt 100"], + "expected": "kurt 100\nkurt 100" + } +]