Track Dish Ratings and Report the Top-Rated Dish in Each Cuisine

Quick Overview

Maintain ratings for dishes that each belong to one cuisine, apply rating changes, and report the highest-rated dish in a cuisine, breaking ties by the alphabetically smallest name. It tests choosing data structures that keep per-cuisine maximum queries fast while ratings keep changing.

Track Dish Ratings and Report the Top-Rated Dish in Each Cuisine

Company: Apple

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

A rating tracker keeps a rating for every dish on a menu, and each dish belongs to exactly one cuisine. Ratings change over time, and at any moment the tracker must report the highest-rated dish within a given cuisine. In the interview this was written as a class (a constructor, a method that changes a rating, and a method that reports the top dish of a cuisine) together with the candidate's own test cases; here the class is driven by a single function that replays a list of operations. ### Function Signature ```python def run_dish_ratings(foods: list[str], cuisines: list[str], ratings: list[int], operations: list[list[str]]) -> list[str]: ``` ### Rules - Dish `foods[i]` belongs to cuisine `cuisines[i]` and starts with rating `ratings[i]`. A dish's cuisine never changes. - The operations are applied in order. Each one is either: - `["change", food, new_rating]`: set the rating of dish `food` to the integer written in decimal in the string `new_rating`. Setting a dish to its current rating is allowed and changes nothing. - `["highest", cuisine]`: report the name of the dish in `cuisine` with the highest current rating. If several dishes share that rating, report the name that is smallest in lexicographic order: compare character by character, and a name that is a proper prefix of another comes first, so `"pie"` comes before `"pierogi"`. - Return the reports of all `"highest"` operations, in the order those operations appear. Return an empty list if there are none. ### Constraints - `1 <= len(foods) <= 2 * 10^4`, and `len(cuisines) == len(ratings) == len(foods)` - Every dish name and cuisine name has 1 to 10 lowercase English letters. Dish names are distinct; many dishes can share a cuisine. - `1 <= ratings[i] <= 10^9`. Every `new_rating` is the decimal string of an integer in the same range, with no sign and no leading zeros. - `1 <= len(operations) <= 2 * 10^4` - Every `"change"` names a dish in `foods`, and every `"highest"` names a cuisine that appears in `cuisines`. - All values fit in a 32-bit signed integer. ### Examples **Example 1** ```text Input: foods = ["tacos", "pho", "burrito", "ramen", "nachos"] cuisines = ["mexican", "vietnamese", "mexican", "japanese", "mexican"] ratings = [7, 9, 8, 6, 8] operations = [["highest", "mexican"], ["change", "tacos", "10"], ["highest", "mexican"], ["change", "tacos", "5"], ["highest", "mexican"], ["change", "burrito", "3"], ["highest", "mexican"], ["highest", "japanese"]] Output: ["burrito", "tacos", "burrito", "nachos", "ramen"] ``` The Mexican dishes start at tacos 7, burrito 8 and nachos 8, and the tie at 8 goes to `"burrito"`. Tacos then rises to 10 and leads. After it drops to 5, burrito and nachos tie at 8 again and `"burrito"` wins. After burrito drops to 3, nachos leads with 8. Ramen is the only Japanese dish. **Example 2** ```text Input: foods = ["pierogi", "pie"] cuisines = ["comfort", "comfort"] ratings = [5, 5] operations = [["highest", "comfort"], ["change", "pierogi", "6"], ["highest", "comfort"], ["change", "pie", "6"], ["highest", "comfort"]] Output: ["pie", "pierogi", "pie"] ``` `"pie"` is a proper prefix of `"pierogi"`, so it wins both ties; in between, pierogi leads alone with 6.

Overview: Maintain ratings for dishes that each belong to one cuisine, apply rating changes, and report the highest-rated dish in a cuisine, breaking ties by the alphabetically smallest name. It tests choosing data structures that keep per-cuisine maximum queries fast while ratings keep changing.

Apple logo
Apple
Oct 20, 2026
mediumSoftware EngineerTechnical ScreenCoding & Algorithms
0
0

A rating tracker keeps a rating for every dish on a menu, and each dish belongs to exactly one cuisine. Ratings change over time, and at any moment the tracker must report the highest-rated dish within a given cuisine. In the interview this was written as a class (a constructor, a method that changes a rating, and a method that reports the top dish of a cuisine) together with the candidate's own test cases; here the class is driven by a single function that replays a list of operations.

Function Signature

def run_dish_ratings(foods: list[str], cuisines: list[str], ratings: list[int], operations: list[list[str]]) -> list[str]:

Rules

  • Dish foods[i] belongs to cuisine cuisines[i] and starts with rating ratings[i] . A dish's cuisine never changes.
  • The operations are applied in order. Each one is either:
    • ["change", food, new_rating] : set the rating of dish food to the integer written in decimal in the string new_rating . Setting a dish to its current rating is allowed and changes nothing.
    • ["highest", cuisine] : report the name of the dish in cuisine with the highest current rating. If several dishes share that rating, report the name that is smallest in lexicographic order: compare character by character, and a name that is a proper prefix of another comes first, so "pie" comes before "pierogi" .
  • Return the reports of all "highest" operations, in the order those operations appear. Return an empty list if there are none.

Constraints

  • 1 <= len(foods) <= 2 * 10^4 , and len(cuisines) == len(ratings) == len(foods)
  • Every dish name and cuisine name has 1 to 10 lowercase English letters. Dish names are distinct; many dishes can share a cuisine.
  • 1 <= ratings[i] <= 10^9 . Every new_rating is the decimal string of an integer in the same range, with no sign and no leading zeros.
  • 1 <= len(operations) <= 2 * 10^4
  • Every "change" names a dish in foods , and every "highest" names a cuisine that appears in cuisines .
  • All values fit in a 32-bit signed integer.

Examples

Example 1

Input:  foods      = ["tacos", "pho", "burrito", "ramen", "nachos"]
        cuisines   = ["mexican", "vietnamese", "mexican", "japanese", "mexican"]
        ratings    = [7, 9, 8, 6, 8]
        operations = [["highest", "mexican"], ["change", "tacos", "10"],
                      ["highest", "mexican"], ["change", "tacos", "5"],
                      ["highest", "mexican"], ["change", "burrito", "3"],
                      ["highest", "mexican"], ["highest", "japanese"]]
Output: ["burrito", "tacos", "burrito", "nachos", "ramen"]

The Mexican dishes start at tacos 7, burrito 8 and nachos 8, and the tie at 8 goes to "burrito". Tacos then rises to 10 and leads. After it drops to 5, burrito and nachos tie at 8 again and "burrito" wins. After burrito drops to 3, nachos leads with 8. Ramen is the only Japanese dish.

Example 2

Input:  foods      = ["pierogi", "pie"]
        cuisines   = ["comfort", "comfort"]
        ratings    = [5, 5]
        operations = [["highest", "comfort"], ["change", "pierogi", "6"],
                      ["highest", "comfort"], ["change", "pie", "6"],
                      ["highest", "comfort"]]
Output: ["pie", "pierogi", "pie"]

"pie" is a proper prefix of "pierogi", so it wins both ties; in between, pierogi leads alone with 6.