Quick Overview

This question evaluates API and system design, configurable string processing and state management for a logger (including search and complexity considerations), as well as algorithmic reasoning for card-hand ranking, sorting, and tie-breaking logic.

Implement logger and card ranking

Company: Rippling

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Onsite

This coding round contains two independent implementation tasks. ### Task A: Implement a configurable logger Implement a `Logger` component that accepts text messages and supports the following independently configurable behaviors: 1. Remove all occurrences of a configured substring before output. 2. Truncate the message to at most a configured maximum number of characters before output. 3. Convert the entire message to uppercase before output. 4. Store messages in an internal list without printing them. Requirements: - Design a clear API for enabling, disabling, and configuring these behaviors. - When multiple transformations are enabled, define and document the order in which they are applied. - Define behavior for edge cases such as an empty removal string, a negative truncation length, `null` or empty input, and repeated calls. - The stored value should be the transformed message unless you explicitly document another choice. - Add a `search(query)` feature for stored messages. It should return all stored messages containing the query string. Discuss whether search is case-sensitive, the expected time complexity, and how you would optimize it if the number of stored messages became large. ### Task B: Rank custom five-card hands Implement a program that ranks five-card hands in a simplified card game. Input: - A list of records. Each record contains a five-character hand and an integer bid. - Card ranks from lowest to highest are: `2 3 4 5 6 7 8 9 T J Q K A`. Hand categories from weakest to strongest are: 1. High card 2. One pair 3. Two pair 4. Three of a kind 5. Full house 6. Four of a kind 7. Five of a kind Comparison rules: - A hand with a stronger category wins. - If two hands have the same category, compare their cards from left to right using the rank order above. - Sort all hands from weakest to strongest. - The total score is the sum over all sorted hands of `1-based_rank * bid`. Extension if time allows: - Add a wildcard mode where `J` can represent any rank that maximizes the hand category, while still being treated as the lowest card for left-to-right tie breaking.

Quick Answer: This question evaluates API and system design, configurable string processing and state management for a logger (including search and complexity considerations), as well as algorithmic reasoning for card-hand ranking, sorting, and tie-breaking logic.

Part 1: Simulate a Configurable Logger

Implement a logger simulator that processes a list of command strings. The logger supports four configurable behaviors: 1. Remove all occurrences of a configured substring. 2. Truncate the message to at most a configured maximum length. 3. Convert the entire message to uppercase. 4. Store transformed messages internally for later searching. Default state: - removal is disabled - truncation is disabled - uppercase is disabled - storing is disabled Commands: - SET_REMOVE <text> : enable substring removal using <text>. If <text> is omitted, the removal string becomes the empty string. - CLEAR_REMOVE : disable substring removal. - SET_TRUNCATE <k> : enable truncation with integer k. If k is negative, treat it as 0. - CLEAR_TRUNCATE : disable truncation. - SET_UPPERCASE 1 or SET_UPPERCASE 0 : enable or disable uppercase conversion. - SET_STORE 1 or SET_STORE 0 : enable or disable storing. - LOG <message> : transform the message and produce output. - SEARCH <query> : return all stored transformed messages containing query as a substring. Transformation order for LOG is always: 1. remove substring 2. truncate 3. uppercase Edge rules: - A LOG command with no message means the empty string. - The special message token <NULL> should be treated as null input, which becomes the empty string. - An empty removal string does nothing. - SEARCH is case-sensitive. - Stored values are the transformed messages. Return a list containing one entry for each LOG or SEARCH command: - LOG contributes [transformed_message] - SEARCH contributes the list of matching stored messages in insertion order A naive SEARCH that scans all stored messages is acceptable. In a follow-up, you could discuss faster search with an index or suffix-based structure if the stored history becomes very large.

Constraints

  • 1 <= len(commands) <= 20000
  • Each command is one of the formats described above
  • Total length of all command strings is at most 200000
  • SEARCH should be implemented case-sensitively

Examples

Input: ["SET_REMOVE ab", "SET_TRUNCATE 5", "SET_UPPERCASE 1", "SET_STORE 1", "LOG xxababy", "SEARCH Y"]

