import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Hand { private String input; private int score; public Hand(String hand) { this.input = hand; this.score = scoreHand(parseCards(hand)); } public int getScore() { return score; } public String getInput() { return input; } private List parseCards(String hand) { ArrayList parsedCards = new ArrayList(); String[] parseString = hand.split(" "); for (int i = 0; i < parseString.length; i++) { parsedCards.add(new Card(parseString[i])); } return parsedCards; } private Map getfrequencyMap(List cards) { Map frequencyMap = new HashMap(); for (Card c : cards) { if (frequencyMap.containsKey(c.getRank())) { frequencyMap.put(c.getRank(), frequencyMap.get(c.getRank()) + 1); } else { frequencyMap.put(c.getRank(), 1); } } return frequencyMap; } private int scoreHand(List cards) { List cardsByRank = cards.stream().sorted(Comparator.comparing(Card::getRank)).unordered() .collect(Collectors.toList()); Map frequencyMap = getfrequencyMap(cards); List ranks = frequencyMap.entrySet().stream().map(x -> x.getKey()).sorted(Comparator.reverseOrder()) .collect(Collectors.toList()); frequencyMap = frequencyMap.entrySet().stream().sorted(Map.Entry.comparingByValue(Collections.reverseOrder())) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); List rankCounts = frequencyMap.entrySet().stream().map(x -> x.getValue()).collect(Collectors.toList()); List suits = cards.stream().map(s -> s.getSuit()).collect(Collectors.toList()); return calculatedScore(frequencyMap, cardsByRank, ranks, rankCounts, suits); } private int calculatedScore(Map frequencyMap, List cardsByRank, List ranks, List rankCounts, List suits) { if (ranks.equals(Arrays.asList(14, 5, 4, 3, 2))) { ranks = Arrays.asList(5, 4, 3, 2, 1); } boolean flush = suits.stream().distinct().count() == 1; boolean straight = ranks.stream().distinct().count() == 5 && ranks.get(0) - ranks.get(4) == 4; Iterator iteratorOverFrequencies = frequencyMap.keySet().iterator(); int highestFrequency = iteratorOverFrequencies.next(); if (straight && flush) { return 800 + highestFrequency; } if (rankCounts.equals(Arrays.asList(4, 1))) { return 700 + cardsByRank.get(0).getRank(); } if (rankCounts.equals(Arrays.asList(3, 2))) { return 600 + cardsByRank.get(0).getRank(); } if (flush) { return 500 + highestFrequency; } if (straight) { return 400 + highestFrequency; } if (rankCounts.equals(Arrays.asList(3, 1, 1))) { return 300 + cardsByRank.get(0).getRank(); } if (rankCounts.equals(Arrays.asList(2, 2, 1))) { return 200 + Math.max(highestFrequency, iteratorOverFrequencies.next()); } if (rankCounts.equals(Arrays.asList(2, 1, 1, 1))) { return 100 + highestFrequency; } Collections.sort(ranks, (a, b) -> b.compareTo(a)); Collections.reverse(ranks); return ranks.get(0); } }