Quick Overview

This question evaluates a candidate's skills in relational data joining, data integration, and numeric reconciliation for mapping userId to customerName across multiple tables.

Join tables to map userId to name

Company: Karat

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

## Problem You are given three tables represented as **2D string arrays** (each row is a record, no headers). You need to produce a mapping from **`userId` → `customerName`** by matching and joining information across tables. ### Table 1: `customers` Each row: `[customerName, email, productName, quantity]` - `quantity` is an integer in string form. - Assumption: **each customer buys only one type of product** (i.e., one `productName` per customer). ### Table 2: `orders` Each row: `[userId, email, orderTotal]` - `orderTotal` is a number in string form (integer or decimal). - `email` **may be null** (or an empty string, depending on how the input is represented). ### Table 3: `products` Each row: `[productName, unitPrice]` - `unitPrice` is a number in string form. ## Matching / Join requirement For each `order` record, identify which customer placed it, then output `userId -> customerName`. Use these matching rules: 1. If `orders.email` is present (non-null/non-empty), match the customer by **email**. 2. If `orders.email` is missing, match by using the fact that: - `orderTotal = quantity * unitPrice` for the customer’s purchased product. - Use `customers.productName` joined to `products.productName` to get `unitPrice`. ## Output Return a mapping/dictionary from `userId` to `customerName` for all orders. ## Assumptions / Edge cases - If multiple customers could match an order (e.g., same computed total), specify and implement a deterministic tie-breaker (e.g., pick lexicographically smallest name) or return all candidates—clarify with the interviewer. - Assume inputs are well-formed aside from possible null/empty emails.

Quick Answer: This question evaluates a candidate's skills in relational data joining, data integration, and numeric reconciliation for mapping userId to customerName across multiple tables.

You are given three tables represented as 2D arrays of strings (each inner list is a row, with no headers). Your task is to build a mapping from each order's `userId` to the corresponding `customerName` by joining information across the tables. Tables: 1) `customers`: each row is `[customerName, email, productName, quantity]` - `quantity` is an integer represented as a string. - Each customer buys exactly one product type (one `productName` per customer). 2) `orders`: each row is `[userId, email, orderTotal]` - `orderTotal` is a number represented as a string (may be integer or decimal). - `email` may be missing, represented as `None` or an empty string `""`. 3) `products`: each row is `[productName, unitPrice]` - `unitPrice` is a number represented as a string. Matching rules for each order: 1) If `orders.email` is present (not `None` and not empty) and matches one or more customer emails, match by email. 2) Otherwise, match by total price using: `orderTotal = quantity * unitPrice`, where `unitPrice` is looked up via `customers.productName` joined with `products.productName`. Ambiguity / tie-breaker: - If multiple customers match by email or by computed total, return the lexicographically smallest `customerName` among the matches. Return a dictionary mapping `userId` (string) to `customerName` (string) for all orders.

Constraints

  • 1 <= len(customers), len(orders), len(products) <= 100000
  • quantity is an integer string that fits in 32-bit signed range
  • unitPrice and orderTotal are valid numeric strings (integer or decimal)
  • orders.email may be None or ""
  • If multiple customers match, choose the lexicographically smallest customerName
  • Inputs are well-formed so that each order can be matched by email or by total

Examples

Input: ([['Alice','a@x.com','Book','2'],['Bob','b@x.com','Pen','5']], [['u1','a@x.com','20'],['u2',None,'10']], [['Book','10'],['Pen','2']])

Expected Output: {'u1': 'Alice', 'u2': 'Bob'}

Explanation: u1 matches by email -> Alice. u2 has no email, total 10 matches Bob because 5*2=10.

Input: ([['Amy','amy@mail','Widget','1'],['Zoe','zoe@mail','Widget','1'],['Bob','bob@mail','Gadget','2']], [['1',None,'9.99'],['2','','9.99'],['3',None,'9.990'],['4','bob@mail','10']], [['Widget','9.99'],['Gadget','5']])

Expected Output: {'1': 'Amy', '2': 'Amy', '3': 'Amy', '4': 'Bob'}

Explanation: Orders 1-3 match by total 9.99; both Amy and Zoe match, pick lexicographically smallest -> Amy. Order 4 matches by email -> Bob.

Loading coding console...