From fd70e0907cab18475985b028a94e0e02cc5ad1bf Mon Sep 17 00:00:00 2001 From: SquidSpirit Date: Wed, 17 Sep 2025 22:53:26 +0800 Subject: [PATCH] feat: 2353_design_a_food_rating_system --- 2353_design_a_food_rating_system/Cargo.lock | 7 ++ 2353_design_a_food_rating_system/Cargo.toml | 6 ++ 2353_design_a_food_rating_system/src/lib.rs | 93 +++++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 2353_design_a_food_rating_system/Cargo.lock create mode 100644 2353_design_a_food_rating_system/Cargo.toml create mode 100644 2353_design_a_food_rating_system/src/lib.rs diff --git a/2353_design_a_food_rating_system/Cargo.lock b/2353_design_a_food_rating_system/Cargo.lock new file mode 100644 index 0000000..7a0506b --- /dev/null +++ b/2353_design_a_food_rating_system/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "design_a_food_rating_system" +version = "0.1.0" diff --git a/2353_design_a_food_rating_system/Cargo.toml b/2353_design_a_food_rating_system/Cargo.toml new file mode 100644 index 0000000..652c311 --- /dev/null +++ b/2353_design_a_food_rating_system/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "design_a_food_rating_system" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/2353_design_a_food_rating_system/src/lib.rs b/2353_design_a_food_rating_system/src/lib.rs new file mode 100644 index 0000000..28ffa55 --- /dev/null +++ b/2353_design_a_food_rating_system/src/lib.rs @@ -0,0 +1,93 @@ +use std::collections::{BinaryHeap, HashMap}; + +#[derive(Clone, PartialEq, Eq)] +struct Cuisine { + name: String, + style: String, + rating: i32, +} + +impl Ord for Cuisine { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.rating + .cmp(&other.rating) + .then(other.name.cmp(&self.name)) + .then(self.style.cmp(&other.style)) + } +} + +impl PartialOrd for Cuisine { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +pub struct FoodRatings { + cuisines: HashMap, + max_heaps: HashMap>, +} + +impl FoodRatings { + pub fn new(foods: Vec, styles: Vec, ratings: Vec) -> Self { + let cuisines_iter = + foods + .iter() + .zip(styles.iter()) + .zip(ratings.iter()) + .map(|((name, style), rating)| Cuisine { + name: name.clone(), + style: style.clone(), + rating: *rating, + }); + + let mut max_heaps: HashMap> = HashMap::new(); + for cuisine in cuisines_iter.clone() { + if let Some(heap) = max_heaps.get_mut(&cuisine.style) { + heap.push(cuisine); + } else { + let mut heap = BinaryHeap::new(); + heap.push(cuisine.clone()); + max_heaps.insert(cuisine.style, heap); + } + } + + Self { + cuisines: HashMap::from_iter( + cuisines_iter.map(|cuisine| (cuisine.name.clone(), cuisine)), + ), + max_heaps: max_heaps, + } + } + + pub fn change_rating(&mut self, food_name: String, new_rating: i32) { + if let Some(cuisine) = self.cuisines.get_mut(&food_name) { + cuisine.rating = new_rating; + + if let Some(heap) = self.max_heaps.get_mut(&cuisine.style) { + heap.push(cuisine.clone()); + } + } + } + + pub fn highest_rated(&mut self, style: String) -> String { + let mut result = String::new(); + let heap = self.max_heaps.get_mut(&style).unwrap(); + + while let Some(highest) = heap.peek() { + if highest.rating + != self + .cuisines + .get(&highest.name) + .map(|cuisine| cuisine.rating) + .unwrap_or_default() + { + heap.pop(); + } else { + result = highest.name.clone(); + break; + } + } + + result + } +}