Expected Output: [["XXY"], ["XXY"]]

Explanation: After removal, truncation, and uppercase, 'xxababy' becomes 'XXY'. It is stored, and SEARCH Y finds it.

Input: ["SET_REMOVE", "SET_TRUNCATE -3", "LOG <NULL>", "SET_STORE 1", "LOG abcdef", "SEARCH"]

Expected Output: [[""], [""], [""]]

Explanation: Empty removal does nothing. Negative truncation becomes 0. '<NULL>' is treated as empty input. SEARCH with no query uses the empty string, so it matches every stored message.

Hints

  1. Keep four pieces of mutable state: removal substring, truncation length, uppercase flag, and store flag.
  2. Be careful with edge cases: empty removal string should not loop forever, and negative truncation should behave like length 0.

Part 2: Rank Custom Five-Card Hands

You are given a list of records for a simplified five-card game. Each record is a string in the form 'HAND BID', where HAND is exactly 5 characters and BID is an integer. Card ranks from weakest to strongest are: 2 3 4 5 6 7 8 9 T J Q K A Hand categories from weakest to strongest are: 1. High card 2. One pair 3. Two pair 4. Three of a kind 5. Full house 6. Four of a kind 7. Five of a kind Comparison rules: - A stronger category always wins. - If two hands have the same category, compare their cards from left to right using the rank order above. - Do not reorder cards inside a hand. Sort all hands from weakest to strongest. If a hand ends up in 1-based position i in this sorted order, it contributes i * bid to the total score. Return the total score.

Constraints

  • 1 <= len(records) <= 100000
  • Each HAND has length exactly 5
  • HAND contains only characters from 23456789TJQKA
  • 0 <= BID <= 10^9
  • Use 64-bit arithmetic in languages that need it

Examples

Input: ["32T3K 765", "T55J5 684", "KK677 28", "KTJJT 220", "QQQJA 483"]

Expected Output: 6440

Explanation: This is the standard sample for the non-wildcard rules.

Input: ["AAAAA 10"]

Expected Output: 10

Explanation: Edge case: a single hand always has rank 1.

Hints

  1. A hand's category depends only on the frequency counts of its 5 cards.
  2. For sorting, build a key like (category_strength, rank_of_card_1, rank_of_card_2, ..., rank_of_card_5).

Part 3: Rank Five-Card Hands with Wildcard Jokers

This problem uses the same game and scoring rules as Part 2, but with one change: Wildcard mode: - 'J' acts as a wildcard that can represent any rank when determining the best possible hand category. - However, for left-to-right tie breaking, the original hand is still compared as written, and 'J' is treated as the weakest card. Tie-break rank order in wildcard mode is therefore: J 2 3 4 5 6 7 8 9 T Q K A Examples: - 'T55J5' can become four of a kind. - 'JJJJJ' is five of a kind. - If two hands both become the same category, compare the original 5-character strings left to right using the wildcard tie-break order above. Input records are strings in the form 'HAND BID'. Sort all hands from weakest to strongest under these wildcard rules, then return the total score: sum of 1-based_rank * bid.

Constraints

  • 1 <= len(records) <= 100000
  • Each HAND has length exactly 5
  • HAND contains only characters from 23456789TJQKA
  • 0 <= BID <= 10^9
  • Use 64-bit arithmetic in languages that need it

Examples

Input: ["32T3K 765", "T55J5 684", "KK677 28", "KTJJT 220", "QQQJA 483"]

Expected Output: 5905

Explanation: This is the standard sample for wildcard mode.

Input: ["JJJJJ 7"]

Expected Output: 7

Explanation: Edge case: all jokers become five of a kind, and the only hand gets rank 1.

Hints

  1. Separate the number of J cards from the counts of the other ranks. If the hand is all J, it is automatically five of a kind.
  2. To maximize only the category, it is enough to add all jokers to the largest existing group. But for tie breaking, use the original hand with J as the lowest rank.

Loading coding console...