📖 Scenario: Imagine you are organizing a small event and need to select tasks to complete within a limited time. Each task has a duration and a value representing its importance. You want to pick tasks to maximize total importance without exceeding your available time.This project will help you understand how a greedy approach can work well in some cases and fail in others.
🎯 Goal: You will build a simple Rust program that selects tasks using a greedy method based on task duration. Then, you will see when this approach fails and why.
📋 What You'll Learn
Create a list of tasks with exact durations and values
Set a total available time limit
Implement a greedy selection picking shortest tasks first
Print the selected tasks and their total value
💡 Why This Matters
🌍 Real World
Greedy algorithms are used in scheduling, resource allocation, and many optimization problems where quick decisions are needed.
💼 Career
Understanding when greedy algorithms work or fail helps in software engineering roles involving algorithm design and performance optimization.
Progress0 / 4 steps
1
Create the list of tasks
Create a vector called tasks containing these tuples exactly: ("Task1", 3, 5), ("Task2", 1, 1), ("Task3", 2, 8), ("Task4", 4, 4). Each tuple is (name, duration, value).
DSA Rust
Hint
Use vec![ ("Task1", 3, 5), ... ] to create the vector.
2
Set the total available time
Create a variable called total_time and set it to 5 to represent the total available time for tasks.
DSA Rust
Hint
Use let total_time = 5; to set the time limit.
3
Select tasks greedily by shortest duration
Write code to select tasks greedily by picking tasks with the shortest duration first. Use a mutable vector selected_tasks to store chosen tasks. Keep track of used_time starting at 0. Iterate over tasks sorted by duration, add a task if it fits in total_time, and update used_time.
DSA Rust
Hint
Sort tasks by duration, then pick tasks while total time allows.
4
Print the selected tasks and total value
Print the selected tasks in the format Task1 (3, 5) separated by commas. Then print the total value of selected tasks as Total value: X where X is the sum of values.
DSA Rust
Hint
Use println! to show tasks and sum values.
Practice
(1/5)
1. What is the main reason a greedy algorithm works correctly for some problems?
easy
A. Because it tries all possible solutions and picks the best one
B. Because choosing the best option at each step leads to an optimal solution
C. Because it uses recursion to explore all paths
D. Because it sorts the input data before processing
Solution
Step 1: Understand greedy choice property
A greedy algorithm works when making the best local choice at each step leads to a globally optimal solution.
Step 2: Differentiate from other methods
Unlike exhaustive search or recursion, greedy does not try all solutions but relies on local optimal choices.
Final Answer:
Because choosing the best option at each step leads to an optimal solution -> Option B
Quick Check:
Greedy choice property = A [OK]
Hint: Greedy picks best local choice aiming for global best [OK]
Common Mistakes:
Thinking greedy tries all solutions
Confusing greedy with recursion or backtracking
Assuming sorting alone makes greedy work
2. Which of the following Rust code snippets correctly implements a greedy approach to select intervals with earliest finishing time?
easy
A. intervals.sort_by_key(|x| x.start); let mut count = 0; let mut last_end = 0; for i in &intervals { if i.end >= last_end { count += 1; last_end = i.start; } }
B. intervals.sort_by_key(|x| x.end); let mut count = 0; for i in &intervals { count += 1; }
C. intervals.sort_by_key(|x| x.end); let mut count = 0; let mut last_end = 0; for i in &intervals { if i.start >= last_end { count += 1; last_end = i.end; } }
D. intervals.sort_by_key(|x| x.start); let mut count = 0; for i in &intervals { if i.start > last_end { count += 1; last_end = i.end; } }
Solution
Step 1: Identify correct sorting key
The greedy interval scheduling algorithm sorts intervals by their finishing time (end).
Step 2: Check selection condition and update
It selects intervals starting after or at the last selected interval's end, updating last_end accordingly.
Final Answer:
intervals.sort_by_key(|x| x.end); let mut count = 0; let mut last_end = 0; for i in &intervals { if i.start >= last_end { count += 1; last_end = i.end; } } -> Option C
Quick Check:
Sort by end, pick if start >= last_end = B [OK]
Hint: Sort by finish time, pick intervals starting after last end [OK]
Common Mistakes:
Sorting by start time instead of end time
Updating last_end incorrectly
Counting all intervals without condition
3. Consider the Rust code below that tries to find the minimum number of coins for a given amount using greedy approach with coin denominations [25, 10, 5, 1]. What is the output for amount = 30?
let coins = [25, 10, 5, 1];
let mut amount = 30;
let mut count = 0;
for &coin in &coins {
count += amount / coin;
amount %= coin;
}
println!("{}", count);
medium
A. 4
B. 3
C. 5
D. 2
Solution
Step 1: Calculate coins for 25-cent
30 / 25 = 1 coin, remainder 30 % 25 = 5
Step 2: Calculate coins for 10-cent, 5-cent, 1-cent
Hint: Divide amount by largest coin, reduce remainder, sum counts [OK]
Common Mistakes:
Adding coins incorrectly
Using wrong coin order
Ignoring remainder after division
4. The following Rust code attempts to solve the coin change problem greedily with coins [10, 6, 1] and amount 12. It outputs the number of coins used. What is the bug?
let coins = [10, 6, 1];
let mut amount = 12;
let mut count = 0;
for &coin in &coins {
count += amount / coin;
amount %= coin;
}
println!("{}", count);
medium
A. The greedy approach fails to find minimum coins for these denominations
B. The code has a syntax error in the for loop
C. The amount variable is not mutable
D. The coins array is not sorted
Solution
Step 1: Understand greedy failure for coin set
Greedy picks 10 once, remainder 2, then two 1 coins = 3 coins total.
Step 2: Check for better solution
Using two 6 coins gives 12 with only 2 coins, better than greedy's 3.
Step 3: Identify bug
The bug is greedy approach itself fails to find minimum coins for this coin set.
Final Answer:
The greedy approach fails to find minimum coins for these denominations -> Option A
Quick Check:
Greedy fails on non-canonical coins = D [OK]
Hint: Greedy fails if coin set is non-canonical [OK]
Common Mistakes:
Thinking code syntax is wrong
Assuming sorting fixes greedy failure
Ignoring greedy algorithm limitations
5. You want to select activities from a list with start and end times to maximize the number of activities chosen. However, some activities overlap partially. Which approach correctly applies greedy algorithm to solve this, and why might it fail if you choose activities by earliest start time instead of earliest finish time?
hard
A. Sort activities by earliest finish time and pick compatible ones; choosing by start time can miss optimal sets
B. Sort activities by earliest start time and pick all that start earliest; this always works
C. Pick activities randomly; greedy always finds optimal solution
D. Sort activities by longest duration and pick those first; this maximizes usage
Solution
Step 1: Identify correct greedy strategy
Sorting by earliest finish time ensures maximum remaining time for other activities.
Step 2: Explain failure of sorting by start time
Choosing by earliest start time can select long activities blocking many others, missing optimal count.
Step 3: Conclude correct approach and failure reason
Greedy works with earliest finish time sorting; earliest start time sorting may fail to maximize activities.
Final Answer:
Sort activities by earliest finish time and pick compatible ones; choosing by start time can miss optimal sets -> Option A
Quick Check:
Earliest finish time sorting = A [OK]
Hint: Sort by finish time, not start time, to maximize activities [OK]
Common Mistakes:
Assuming earliest start time sorting always works
Picking longest duration first
Ignoring overlap constraints
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.