Skip to content

Commit 33bb6ad

Browse files
authored
Merge pull request #350 from sir-gon/feature/greedy_florist
[Hacker Rank] Interview Preparation Kit: Greedy Algorithms: Greedy Fl…
2 parents 385692b + 59aba5f commit 33bb6ad

File tree

5 files changed

+284
-0
lines changed

5 files changed

+284
-0
lines changed
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` `#greedyalgorithms`
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` `#greedyalgorithms`
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`.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* @link Problem definition [[docs/hackerrank/interview_preparation_kit/greedy_algorithms/greedy-florist.md]]
3+
* @see Solution notes [[docs/hackerrank/interview_preparation_kit/greedy_algorithms/greedy-florist-solution-notes.md]]
4+
*/
5+
6+
package hackerrank
7+
8+
import (
9+
"slices"
10+
)
11+
12+
func getMinimumCost(k int32, c []int32) int32 {
13+
// Sort the array
14+
flowers := make([]int32, len(c))
15+
copy(flowers, c)
16+
slices.Sort(flowers)
17+
slices.Reverse(flowers)
18+
19+
total := int32(0)
20+
k_customers := int(k)
21+
22+
for i, flower_cost := range flowers {
23+
var position = int32(i / k_customers)
24+
total += int32(position+1) * int32(flower_cost)
25+
}
26+
27+
return total
28+
}
29+
30+
func GetMinimumCost(k int32, c []int32) int32 {
31+
return getMinimumCost(k, c)
32+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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+
{
21+
"title": "Test case 1",
22+
"k": 3,
23+
"c": [390225, 426456, 688267, 800389, 990107, 439248, 240638, 15991, 874479, 568754, 729927, 980985, 132244, 488186, 5037, 721765, 251885, 28458, 23710, 281490, 30935, 897665, 768945, 337228, 533277, 959855, 927447, 941485, 24242, 684459, 312855, 716170, 512600, 608266, 779912, 950103, 211756, 665028, 642996, 262173, 789020, 932421, 390745, 433434, 350262, 463568, 668809, 305781, 815771, 550800],
24+
"expected": 163578911
25+
}
26+
]
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package hackerrank
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
"gon.cl/algorithms/utils"
10+
)
11+
12+
type GreedyFloristTestCase struct {
13+
C []int32 `json:"c"`
14+
K int32 `json:"k"`
15+
Expected int32 `json:"expected"`
16+
}
17+
18+
var GreedyFloristTestCases []GreedyFloristTestCase
19+
20+
// You can use testing.T, if you want to test the code without benchmarking
21+
func GreedyFloristSetupSuite(t testing.TB) {
22+
wd, _ := os.Getwd()
23+
filepath := wd + "/greedy_florist.testcases.json"
24+
t.Log("Setup test cases from JSON: ", filepath)
25+
26+
var _, err = utils.LoadJSON(filepath, &GreedyFloristTestCases)
27+
if err != nil {
28+
t.Log(err)
29+
}
30+
}
31+
32+
func TestGreedyFlorist(t *testing.T) {
33+
34+
GreedyFloristSetupSuite(t)
35+
36+
for _, tt := range GreedyFloristTestCases {
37+
testname := fmt.Sprintf("getMinimumCost(%v, %v) => %v \n", tt.K, tt.C, tt.Expected)
38+
t.Run(testname, func(t *testing.T) {
39+
ans := GetMinimumCost(tt.K, tt.C)
40+
assert.Equal(t, tt.Expected, ans)
41+
})
42+
}
43+
}

0 commit comments

Comments
 (0)