Skip to content

Commit 5986eb0

Browse files
author
Gonzalo Diaz
committed
[Hacker Rank] Interview Preparation Kit: Hash Tables: Ice Cream Parlor. Solved ✅.
1 parent 90aa172 commit 5986eb0

File tree

6 files changed

+287
-0
lines changed

6 files changed

+287
-0
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# [Hash Tables: Ice Cream Parlor](https://www.hackerrank.com/challenges/ctci-ice-cream-parlor)
2+
3+
- Difficulty: `#medium`
4+
- Category: `#ProblemSolvingIntermediate`
5+
6+
## Failed tries
7+
8+
### Brute force
9+
10+
First attempt: Brute force. Complexity O(n^2)
11+
Fails to pass additional test cases due to excessive time.
12+
13+
### Binary search
14+
15+
This attempt use the editorial suggestion: do a binary search.
16+
17+
For each flavor of ice cream on the cost list, the searched one
18+
is "trimmed" in a search from half (then half of half and so on) of the list.
19+
Complexity O(log n)
20+
21+
For some reason that I have not reviewed in detail,
22+
it works with the test cases in the examples,
23+
but fails in the result with all the hidden test cases.
24+
25+
The preliminary guess is that the "edges" may be poorly thought out,
26+
and it may also not properly account for cases where there may be
27+
"repeated" values in the search.
28+
29+
## Working solution
30+
31+
This solution has a complexity of O(N).
32+
It is based on a very simple idea.
33+
34+
A dictionary (key-value object) is created.
35+
36+
Then for each item (current ice cream):
37+
38+
- The difference between the budget and the current item is calculated.
39+
It tells us the value of the element to search for.
40+
41+
- We look for the element if it is in the "cache" (dictionary).
42+
We look for the value of the current element among the cache keys.
43+
44+
- If the element is NOT found in the dictionary,
45+
then we store the currently searched element in the cache,
46+
using the element's value as the cache key and the position
47+
(what we care about returning) as the cache value.
48+
49+
If the element is found, then we return the key of the current element
50+
and the key of the element found in the cache.
51+
52+
This mechanism also returns the smallest element that matches,
53+
in the case of repeated values (because the search is from start to finish,
54+
without reordering). In the case of passing by repeated values,
55+
the current element to be stored in the cache,
56+
steps on the previous position value with the new one,
57+
but since it is not the searched value, it is irrelevant.
58+
59+
- Source: [Hackerrank Hash Tables - Ice Cream Parlor Python solution](https://medium.com/@xww0701/hackerrank-hash-tables-ice-cream-parlor-python-solution-fac434523ec7)
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# [Hash Tables: Ice Cream Parlor](https://www.hackerrank.com/challenges/ctci-ice-cream-parlor)
2+
3+
- Difficulty: `#medium`
4+
- Category: `#ProblemSolvingIntermediate`
5+
6+
Each time Sunny and Johnny take a trip to the Ice Cream Parlor,
7+
they pool their money to buy ice cream.
8+
On any given day, the parlor offers a line of flavors.
9+
Each flavor has a cost associated with it.
10+
11+
Given the value of `money` and the `cost` of each flavor for `t`
12+
trips to the Ice Cream Parlor, help Sunny and Johnny choose two
13+
distinct flavors such that they spend their entire pool of money during each visit.
14+
ID numbers are the 1-based index number associated with a `cost`.
15+
For each trip to the parlor, print the ID numbers for the two
16+
types of ice cream that Sunny and Johnny purchase as
17+
two space-separated integers on a new line. You must print the smaller
18+
ID first and the larger ID second.
19+
20+
## Example
21+
22+
`cost = [2, 1, 3, 5, 6]`
23+
24+
`money = 5`
25+
26+
They would purchase flavor ID's `1` and `3` for a cost of `2 + 3 = 5`.
27+
Use 1-based indexing for your response.
28+
29+
**Note**:
30+
31+
- Two ice creams having unique IDs and may have the same cost
32+
(i.e., $ cost[i] \equiv cost[j] $).
33+
34+
- There will always be a unique solution.
35+
36+
## Function Description
37+
38+
Complete the function whatFlavors in the editor below.
39+
40+
whatFlavors has the following parameter(s):
41+
42+
- `int cost[n]`: the prices for each flavor
43+
- `int money`: the amount of money they have to spend
44+
45+
## Prints
46+
47+
- `int int`: the indices of the two flavors they will purchase as
48+
two space-separated integers on a line
49+
50+
## Input Format
51+
52+
The first line contains an integer, `t`, the number of trips to the ice cream parlor.
53+
54+
Each of the next sets of lines is as follows:
55+
56+
- The first line contains `money`.
57+
- The second line contains an integer, `n`, the size of the array `cost`.
58+
- The third line contains `n` space-separated integers denoting the `cost[i]`.
59+
60+
## Constraints
61+
62+
- $ 1 \leq t \leq 50$
63+
- $ 2 \leq money \leq 10^9 $
64+
- $ 2 \leq n \leq 5 * 10^4 $
65+
- $ 1 \leq cost[i] \leq 10^9 $
66+
67+
## Sample Input
68+
69+
```text
70+
STDIN Function
71+
----- --------
72+
2 t = 2
73+
4 money = 4
74+
5 cost[] size n = 5
75+
1 4 5 3 2 cost = [1, 4, 5, 3, 2]
76+
4 money = 4
77+
4 cost[] size n = 4
78+
2 2 4 3 cost = [2, 2, 4, 3]
79+
```
80+
81+
## Sample Output
82+
83+
```text
84+
1 4
85+
1 2
86+
```
87+
88+
## Explanation
89+
90+
Sunny and Johnny make the following two trips to the parlor:
91+
92+
1. The first time, they pool together $ money = 4 $ dollars.
93+
There are five flavors available that day and
94+
flavors `1` and `4` have a total cost of `1 + 3 = 4`.
95+
2. The second time, they pool together `money = 4` dollars.
96+
There are four flavors available that day and
97+
flavors `1` and `2` have a total cost of `2 + 2 = 4`.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[
2+
{
3+
"title": "Sample Test Case 0",
4+
"tests": [
5+
{
6+
"costs": [1, 4, 5, 3, 2],
7+
"money": 90,
8+
"expected": []
9+
}
10+
]
11+
}
12+
]
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { describe, expect, it } from '@jest/globals';
2+
import { logger as console } from '../../../logger';
3+
4+
import { whatFlavors, whatFlavorsCompute } from './ctci_ice_cream_parlor';
5+
import TEST_CASES from './ctci_ice_cream_parlor.testcases.json';
6+
import TEST_CASES_BORDER_CASES from './ctci_ice_cream_parlor.border_testcases.json';
7+
8+
describe('ctci_ice_cream_parlor', () => {
9+
it('whatFlavorsCompute test cases', () => {
10+
expect.assertions(10);
11+
12+
TEST_CASES.forEach((testSet) => {
13+
testSet?.tests.forEach((test) => {
14+
const answer = whatFlavorsCompute(test.costs, test.money);
15+
16+
console.debug(
17+
`whatFlavorsCompute(${test.costs}, ${test.money}) solution found: ${answer}`
18+
);
19+
20+
expect(answer).toStrictEqual(test.expected);
21+
expect(whatFlavors(test.costs, test.money)).toBeUndefined();
22+
});
23+
});
24+
});
25+
26+
it('whatFlavors border test cases', () => {
27+
expect.assertions(2);
28+
29+
TEST_CASES_BORDER_CASES.forEach((testSet) => {
30+
testSet?.tests.forEach((test) => {
31+
expect(whatFlavorsCompute(test.costs, test.money)).toStrictEqual(
32+
test.expected
33+
);
34+
expect(whatFlavors(test.costs, test.money)).toBeUndefined();
35+
});
36+
});
37+
});
38+
39+
it('whatFlavors test caller function', () => {
40+
expect.assertions(1);
41+
42+
const cost: number[] = [];
43+
const money: number = 100;
44+
45+
expect(whatFlavors(cost, money)).toBeUndefined();
46+
});
47+
});
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
[
2+
{
3+
"title": "Sample Test Case 0",
4+
"tests": [
5+
{
6+
"costs": [1, 4, 5, 3, 2],
7+
"money": 4,
8+
"expected": [1, 4]
9+
},
10+
{
11+
"costs": [2, 2, 4, 3],
12+
"money": 4,
13+
"expected": [1, 2]
14+
}
15+
]
16+
},
17+
{
18+
"title": "Sample Test Case 1",
19+
"tests": [
20+
{
21+
"costs": [1, 2, 3, 5, 6],
22+
"money": 5,
23+
"expected": [2, 3]
24+
}
25+
]
26+
},
27+
{
28+
"title": "Sample Test Case 2",
29+
"tests": [
30+
{
31+
"costs": [4, 3, 2, 5, 7],
32+
"money": 8,
33+
"expected": [2, 4]
34+
},
35+
{
36+
"costs": [7, 2, 5, 4, 11],
37+
"money": 12,
38+
"expected": [1, 3]
39+
}
40+
]
41+
}
42+
]
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* @link Problem definition [[docs/hackerrank/interview_preparation_kit/search/ctci-ice-cream-parlor.md]]
3+
*/
4+
5+
export function whatFlavorsCompute(
6+
cost: number[],
7+
money: number
8+
): number[] | null {
9+
const cache: Record<number, number> = {};
10+
11+
for (const [key, price] of Object.entries(cost)) {
12+
const i = parseInt(key);
13+
const diff = money - price;
14+
const cacheKeys = new Set(Object.keys(cache));
15+
16+
if (cacheKeys.has(diff.toString())) {
17+
return [i + 1, cache[diff] + 1].sort((a, b) => a - b);
18+
}
19+
20+
cache[price] = i;
21+
}
22+
23+
return [];
24+
}
25+
26+
export function whatFlavors(cost: number[], money: number): void {
27+
console.log(whatFlavorsCompute(cost, money)?.join(' '));
28+
}
29+
30+
export default { whatFlavorsCompute, whatFlavors };

0 commit comments

Comments
 (0)