Last active
May 13, 2018 15:28
-
-
Save pixeldrew/748f4414cb7c461dcfef10a3b36b949f to your computer and use it in GitHub Desktop.
Answers for ML
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.interview.poker.solution; | |
import com.interview.poker.PokerHand; | |
import com.interview.poker.PokerHandEvaluator; | |
import com.interview.poker.card.Card; | |
import com.interview.poker.card.Card.Rank; | |
import java.util.*; | |
/** | |
* Provides a poker hand evaluator implementation. | |
*/ | |
public class PokerHandEvaluatorImpl implements PokerHandEvaluator { | |
/* (non-Javadoc) | |
* @see com.interview.poker.PokerHandEvaluator#evaluate(java.util.Collection) | |
*/ | |
public PokerHand evaluate(Collection<Card> hand) { | |
if (hand == null) { | |
throw new IllegalArgumentException("hand should not be empty"); | |
} | |
if (hand.size() != 5) { | |
throw new IllegalArgumentException("hand should be 5 cards"); | |
} | |
List<Card> handAsList = new ArrayList<Card>(hand); | |
if (this.isStraightFlush(handAsList)) { | |
return PokerHand.STRAIGHT_FLUSH; | |
} | |
if (this.isFourOfAKind(handAsList) != null) { | |
return PokerHand.FOUR_OF_A_KIND; | |
} | |
if (this.isFullHouse(handAsList)) { | |
return PokerHand.FULL_HOUSE; | |
} | |
if (this.isFlush(handAsList)) { | |
return PokerHand.FLUSH; | |
} | |
if (this.isStraight(handAsList)) { | |
return PokerHand.STRAIGHT; | |
} | |
if (this.isThreeOfAKind(handAsList) != null) { | |
return PokerHand.THREE_OF_A_KIND; | |
} | |
if (this.isTwoPair(handAsList)) { | |
return PokerHand.TWO_PAIR; | |
} | |
if (this.isSinglePair(handAsList) != null) { | |
return PokerHand.PAIR; | |
} | |
return PokerHand.NONE; | |
} | |
private Integer getAmountOfRank(Card card, Collection<Card> hand) { | |
Integer appearsInHand = 1; | |
for (Card aHand : hand) { | |
if (aHand != card && aHand.rank() == card.rank()) { | |
appearsInHand++; | |
} | |
} | |
return appearsInHand; | |
} | |
private Boolean isStraight(List<Card> hand) { | |
final List<Rank> ranks = Arrays.asList(Rank.values()); | |
Boolean straight = false; | |
Collections.sort(hand, new Comparator<Card>() { | |
public int compare(Card lhs, Card rhs) { | |
return ranks.indexOf(lhs.rank()) > ranks.indexOf(rhs.rank()) ? 1 : -1; | |
} | |
}); | |
for (int i = 0, rankIndex = ranks.indexOf(hand.get(0).rank()); i < hand.size(); i++, rankIndex++ ) { | |
Card card = hand.get(i); | |
if(ranks.get(rankIndex) == card.rank()) { | |
straight = true; | |
} else { | |
// Straight Low | |
if(i == hand.size() -1 && card.rank() == Rank.ACE && hand.get(0).rank() == Rank.DEUCE ) { | |
straight = true; | |
} else { | |
straight = false; | |
break; | |
} | |
} | |
if(rankIndex == 12) { | |
rankIndex = -1; | |
} | |
} | |
return straight; | |
} | |
private Boolean isStraightFlush(List<Card> hand) { | |
return this.isStraight(hand) && this.isFlush(hand); | |
} | |
private Boolean isTwoPair(List<Card> hand) { | |
ArrayList<Rank> hasTwoPair = new ArrayList<Rank>(); | |
Rank firstPair = null; | |
for (int i = 0; i < hand.size(); i++) { | |
if (this.getAmountOfRank(hand.get(i), hand) == 2 && (firstPair == null || firstPair != hand.get(i).rank())) { | |
hasTwoPair.add(hand.get(i).rank()); | |
firstPair = hand.get(i).rank(); | |
} | |
} | |
return hasTwoPair.size() == 2; | |
} | |
private Boolean isFlush(List<Card> hand) { | |
Boolean sameSuite = false; | |
Card firstCard = hand.get(0); | |
for (Card card : hand) { | |
if (card.suit() == firstCard.suit()) { | |
sameSuite = true; | |
} else { | |
sameSuite = false; | |
break; | |
} | |
} | |
return sameSuite; | |
} | |
private Rank isNofKind(Integer amount, List<Card> hand) { | |
Rank nOfKind = null; | |
for (int i = 0; i < hand.size(); i++) { | |
if (this.getAmountOfRank(hand.get(i), hand).equals(amount)) { | |
nOfKind = hand.get(i).rank(); | |
break; | |
} | |
} | |
return nOfKind; | |
} | |
private Rank isFourOfAKind(List<Card> hand) { | |
return this.isNofKind(4, hand); | |
} | |
private Rank isThreeOfAKind(List<Card> hand) { | |
return this.isNofKind(3, hand); | |
} | |
private Rank isSinglePair(List<Card> hand) { | |
return this.isNofKind(2, hand); | |
} | |
private Boolean isFullHouse(List<Card> hand) { | |
Rank threeOfAKind = this.isThreeOfAKind(hand); | |
Rank singlePair = this.isSinglePair(hand); | |
return threeOfAKind != null && singlePair != null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment