Design a Camel Cards hand evaluator and find best and worst completions

Read the full interview experience this question came from →

Quick Overview

Model five-card Camel Cards hands with an abstract hand type class and a hand class, compare two hands by type and tie-break, then find the best and worst complete hands consistent with a partial hand. Tests object-oriented design, classification logic and step-by-step complexity analysis.

Design a Camel Cards hand evaluator and find best and worst completions

Company: Rippling

Role: Software Engineer

Category: Software Engineering Fundamentals

Difficulty: medium

Interview Round: Technical Screen

Camel Cards is played with hands of exactly five cards. Every hand belongs to exactly one of seven hand types, and each type has a fixed weight. From strongest to weakest: 1. Five of a kind: all five cards have the same label. 2. Four of a kind: four cards share a label. 3. Full house: three cards share one label and the other two share another. 4. Three of a kind: three cards share a label, and the other two differ from it and from each other. 5. Two pair: two cards share one label, two others share a second label, and the fifth card is different. 6. One pair: exactly two cards share a label, and the other three are all different. 7. High card: all five labels are different. There is no limit on how many cards of one label a hand may hold, so five of a kind is possible. You will design classes for hands and hand types, implement a comparison between two hands, and then handle hands with missing cards. ### Constraints and Clarifications - A complete hand always has exactly five cards. - A stronger hand type always beats a weaker one, whatever the labels. - In Part 2 the interviewer accepted a brute-force solution, and a careful time-complexity analysis is part of the expected answer. ### Clarifying Questions - What is the full set of card labels, and in what order do they rank? The example in Part 2 uses digit labels and includes `1`, so confirm which label is lowest. - When two hands have the same type, how is the tie broken: card by card in the order the cards were dealt, or by comparing the largest group first (for example, the three-of-a-kind label of a full house before its pair)? - What should `evaluate` return: the stronger hand, or a negative, zero or positive comparison result? Can two hands rank exactly equal? - How should malformed input, such as four cards or an unknown label, be reported? ### Part 1 — Model hands and compare two of them Create an abstract class `HandType` and a class `Hand`. Decide which fields each holds and which methods each exposes, then implement `evaluate(hand_1, hand_2)`, which decides which of two hands is stronger. Explain the design before writing code, and state the complexity of building a hand and of one comparison. ```hint Count once All seven types can be recognized from how many cards share each label. Decide which object computes those counts, and when, so that classification and comparison do not repeat the work. ``` #### What This Part Should Cover - What `HandType` abstracts (a name, a weight and a matching rule) and how the seven concrete types plug into it - How `Hand` stores its cards and determines its type once - A comparison by type weight first and a stated tie-break rule second - Input validation, and the cost of building and comparing hands ### Part 2 — Best and worst completions of a partial hand Some of a hand's cards are missing. Given the known cards, return `best_hand`, the strongest complete five-card hand that contains all of them, and `worst_hand`, the weakest. For example, if only `99` is known, the best hand is `99999` and the worst is `99321`. The interviewer said a brute-force approach is fine. Implement it, and break its time complexity down step by step. ```hint Count the candidates Work out how many ways the missing cards can be filled, then multiply by the cost of building and comparing one candidate. Express the result in terms of the number of labels and the number of missing cards. ``` #### Clarifying Questions for this Part - Do known cards keep fixed positions in the hand, or is a hand just a collection of cards whose order does not matter? - Can no cards be known at all, and what should happen if more than five are given? - If several completions tie for best or worst, which one should be returned? #### What This Part Should Cover - A brute-force enumeration that reuses the Part 1 classes and comparison - A step-by-step complexity breakdown, and the reason it is polynomial for a fixed hand size - How the answer depends on the tie-break rule and on whether positions are fixed - Whether a direct construction can replace enumeration, and what it would need to prove ### What a Strong Answer Covers - An object model in which adding, removing or reordering a hand type touches one place - Correct classification at the boundaries: full house versus three of a kind, and two pair versus one pair - A tie-break rule that is confirmed up front and applied the same way in both parts - Complexity analysis that keeps the fixed hand size separate from the number of labels - A clear explanation of the design before any code is written ### Follow-up Questions - Add a wildcard label that counts as any label when the type is determined but ranks lowest in tie-breaks. What changes in type matching and in Part 2? - Sort 1,000 hands from weakest to strongest. How do you reuse `evaluate`, and what does the whole sort cost? - If a hand had `H` cards instead of five, how would the brute force in Part 2 grow with `H`, and would it still be polynomial?

