Skip to content

Commit 1800ebc

Browse files
author
Gonzalo Diaz
committed
[Hacker Rank] Interview Preparation Kit: Greedy Algorithms: Greedy Florist. Solved ✅.
1 parent fb0e6bc commit 1800ebc

File tree

5 files changed

+293
-0
lines changed

5 files changed

+293
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package ae.hackerrank.interview_preparation_kit.greedy_algorithms;
2+
3+
import java.util.Arrays;
4+
import java.util.Collections;
5+
import java.util.List;
6+
import java.util.stream.Collectors;
7+
8+
/**
9+
* GreedyFlorist.
10+
*
11+
* @link Problem definition
12+
* [[docs/hackerrank/interview_preparation_kit/greedy_algorithms/greedy-florist.md]]
13+
* @link Solution notes
14+
* [[docs/hackerrank/interview_preparation_kit/greedy_algorithms/greedy-florist-solution-notes.md]]
15+
*/
16+
public class GreedyFlorist {
17+
18+
private GreedyFlorist() {
19+
}
20+
21+
/**
22+
* getMinimumCost.
23+
*/
24+
public static int getMinimumCost(int k, int[] c) {
25+
List<Integer> flowers = Arrays.stream(c).boxed().collect(Collectors.toList());
26+
Collections.reverse(flowers);
27+
28+
int totalCost = 0;
29+
int i = 0;
30+
31+
for (Integer flowerCost : flowers) {
32+
int position = (int) (i / k);
33+
totalCost += (position + 1) * flowerCost;
34+
35+
i += 1;
36+
}
37+
38+
return totalCost;
39+
}
40+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package ae.hackerrank.interview_preparation_kit.greedy_algorithms;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
5+
import java.io.IOException;
6+
import java.util.List;
7+
import org.junit.jupiter.api.BeforeAll;
8+
import org.junit.jupiter.api.Test;
9+
import org.junit.jupiter.api.TestInstance;
10+
import org.junit.jupiter.api.TestInstance.Lifecycle;
11+
import util.JsonLoader;
12+
13+
/**
14+
* GreedyFloristTest.
15+
*/
16+
@TestInstance(Lifecycle.PER_CLASS)
17+
class GreedyFloristTest {
18+
public static class GreedyFloristTestCase {
19+
public String title;
20+
public List<Integer> c;
21+
public Integer k;
22+
public Integer expected;
23+
}
24+
25+
private List<GreedyFloristTestCase> testCases;
26+
27+
@BeforeAll
28+
void setup() throws IOException {
29+
String path = String.join("/",
30+
"hackerrank",
31+
"interview_preparation_kit",
32+
"greedy_algorithms",
33+
"greedy_florist.testcases.json");
34+
this.testCases = JsonLoader.loadJson(path, GreedyFloristTestCase.class);
35+
}
36+
37+
@Test
38+
void testLuckBalance() {
39+
for (GreedyFloristTestCase test : testCases) {
40+
int[] inputArray = test.c.stream().mapToInt(Integer::intValue).toArray();
41+
Integer result = GreedyFlorist.getMinimumCost(test.k, inputArray);
42+
43+
assertEquals(test.expected, result,
44+
"%s(%s) => must be: %d".formatted(
45+
"GreedyFlorist.getMinimumCost",
46+
test.c.toString(),
47+
test.expected));
48+
}
49+
}
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[
2+
{
3+
"title": "Sample Test case 0",
4+
"k": 3,
5+
"c": [2, 5, 6],
6+
"expected": 13
7+
},
8+
{
9+
"title": "Sample Test case 1",
10+
"k": 2,
11+
"c": [2, 5, 6],
12+
"expected": 15
13+
},
14+
{
15+
"title": "Sample Test case 2",
16+
"k": 3,
17+
"c": [1, 3, 5, 7, 9],
18+
"expected": 29
19+
}
20+
]
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# [Greedy Algorithms: Greedy Florist](https://www.hackerrank.com/challenges/greedy-florist)
2+
3+
- Difficulty: `#medium`
4+
- Category: `#ProblemSolvingBasic`
5+
6+
## About the problem statement
7+
8+
At first it seems a bit confusing. Due the problem statement tends to
9+
make us believe that the most convenient thing is to start with the highest
10+
numbers, but the examples doesn't not present a logical descending order.
11+
12+
## Way of thinking
13+
14+
After rereading the problem several times it can be determined that:
15+
16+
- It does not matter who the buyers are, nor in what order they buy,
17+
nor how much each one buys.
18+
The important thing is how many people are organized
19+
into a group to minimize the purchase price.
20+
21+
- If the number of people in the group is greater than or equal to
22+
the number of different flowers, then the price is the lowest possible,
23+
because they can all be purchased "in a single pass",
24+
making each person in the group (or less) buy 1 unit.
25+
26+
- The price of flowers does matter, therefore it is more convenient to buy
27+
the most expensive ones first.
28+
Each "round" of purchasing makes the flowers more expensive,
29+
therefore it is better to buy the cheapest ones in the last "round."
30+
31+
## Deductions
32+
33+
- It seems convenient to sort the flower price list entry in descending order
34+
(or in ascending order, traversing the new sorted list in reverse).
35+
36+
- The number of passes depends on how many "groups" of "k - people"
37+
fit in the list of flowers, that is:
38+
$ \textbf{\#(c) / k}$ (integer division)
39+
40+
- At first I assumed that the order in which the traversal is done in
41+
the examples was a suggestion of the criteria in which the list of flowers
42+
should be traversed to reach the solution.
43+
44+
Finally, realizing that the price calculation in descending order
45+
(and "the round" in which the purchase is made)
46+
and the example were equivalent, made me consider the idea that the order of
47+
the examples might just be a distractor,
48+
introduced on purpose to make deducing the solution a little more difficult.
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# [Greedy Algorithms: Greedy Florist](https://www.hackerrank.com/challenges/greedy-florist)
2+
3+
- Difficulty: `#medium`
4+
- Category: `#ProblemSolvingBasic`
5+
6+
A group of friends want to buy a bouquet of flowers.
7+
The florist wants to maximize his number of new customers and the money he makes.
8+
To do this, he decides he'll multiply the price of each flower by the number
9+
of that customer's previously purchased flowers plus `1`.
10+
The first flower will be original price, $(0 + 1) \times \text{original price}$,
11+
the next will be $(1 + 1) \times \text{original price}$ and so on.
12+
13+
Given the size of the group of friends, the number of flowers they want
14+
to purchase and the original prices of the flowers, determine the minimum cost
15+
to purchase all of the flowers.
16+
The number of flowers they want equals the length of the array.
17+
18+
## Example
19+
20+
`c = [1, 2, 3, 4]`
21+
`k = 3`
22+
23+
The length of `c = 4`, so they want to buy `4` flowers total.
24+
Each will buy one of the flowers priced `[2, 3, 4]` at the original price.
25+
Having each purchased `x = 1` flower,
26+
the first flower in the list, `c[0]`, will now cost
27+
$ (
28+
\textsf{\textbf{current purchase}}
29+
+
30+
\textsf{\textbf{previous purchase}}
31+
) \times
32+
\textsf{\textbf{c[0]}} $.
33+
The total cost is `2 + 3 + 4 + 2 = 11`.
34+
35+
## Function Description
36+
37+
Complete the getMinimumCost function in the editor below.
38+
39+
getMinimumCost has the following parameter(s):
40+
41+
- `int c[n]`: the original price of each flower
42+
- `int k`: the number of friends
43+
44+
## Returns
45+
46+
- `int`: the minimum cost to purchase all flowers
47+
48+
## Input Format
49+
50+
The first line contains two space-separated integers `n` and `k`,
51+
the number of flowers and the number of friends.
52+
The second line contains `n` space-separated positive integers `c[i]`,
53+
the original price of each flower.
54+
55+
## Constraints
56+
57+
- $ 1 \leq n, k \leq 100 $
58+
- $ 1 \leq c[i] \leq 10^5 $
59+
- $ answer < 2^31 $
60+
- $ 0 \leq i \leq n $
61+
62+
## Sample Input 0
63+
64+
```text
65+
3 3
66+
2 5 6
67+
```
68+
69+
## Sample Output 0
70+
71+
```text
72+
13
73+
```
74+
75+
## Explanation 0
76+
77+
There are `n = 3` flowers with costs `c = [2, 5, ,6]` and `k = 3` people in the group.
78+
If each person buys one flower,
79+
the total cost of prices paid is `2 + 5 + 6 = 13` dollars.
80+
Thus, we print `13` as our answer.
81+
82+
## Sample Input 1
83+
84+
```text
85+
3 2
86+
2 5 6
87+
```
88+
89+
## Sample Output 1
90+
91+
```text
92+
15
93+
```
94+
95+
## Explanation 1
96+
97+
There are `n = 3` flowers with costs `c = [2, 5, 6]` and `k = 2`
98+
people in the group.
99+
We can minimize the total purchase cost like so:
100+
101+
1. The first person purchases 2 flowers in order of decreasing price;
102+
this means they buy the more expensive flower ($ c_1 = 5 $) first at price
103+
$
104+
p_1 = (0 + 1) \times 5 = 5
105+
$
106+
dollars and the less expensive flower ($ c_0 = 5 $) second at price
107+
$
108+
p_0 = (1 + 1) \times 2 = 4
109+
$
110+
dollars.
111+
2. The second person buys the most expensive flower at price
112+
$
113+
p_2 = (0 + 1) \times 6 = 6
114+
$
115+
dollars.
116+
117+
We then print the sum of these purchases, which is `5 + 4 + 6 = 15`, as our answer.
118+
119+
## Sample Input 2
120+
121+
```text
122+
5 3
123+
1 3 5 7 9
124+
```
125+
126+
## Sample Output 2
127+
128+
```text
129+
29
130+
```
131+
132+
## Explanation 2
133+
134+
The friends buy flowers for `9, 7`, and `3, 5`, and `1` for a cost of
135+
`9 + 7 + 3 * (1 + 1) + 5 + 1 * (1 + 1) = 29`.

0 commit comments

Comments
 (0)