Problem · Design

Nested Recipe Cart Transactions

Learn this problem
HardDecagon logoDecagonFULLTIMEPHONE SCREEN

Problem statement

Implement a recipe cart with nested transactions. Parallel arrays describe a catalog of uniquely named recipes and the unique ingredients used by each recipe. Three more parallel arrays describe ingredient discount rules: a rule contributes its discountAmounts[i] exactly once whenever at least discountThresholds[i] recipes currently in the cart contain discountedIngredients[i].

The cart starts empty. Process operations in order:

  • ["add_recipe", recipeName] adds an absent recipe.
  • ["remove_recipe", recipeName] removes a present recipe.
  • ["get_total_discounts"] appends the current total discount to the answer.
  • ["begin"] opens a nested transaction scope.
  • ["commit"] commits the innermost active scope. Its changes become part of its parent scope when one exists.
  • ["abort"] discards every change made in the innermost active scope. If there is no active scope, it is a no-op.

An outer abort also discards changes from inner scopes that were committed into it. An inner abort leaves changes made before that inner begin visible. Discount queries always observe the current working cart state.

Return all get_total_discounts results in encounter order. Mutations and transaction-control operations produce no result.

Function

processCartTransactions(recipeNames: String[], recipeIngredients: String[][], discountedIngredients: String[], discountThresholds: int[], discountAmounts: int[], operations: String[][]) → int[]

Examples

Example 1

recipeNames = ["A","B","C"]recipeIngredients = [["Garlic"],["Garlic","Rice"],["Chicken"]]discountedIngredients = ["Garlic","Chicken"]discountThresholds = [2,1]discountAmounts = [4,3]operations = [["add_recipe","A"],["begin"],["add_recipe","B"],["get_total_discounts"],["abort"],["get_total_discounts"],["begin"],["add_recipe","C"],["commit"],["get_total_discounts"]]return = [4,0,3]

Adding B inside the first transaction makes the Garlic rule qualify, but abort restores the cart to just A. The second transaction commits C, so the Chicken rule contributes 3.

Example 2

recipeNames = ["A","B","C"]recipeIngredients = [["Garlic"],["Garlic"],["Chicken"]]discountedIngredients = ["Garlic","Chicken"]discountThresholds = [2,1]discountAmounts = [5,2]operations = [["add_recipe","A"],["begin"],["add_recipe","B"],["begin"],["add_recipe","C"],["get_total_discounts"],["commit"],["get_total_discounts"],["abort"],["get_total_discounts"]]return = [7,7,0]

The inner scope adds C, making both rules qualify. Committing it preserves that change inside the outer scope. Aborting the outer scope then discards both B and the committed inner change, leaving only A.

Example 3

recipeNames = ["A","B"]recipeIngredients = [["Chicken"],["Garlic"]]discountedIngredients = ["Chicken","Garlic"]discountThresholds = [1,1]discountAmounts = [2,3]operations = [["begin"],["add_recipe","A"],["begin"],["add_recipe","B"],["get_total_discounts"],["abort"],["get_total_discounts"],["commit"],["begin"],["remove_recipe","A"],["get_total_discounts"],["abort"],["get_total_discounts"],["abort"]]return = [5,2,0,2]

Aborting the inner scope removes only B. The outer commit keeps A. A later transaction temporarily removes A, then abort restores it; the final abort has no active scope and does nothing.

Constraints

  • 1 <= recipeNames.length == recipeIngredients.length <= 2000, and recipe names are unique non-empty strings.
  • 1 <= recipeIngredients[i].length <= 20; ingredients within one recipe are unique.
  • discountedIngredients.length == discountThresholds.length == discountAmounts.length <= 2000, and discounted ingredient names are unique and occur in the catalog.
  • 1 <= discountThresholds[i] <= recipeNames.length and 1 <= discountAmounts[i] <= 10^6; the sum of all discount amounts is at most 10^9.
  • 1 <= operations.length <= 2000, with maximum active transaction depth 100.
  • Every add names an absent known recipe, every remove names a present recipe, and every commit has an active transaction.
  • Every row has exactly the tag and arity shown in the statement, and at least one row is get_total_discounts.

More Decagon problems

drafts saved locally
public int[] processCartTransactions(String[] recipeNames, String[][] recipeIngredients, String[] discountedIngredients, int[] discountThresholds, int[] discountAmounts, String[][] operations) {
    // Write your code here.
}
recipeNames["A","B","C"]
recipeIngredients[["Garlic"],["Garlic","Rice"],["Chicken"]]
discountedIngredients["Garlic","Chicken"]
discountThresholds[2,1]
discountAmounts[4,3]
operations[["add_recipe","A"],["begin"],["add_recipe","B"],["get_total_discounts"],["abort"],["get_total_discounts"],["begin"],["add_recipe","C"],["commit"],["get_total_discounts"]]
expected[4,0,3]
checking account