From a7c8cd3a95fd352ce9b3063f59b45744135218ea Mon Sep 17 00:00:00 2001 From: dcodesdev <101001810+dcodesdev@users.noreply.github.com> Date: Fri, 3 May 2024 13:23:18 +0300 Subject: [PATCH] new challenge: median and mode --- Cargo.lock | 4 ++ Cargo.toml | 1 + challenges/challenges.json | 12 +++++ challenges/median-and-mode/Cargo.toml | 6 +++ challenges/median-and-mode/description.md | 64 +++++++++++++++++++++++ challenges/median-and-mode/src/lib.rs | 30 +++++++++++ challenges/median-and-mode/src/starter.rs | 9 ++++ challenges/median-and-mode/src/tests.rs | 34 ++++++++++++ 8 files changed, 160 insertions(+) create mode 100644 challenges/median-and-mode/Cargo.toml create mode 100644 challenges/median-and-mode/description.md create mode 100644 challenges/median-and-mode/src/lib.rs create mode 100644 challenges/median-and-mode/src/starter.rs create mode 100644 challenges/median-and-mode/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 25deea3..58be872 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -594,6 +594,10 @@ checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" name = "mathematical-operations" version = "0.1.0" +[[package]] +name = "median-and-mod" +version = "0.1.0" + [[package]] name = "memchr" version = "2.7.2" diff --git a/Cargo.toml b/Cargo.toml index eb39aee..60d6ccd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ members = [ "challenges/mathematical-operations", "challenges/the-from-trait", "challenges/animal-sanctuary-registry", + "challenges/median-and-mode", "crates/cli", ] diff --git a/challenges/challenges.json b/challenges/challenges.json index b556702..4c492d8 100644 --- a/challenges/challenges.json +++ b/challenges/challenges.json @@ -82,5 +82,17 @@ "tags": [], "created_at": "2024-04-30T00:00:00Z", "updated_at": "2024-04-30T00:00:00Z" + }, + { + "id": 8, + "title": "Median and mode", + "slug": "median-and-mode", + "short_description": "Write a program that calculates the median and mode of a list of numbers.", + "language": "RUST", + "difficulty": "MEDIUM", + "track": "RUST_BASICS", + "tags": [], + "created_at": "2024-05-03T00:00:00Z", + "updated_at": "2024-05-03T00:00:00Z" } ] diff --git a/challenges/median-and-mode/Cargo.toml b/challenges/median-and-mode/Cargo.toml new file mode 100644 index 0000000..787978e --- /dev/null +++ b/challenges/median-and-mode/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "median-and-mod" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/challenges/median-and-mode/description.md b/challenges/median-and-mode/description.md new file mode 100644 index 0000000..c9e9c55 --- /dev/null +++ b/challenges/median-and-mode/description.md @@ -0,0 +1,64 @@ +## Vectors + +Vectors in Rust are a collection type that can store multiple values of the same type. They are similar to **arrays in JavaScript** and **lists in Python** but with some additional features, they are stored on the heap and they can grow or shrink in size. + +In this challenge you're asked to implement two functions that calculate the **median and mode** of a list of integers. + +Read the definitions of each **Median** and **Mode** below to understand what you need to implement. + +### Median + +The median is the middle value of a list when it is ordered by size. If the list has an even number of elements, the median is the average of the two middle numbers. + +Here's an example: + +```rust +let mut numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9]; +let median = median(&mut numbers); +assert_eq!(median, 5.0); +``` + +Or if the number of elements is even: + +```rust +let mut numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; +let median = median(&mut numbers); +assert_eq!(median, 5.5); +``` + +You can implement the function in the following steps: + +- Sort the list of numbers. +- If the number of elements is odd, return the middle element. +- If the number of elements is even, return the average of the two middle elements. + +### Mode + +The mode is the number that appears most frequently in a list, if there are multiple numbers that appear the same number of times, return all of them in a vector. + +Here's an example: + +```rust +let numbers = vec![1, 1, 1, 1, 2] +let mode = mode(&numbers); +assert_eq!(mode, vec![1]); +``` + +The number `1` appears four times, which is more than any other number in the list. + +> **Important**: You must sort the list of numbers before returning the modes list. + +### Hints + +- You can use the `sort` method to sort a vector. +- You can use the `entry` method to insert a value into a hash map if it doesn't exist or update it if it does. +- When looping through a vector, you can dereference the value using `&` to get the value instead of a reference to it. For example: + +```rust +let numbers = vec![1, 2, 3, 4, 5]; +for &number in &numbers { + println!("{}", number); +} +``` + +- Store the maximum frequency and the number that appears most frequently in a `HashMap` and update it as you iterate through the list of numbers, and finally return the list of numbers that appears most frequently. diff --git a/challenges/median-and-mode/src/lib.rs b/challenges/median-and-mode/src/lib.rs new file mode 100644 index 0000000..7677f5a --- /dev/null +++ b/challenges/median-and-mode/src/lib.rs @@ -0,0 +1,30 @@ +mod tests; + +use std::collections::HashMap; + +pub fn median(numbers: &mut Vec) -> f32 { + numbers.sort(); + let mid = numbers.len() / 2; + if numbers.len() % 2 == 0 { + (numbers[mid - 1] as f32 + numbers[mid] as f32) / 2.0 + } else { + numbers[mid] as f32 + } +} + +pub fn mode(numbers: &Vec) -> Vec { + let mut occurrences = HashMap::new(); + for &number in numbers { + *occurrences.entry(number).or_insert(0) += 1; + } + + let max_count = occurrences.values().max().unwrap_or(&0); + let mut modes: Vec = occurrences + .iter() + .filter(|&(_, &count)| count == *max_count) + .map(|(&number, _)| number) + .collect(); + + modes.sort(); + modes +} diff --git a/challenges/median-and-mode/src/starter.rs b/challenges/median-and-mode/src/starter.rs new file mode 100644 index 0000000..3850b9e --- /dev/null +++ b/challenges/median-and-mode/src/starter.rs @@ -0,0 +1,9 @@ +use std::collections::HashMap; + +pub fn median(numbers: &mut Vec) -> f32 { + // TODO: Implement logic here to return the median of the list +} + +pub fn mode(numbers: &Vec) -> Vec { + // TODO: Implement logic here to return the mode of the list +} diff --git a/challenges/median-and-mode/src/tests.rs b/challenges/median-and-mode/src/tests.rs new file mode 100644 index 0000000..aad5b1e --- /dev/null +++ b/challenges/median-and-mode/src/tests.rs @@ -0,0 +1,34 @@ +#[cfg(test)] +mod tests { + use crate::{median, mode}; + + #[test] + fn test_median() { + let mut numbers = vec![1, 2, 2, 3, 4]; + assert_eq!(median(&mut numbers), 2.0); + + let mut numbers = vec![6, 1, 2, 3, 4, 5]; + assert_eq!(median(&mut numbers), 3.5); + + let mut numbers = vec![1, 2, 3, 4, 5, 6, 7]; + assert_eq!(median(&mut numbers), 4.0); + + let mut numbers = vec![123, 456, 789, 101112, 131415]; + assert_eq!(median(&mut numbers), 789.0); + } + + #[test] + fn test_mode() { + let numbers = vec![1, 2, 2, 2, 3, 4]; + assert_eq!(mode(&numbers), vec![2]); + + let numbers = vec![1, 3, 3, 6, 7, 8, 9]; + assert_eq!(mode(&numbers), vec![3]); + + let numbers = vec![2, 2, 2, 2, 2, 2, 2, 100, 100, 100, 100, 100, 100, 100, 100]; + assert_eq!(mode(&numbers), vec![100]); + + let numbers = vec![1, 1, 2, 2]; + assert_eq!(mode(&numbers), vec![1, 2]); + } +}