Overview: Model five-card Camel Cards hands with an abstract hand type class and a hand class, compare two hands by type and tie-break, then find the best and worst complete hands consistent with a partial hand. Tests object-oriented design, classification logic and step-by-step complexity analysis.

Read the full Rippling Software Engineer interview experience this question came from

|Home/Software Engineering Fundamentals/Rippling
Rippling logo
Rippling
Sep 14, 2026
mediumSoftware EngineerTechnical ScreenSoftware Engineering Fundamentals
0
0

Camel Cards is played with hands of exactly five cards. Every hand belongs to exactly one of seven hand types, and each type has a fixed weight. From strongest to weakest:

  1. Five of a kind: all five cards have the same label.
  2. Four of a kind: four cards share a label.
  3. Full house: three cards share one label and the other two share another.
  4. Three of a kind: three cards share a label, and the other two differ from it and from each other.
  5. Two pair: two cards share one label, two others share a second label, and the fifth card is different.
  6. One pair: exactly two cards share a label, and the other three are all different.
  7. High card: all five labels are different.

There is no limit on how many cards of one label a hand may hold, so five of a kind is possible. You will design classes for hands and hand types, implement a comparison between two hands, and then handle hands with missing cards.

Constraints and Clarifications

  • A complete hand always has exactly five cards.
  • A stronger hand type always beats a weaker one, whatever the labels.
  • In Part 2 the interviewer accepted a brute-force solution, and a careful time-complexity analysis is part of the expected answer.

Clarifying Questions Guidance

  • What is the full set of card labels, and in what order do they rank? The example in Part 2 uses digit labels and includes 1 , so confirm which label is lowest.
  • When two hands have the same type, how is the tie broken: card by card in the order the cards were dealt, or by comparing the largest group first (for example, the three-of-a-kind label of a full house before its pair)?
  • What should evaluate return: the stronger hand, or a negative, zero or positive comparison result? Can two hands rank exactly equal?
  • How should malformed input, such as four cards or an unknown label, be reported?

Part 1 — Model hands and compare two of them

Create an abstract class HandType and a class Hand. Decide which fields each holds and which methods each exposes, then implement evaluate(hand_1, hand_2), which decides which of two hands is stronger. Explain the design before writing code, and state the complexity of building a hand and of one comparison.

What This Part Should Cover Guidance

  • What HandType abstracts (a name, a weight and a matching rule) and how the seven concrete types plug into it
  • How Hand stores its cards and determines its type once
  • A comparison by type weight first and a stated tie-break rule second
  • Input validation, and the cost of building and comparing hands

Part 2 — Best and worst completions of a partial hand

Some of a hand's cards are missing. Given the known cards, return best_hand, the strongest complete five-card hand that contains all of them, and worst_hand, the weakest. For example, if only 99 is known, the best hand is 99999 and the worst is 99321. The interviewer said a brute-force approach is fine. Implement it, and break its time complexity down step by step.

Clarifying Questions for this Part Guidance

  • Do known cards keep fixed positions in the hand, or is a hand just a collection of cards whose order does not matter?
  • Can no cards be known at all, and what should happen if more than five are given?
  • If several completions tie for best or worst, which one should be returned?

What This Part Should Cover Guidance

  • A brute-force enumeration that reuses the Part 1 classes and comparison
  • A step-by-step complexity breakdown, and the reason it is polynomial for a fixed hand size
  • How the answer depends on the tie-break rule and on whether positions are fixed
  • Whether a direct construction can replace enumeration, and what it would need to prove

What a Strong Answer Covers Guidance

  • An object model in which adding, removing or reordering a hand type touches one place
  • Correct classification at the boundaries: full house versus three of a kind, and two pair versus one pair
  • A tie-break rule that is confirmed up front and applied the same way in both parts
  • Complexity analysis that keeps the fixed hand size separate from the number of labels
  • A clear explanation of the design before any code is written

Follow-up Questions Guidance

  • Add a wildcard label that counts as any label when the type is determined but ranks lowest in tie-breaks. What changes in type matching and in Part 2?
  • Sort 1,000 hands from weakest to strongest. How do you reuse evaluate , and what does the whole sort cost?
  • If a hand had H cards instead of five, how would the brute force in Part 2 grow with H , and would it still be polynomial?
Loading comments...