FastPrepRecipe Management System

Recipe Management System

Ramp logoRamp● HardFULLTIMEOA
Learn

Problem statement

Process an ordered sequence of operations for an in-memory recipe manager. Recipe IDs are assigned monotonically as recipe1, recipe2, and so on; deleted IDs are never reused. Return one string-list result for every operation.

Recipe Operations

  • ["ADD_RECIPE", name, ingredientsCsv, stepsCsv]: add a recipe when no current recipe has the same name case-insensitively. Return [recipeId], or an empty list on conflict.
  • ["GET_RECIPE", recipeId]: return [name, ingredientsCsv, stepsCsv], or an empty list when missing.
  • ["UPDATE_RECIPE", recipeId, name, ingredientsCsv, stepsCsv]: replace all fields, subject to the same name rule. Return ["true"] on success and ["false"] otherwise. Every successful update appends a version whose editor is system.
  • ["DELETE_RECIPE", recipeId]: delete the recipe and return a one-element lowercase boolean list.

Search and Users

  • ["SEARCH_INGREDIENT", ingredient]: return IDs containing that exact ingredient case-insensitively, ordered by ingredient count ascending and then numeric recipe ID ascending.
  • ["LIST_RECIPES", sortBy]: return all current IDs. For ingredient_count, sort by ingredient count and numeric ID. For name, or an unsupported value, sort by case-insensitive name and numeric ID.
  • ["ADD_USER", userId]: add a case-sensitive user and return a one-element lowercase boolean list.
  • ["EDIT_RECIPE", userId, recipeId, name, ingredientsCsv, stepsCsv]: let any existing user edit any current recipe, subject to name uniqueness. A success appends a version whose editor is userId. Return a one-element lowercase boolean list.

Version History

  • A newly added recipe has no history. Each successful UPDATE_RECIPE, EDIT_RECIPE, or rollback appends the complete post-operation state as the next version, starting at version 1.
  • ["VERSION_RECIPE", recipeId]: return every version in ascending order, formatted as version:name:ingredientsCsv:stepsCsv:lastEditedBy. Return an empty list when the recipe is missing or has never been edited.
  • ["ROLLBACK_RECIPE", recipeId, version]: restore the name, ingredients, and steps from an existing version. The old history stays immutable and the restored state is appended as a new version whose editor is rollback. Return ["false"] for a missing recipe or version, or when the restored name conflicts with another current recipe.

Runner Interface

manageRecipes accepts String[][] operations and returns String[][].

Function

manageRecipes(operations: String[][]) → String[][]

Examples

Example 1

operations = [["ADD_RECIPE","Pancakes","Flour,Egg,Milk","Mix,Cook"],["ADD_RECIPE","Salad","Lettuce,Tomato","Chop,Toss"],["GET_RECIPE","recipe1"],["SEARCH_INGREDIENT","egg"],["LIST_RECIPES","name"]]return = [["recipe1"],["recipe2"],["Pancakes","Flour,Egg,Milk","Mix,Cook"],["recipe1"],["recipe1","recipe2"]]

The ingredient lookup is case-insensitive, so egg finds recipe1. Name order places Pancakes before Salad.

Example 2

operations = [["ADD_RECIPE","Soup","Water,Carrot","Boil,Serve"],["ADD_RECIPE","sOuP","Stock","Heat"],["UPDATE_RECIPE","recipe1","Stew","Potato,Beef,Carrot","Brown,Simmer"],["GET_RECIPE","recipe1"],["DELETE_RECIPE","recipe9"],["DELETE_RECIPE","recipe1"],["GET_RECIPE","recipe1"]]return = [["recipe1"],[],["true"],["Stew","Potato,Beef,Carrot","Brown,Simmer"],["false"],["true"],[]]

The second add conflicts with Soup case-insensitively. Updating changes every stored field; deletion releases the name but never reuses the ID.

Example 3

operations = [["ADD_RECIPE","Beta","X,Y","One,Two"],["ADD_RECIPE","Alpha","Z","Only"],["ADD_USER","chef"],["ADD_USER","chef"],["EDIT_RECIPE","missing","recipe1","Nope","X","Only"],["EDIT_RECIPE","chef","recipe1","Gamma","X","Only"],["LIST_RECIPES","ingredient_count"],["LIST_RECIPES","unsupported"]]return = [["recipe1"],["recipe2"],["true"],["false"],["false"],["true"],["recipe1","recipe2"],["recipe2","recipe1"]]

Only an existing user can edit. After the edit, both recipes have one ingredient, so numeric ID breaks that tie. The unsupported sort key defaults to name order.

Example 4

operations = [["ADD_RECIPE","Soup","Water,Carrot","Boil,Serve"],["VERSION_RECIPE","recipe1"],["UPDATE_RECIPE","recipe1","Stew","Carrot,Potato","Chop,Simmer"],["ADD_USER","chef"],["EDIT_RECIPE","chef","recipe1","Curry","Spice,Potato","Toast,Simmer"],["VERSION_RECIPE","recipe1"],["ROLLBACK_RECIPE","recipe1","1"],["GET_RECIPE","recipe1"],["VERSION_RECIPE","recipe1"]]return = [["recipe1"],[],["true"],["true"],["true"],["1:Stew:Carrot,Potato:Chop,Simmer:system","2:Curry:Spice,Potato:Toast,Simmer:chef"],["true"],["Stew","Carrot,Potato","Chop,Simmer"],["1:Stew:Carrot,Potato:Chop,Simmer:system","2:Curry:Spice,Potato:Toast,Simmer:chef","3:Stew:Carrot,Potato:Chop,Simmer:rollback"]]

The initial add creates no version. The system update and user edit create versions 1 and 2. Rolling back to version 1 restores Stew and appends version 3 without changing the earlier entries.

Constraints

  • 1 <= operations.length <= 10^4.
  • Every operation has a documented opcode and exact arity.
  • Names, user IDs, ingredients, and steps contain printable ASCII characters. Names and user IDs are non-empty.
  • Ingredient and step elements are non-empty, contain no commas or colons, have length at most 100, and each CSV has at most 100 elements.
  • Recipe-name equality and ordering and ingredient matching are case-insensitive. User IDs are case-sensitive.
  • A rollback version is a canonical positive decimal integer that fits in a signed 32-bit integer.

More Ramp problems

See Ramp hiring insights
public String[][] manageRecipes(String[][] operations) {
  // write your code here
}
operations[["ADD_RECIPE","Pancakes","Flour,Egg,Milk","Mix,Cook"],["ADD_RECIPE","Salad","Lettuce,Tomato","Chop,Toss"],["GET_RECIPE","recipe1"],["SEARCH_INGREDIENT","egg"],["LIST_RECIPES","name"]]
expected[["recipe1"], ["recipe2"], ["Pancakes", "Flour,Egg,Milk", "Mix,Cook"], ["recipe1"], ["recipe1", "recipe2"]]
Checking account…