-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #438 from sir-gon/feature/ctci-ice-cream-parlor
Feature/ctci ice cream parlor
- Loading branch information
Showing
10 changed files
with
469 additions
and
0 deletions.
There are no files selected for viewing
64 changes: 64 additions & 0 deletions
64
...errank/interview_preparation_kit/search/ctci-ice-cream-parlor-solution-notes.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# [Hash Tables: Ice Cream Parlor](https://www.hackerrank.com/challenges/ctci-ice-cream-parlor) | ||
|
||
- Difficulty: `#medium` | ||
- Category: `#ProblemSolvingIntermediate` | ||
|
||
## Failed tries | ||
|
||
### Brute force | ||
|
||
First attempt: Brute force. Complexity O(n^2) | ||
Fails to pass additional test cases due to excessive time. | ||
|
||
### Binary search | ||
|
||
This attempt use the editorial suggestion: do a binary search. | ||
|
||
For each flavor of ice cream on the cost list, the searched one | ||
is "trimmed" in a search from half (then half of half and so on) of the list. | ||
Complexity O(log n) | ||
|
||
For some reason that I have not reviewed in detail, | ||
it works with the test cases in the examples, | ||
but fails in the result with all the hidden test cases. | ||
|
||
The preliminary guess is that the "edges" may be poorly thought out, | ||
and it may also not properly account for cases where there may be | ||
"repeated" values in the search. | ||
|
||
## Editorial-based solution | ||
|
||
Using editorial C++ based solution, I can notice about that solution in O(n) space, | ||
realy do 3 times (3*O(n)) pass over data list. | ||
|
||
## Final working solution | ||
|
||
This solution has a complexity of O(N) in just one iteration. | ||
It is based on a very simple idea. | ||
|
||
A dictionary (key-value object) is created. | ||
|
||
Then for each item (current ice cream): | ||
|
||
- The difference between the budget and the current item is calculated. | ||
It tells us the value of the element to search for. | ||
|
||
- We look for the element if it is in the "cache" (dictionary). | ||
We look for the value of the current element among the cache keys. | ||
|
||
- If the element is NOT found in the dictionary, | ||
then we store the currently searched element in the cache, | ||
using the element's value as the cache key and the position | ||
(what we care about returning) as the cache value. | ||
|
||
If the element is found, then we return the key of the current element | ||
and the key of the element found in the cache. | ||
|
||
This mechanism also returns the smallest element that matches, | ||
in the case of repeated values (because the search is from start to finish, | ||
without reordering). In the case of passing by repeated values, | ||
the current element to be stored in the cache, | ||
steps on the previous position value with the new one, | ||
but since it is not the searched value, it is irrelevant. | ||
|
||
- Source: [Hackerrank Hash Tables - Ice Cream Parlor Python solution](https://medium.com/@xww0701/hackerrank-hash-tables-ice-cream-parlor-python-solution-fac434523ec7) |
97 changes: 97 additions & 0 deletions
97
docs/hackerrank/interview_preparation_kit/search/ctci-ice-cream-parlor.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
# [Hash Tables: Ice Cream Parlor](https://www.hackerrank.com/challenges/ctci-ice-cream-parlor) | ||
|
||
- Difficulty: `#medium` | ||
- Category: `#ProblemSolvingIntermediate` | ||
|
||
Each time Sunny and Johnny take a trip to the Ice Cream Parlor, | ||
they pool their money to buy ice cream. | ||
On any given day, the parlor offers a line of flavors. | ||
Each flavor has a cost associated with it. | ||
|
||
Given the value of `money` and the `cost` of each flavor for `t` | ||
trips to the Ice Cream Parlor, help Sunny and Johnny choose two | ||
distinct flavors such that they spend their entire pool of money during each visit. | ||
ID numbers are the 1-based index number associated with a `cost`. | ||
For each trip to the parlor, print the ID numbers for the two | ||
types of ice cream that Sunny and Johnny purchase as | ||
two space-separated integers on a new line. You must print the smaller | ||
ID first and the larger ID second. | ||
|
||
## Example | ||
|
||
`cost = [2, 1, 3, 5, 6]` | ||
|
||
`money = 5` | ||
|
||
They would purchase flavor ID's `1` and `3` for a cost of `2 + 3 = 5`. | ||
Use 1-based indexing for your response. | ||
|
||
**Note**: | ||
|
||
- Two ice creams having unique IDs and may have the same cost | ||
(i.e., $ cost[i] \equiv cost[j] $). | ||
|
||
- There will always be a unique solution. | ||
|
||
## Function Description | ||
|
||
Complete the function whatFlavors in the editor below. | ||
|
||
whatFlavors has the following parameter(s): | ||
|
||
- `int cost[n]`: the prices for each flavor | ||
- `int money`: the amount of money they have to spend | ||
|
||
## Prints | ||
|
||
- `int int`: the indices of the two flavors they will purchase as | ||
two space-separated integers on a line | ||
|
||
## Input Format | ||
|
||
The first line contains an integer, `t`, the number of trips to the ice cream parlor. | ||
|
||
Each of the next sets of lines is as follows: | ||
|
||
- The first line contains `money`. | ||
- The second line contains an integer, `n`, the size of the array `cost`. | ||
- The third line contains `n` space-separated integers denoting the `cost[i]`. | ||
|
||
## Constraints | ||
|
||
- $ 1 \leq t \leq 50$ | ||
- $ 2 \leq money \leq 10^9 $ | ||
- $ 2 \leq n \leq 5 * 10^4 $ | ||
- $ 1 \leq cost[i] \leq 10^9 $ | ||
|
||
## Sample Input | ||
|
||
```text | ||
STDIN Function | ||
----- -------- | ||
2 t = 2 | ||
4 money = 4 | ||
5 cost[] size n = 5 | ||
1 4 5 3 2 cost = [1, 4, 5, 3, 2] | ||
4 money = 4 | ||
4 cost[] size n = 4 | ||
2 2 4 3 cost = [2, 2, 4, 3] | ||
``` | ||
|
||
## Sample Output | ||
|
||
```text | ||
1 4 | ||
1 2 | ||
``` | ||
|
||
## Explanation | ||
|
||
Sunny and Johnny make the following two trips to the parlor: | ||
|
||
1. The first time, they pool together $ money = 4 $ dollars. | ||
There are five flavors available that day and | ||
flavors `1` and `4` have a total cost of `1 + 3 = 4`. | ||
2. The second time, they pool together `money = 4` dollars. | ||
There are four flavors available that day and | ||
flavors `1` and `2` have a total cost of `2 + 2 = 4`. |
12 changes: 12 additions & 0 deletions
12
src/hackerrank/interview_preparation_kit/search/ctci_ice_cream_parlor.border_testcases.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[ | ||
{ | ||
"title": "Sample Test Case 0", | ||
"tests": [ | ||
{ | ||
"costs": [1, 4, 5, 3, 2], | ||
"money": 90, | ||
"expected": [] | ||
} | ||
] | ||
} | ||
] |
47 changes: 47 additions & 0 deletions
47
src/hackerrank/interview_preparation_kit/search/ctci_ice_cream_parlor.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { describe, expect, it } from '@jest/globals'; | ||
import { logger as console } from '../../../logger'; | ||
|
||
import { whatFlavors, whatFlavorsCompute } from './ctci_ice_cream_parlor'; | ||
import TEST_CASES from './ctci_ice_cream_parlor.testcases.json'; | ||
import TEST_CASES_BORDER_CASES from './ctci_ice_cream_parlor.border_testcases.json'; | ||
|
||
describe('ctci_ice_cream_parlor', () => { | ||
it('whatFlavorsCompute test cases', () => { | ||
expect.assertions(10); | ||
|
||
TEST_CASES.forEach((testSet) => { | ||
testSet?.tests.forEach((test) => { | ||
const answer = whatFlavorsCompute(test.costs, test.money); | ||
|
||
console.debug( | ||
`whatFlavorsCompute(${test.costs}, ${test.money}) solution found: ${answer}` | ||
); | ||
|
||
expect(answer).toStrictEqual(test.expected); | ||
expect(whatFlavors(test.costs, test.money)).toBeUndefined(); | ||
}); | ||
}); | ||
}); | ||
|
||
it('whatFlavors border test cases', () => { | ||
expect.assertions(2); | ||
|
||
TEST_CASES_BORDER_CASES.forEach((testSet) => { | ||
testSet?.tests.forEach((test) => { | ||
expect(whatFlavorsCompute(test.costs, test.money)).toStrictEqual( | ||
test.expected | ||
); | ||
expect(whatFlavors(test.costs, test.money)).toBeUndefined(); | ||
}); | ||
}); | ||
}); | ||
|
||
it('whatFlavors test caller function', () => { | ||
expect.assertions(1); | ||
|
||
const cost: number[] = []; | ||
const money: number = 100; | ||
|
||
expect(whatFlavors(cost, money)).toBeUndefined(); | ||
}); | ||
}); |
42 changes: 42 additions & 0 deletions
42
src/hackerrank/interview_preparation_kit/search/ctci_ice_cream_parlor.testcases.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
[ | ||
{ | ||
"title": "Sample Test Case 0", | ||
"tests": [ | ||
{ | ||
"costs": [1, 4, 5, 3, 2], | ||
"money": 4, | ||
"expected": [1, 4] | ||
}, | ||
{ | ||
"costs": [2, 2, 4, 3], | ||
"money": 4, | ||
"expected": [1, 2] | ||
} | ||
] | ||
}, | ||
{ | ||
"title": "Sample Test Case 1", | ||
"tests": [ | ||
{ | ||
"costs": [1, 2, 3, 5, 6], | ||
"money": 5, | ||
"expected": [2, 3] | ||
} | ||
] | ||
}, | ||
{ | ||
"title": "Sample Test Case 2", | ||
"tests": [ | ||
{ | ||
"costs": [4, 3, 2, 5, 7], | ||
"money": 8, | ||
"expected": [2, 4] | ||
}, | ||
{ | ||
"costs": [7, 2, 5, 4, 11], | ||
"money": 12, | ||
"expected": [1, 3] | ||
} | ||
] | ||
} | ||
] |
29 changes: 29 additions & 0 deletions
29
src/hackerrank/interview_preparation_kit/search/ctci_ice_cream_parlor.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/** | ||
* @link Problem definition [[docs/hackerrank/interview_preparation_kit/search/ctci-ice-cream-parlor.md]] | ||
*/ | ||
|
||
export function whatFlavorsCompute( | ||
cost: number[], | ||
money: number | ||
): number[] | null { | ||
const cache: Record<number, number> = {}; | ||
|
||
for (const [key, price] of Object.entries(cost)) { | ||
const i = parseInt(key); | ||
const diff = money - price; | ||
|
||
if (Number.isInteger(cache?.[diff])) { | ||
return [i + 1, cache[diff] + 1].sort((a, b) => a - b); | ||
} | ||
|
||
cache[price] = i; | ||
} | ||
|
||
return []; | ||
} | ||
|
||
export function whatFlavors(cost: number[], money: number): void { | ||
console.log(whatFlavorsCompute(cost, money)?.join(' ')); | ||
} | ||
|
||
export default { whatFlavorsCompute, whatFlavors }; |
50 changes: 50 additions & 0 deletions
50
src/hackerrank/interview_preparation_kit/search/ctci_ice_cream_parlor_bruteforce.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { describe, expect, it } from '@jest/globals'; | ||
import { logger as console } from '../../../logger'; | ||
|
||
import { | ||
whatFlavors, | ||
what_flavors_bruteforce_compute | ||
} from './ctci_ice_cream_parlor_bruteforce'; | ||
import TEST_CASES from './ctci_ice_cream_parlor.testcases.json'; | ||
import TEST_CASES_BORDER_CASES from './ctci_ice_cream_parlor.border_testcases.json'; | ||
|
||
describe('ctci_ice_cream_parlor_bruteforce', () => { | ||
it('whatFlavors test cases', () => { | ||
expect.assertions(10); | ||
|
||
TEST_CASES.forEach((testSet) => { | ||
testSet?.tests.forEach((test) => { | ||
const answer = what_flavors_bruteforce_compute(test.costs, test.money); | ||
|
||
console.debug( | ||
`${testSet.title} ctci_ice_cream_parlor_bruteforce(${test.costs}, ${test.money}) solution found: ${answer}` | ||
); | ||
|
||
expect(answer).toStrictEqual(test.expected); | ||
expect(whatFlavors(test.costs, test.money)).toBeUndefined(); | ||
}); | ||
}); | ||
}); | ||
|
||
it('whatFlavors border test cases', () => { | ||
expect.assertions(2); | ||
|
||
TEST_CASES_BORDER_CASES.forEach((testSet) => { | ||
testSet?.tests.forEach((test) => { | ||
expect( | ||
what_flavors_bruteforce_compute(test.costs, test.money) | ||
).toStrictEqual(test.expected); | ||
expect(whatFlavors(test.costs, test.money)).toBeUndefined(); | ||
}); | ||
}); | ||
}); | ||
|
||
it('whatFlavors test caller function', () => { | ||
expect.assertions(1); | ||
|
||
const cost: number[] = []; | ||
const money: number = 100; | ||
|
||
expect(whatFlavors(cost, money)).toBeUndefined(); | ||
}); | ||
}); |
30 changes: 30 additions & 0 deletions
30
src/hackerrank/interview_preparation_kit/search/ctci_ice_cream_parlor_bruteforce.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/** | ||
* @link Problem definition [[docs/hackerrank/interview_preparation_kit/search/ctci-ice-cream-parlor.md]] | ||
*/ | ||
|
||
export function what_flavors_bruteforce_compute( | ||
cost: number[], | ||
money: number | ||
): number[] { | ||
for (const _i in cost) { | ||
const i: number = parseInt(_i); | ||
const x: number = cost[i]; | ||
|
||
const budget = money - x; | ||
|
||
for (let j = i + 1; j < cost.length; j++) { | ||
if (budget - cost[j] == 0) { | ||
console.log(`${i + 1} ${j + 1}`); | ||
return [i + 1, j + 1]; | ||
} | ||
} | ||
} | ||
|
||
return []; | ||
} | ||
|
||
export function whatFlavors(cost: number[], money: number): void { | ||
console.log(what_flavors_bruteforce_compute(cost, money)?.join(' ')); | ||
} | ||
|
||
export default { what_flavors_bruteforce_compute, whatFlavors }; |
Oops, something went wrong.