Skip to content

Commit 95a6714

Browse files
committed
Changeing reference answer for poker exercise
1 parent 447c97f commit 95a6714

File tree

3 files changed

+56
-153
lines changed

3 files changed

+56
-153
lines changed

exercises/practice/poker/.meta/src/reference/java/Card.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
class Card {
2-
private int rank;
3-
private int suit;
2+
private final int rank;
3+
private final int suit;
44

55
Card(String card) {
6-
rank = parseRank(card);
7-
suit = parseSuit(card);
6+
this.rank = parseRank(card);
7+
this.suit = parseSuit(card);
88
}
99

1010
int getRank() {
@@ -16,9 +16,7 @@ int getSuit() {
1616
}
1717

1818
private int parseRank(String card) {
19-
if (card.substring(0, 2).equals("10")) {
20-
return 10;
21-
}
19+
if (card.startsWith("10")) return 10;
2220
return "..23456789TJQKA".indexOf(card.charAt(0));
2321
}
2422

exercises/practice/poker/.meta/src/reference/java/Hand.java

Lines changed: 37 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -2,147 +2,56 @@
22
import java.util.stream.Collectors;
33

44
class Hand {
5-
private String input;
6-
private int score;
5+
private final String original;
6+
private final List<Card> cards;
77

88
Hand(String hand) {
9-
this.input = hand;
10-
this.score = scoreHand(parseCards(hand));
9+
this.original = hand;
10+
this.cards = parseCards(hand);
1111
}
1212

13-
int getScore() {
14-
return score;
13+
String getOriginal() {
14+
return original;
1515
}
1616

17-
String getInput() {
18-
return input;
19-
}
17+
int calculateScore() {
18+
Map<Integer, Long> rankFrequency = cards.stream()
19+
.collect(Collectors.groupingBy(Card::getRank, Collectors.counting()));
2020

21-
private List<Card> parseCards(String hand) {
22-
ArrayList<Card> parsedCards = new ArrayList<>();
23-
String[] cardsToParse = hand.split(" ");
24-
for (String cardToParse : cardsToParse) {
25-
parsedCards.add(new Card(cardToParse));
26-
}
27-
return parsedCards;
28-
}
21+
List<Integer> ranks = rankFrequency.keySet().stream()
22+
.sorted(Comparator.reverseOrder())
23+
.collect(Collectors.toList());
2924

30-
private Map<Integer, Integer> getFrequencyMap(List<Card> cards) {
31-
Map<Integer, Integer> frequencyMap = new HashMap<>();
32-
for (Card c : cards) {
33-
if (frequencyMap.containsKey(c.getRank())) {
34-
frequencyMap.put(c.getRank(), frequencyMap.get(c.getRank()) + 1);
35-
} else {
36-
frequencyMap.put(c.getRank(), 1);
37-
}
38-
}
39-
return frequencyMap;
40-
}
41-
42-
private int scoreHand(List<Card> cards) {
43-
List<Card> cardsByRank = cards.stream()
44-
.sorted(Comparator.comparing(Card::getRank))
45-
.unordered()
46-
.collect(Collectors.toList());
25+
boolean isFlush = cards.stream()
26+
.map(Card::getSuit)
27+
.distinct()
28+
.count() == 1;
4729

48-
Map<Integer, Integer> frequencyMap = getFrequencyMap(cards);
49-
List<Integer> ranks = frequencyMap
50-
.entrySet()
51-
.stream()
52-
.map(Map.Entry::getKey)
53-
.sorted(Comparator.reverseOrder())
54-
.collect(Collectors.toList());
55-
frequencyMap = frequencyMap
56-
.entrySet()
57-
.stream()
58-
.sorted(Map.Entry.comparingByValue(Collections.reverseOrder()))
59-
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
60-
List<Integer> rankCounts = frequencyMap
61-
.entrySet()
62-
.stream()
63-
.map(Map.Entry::getValue)
64-
.collect(Collectors.toList());
65-
List<Integer> suits = cards
66-
.stream()
67-
.map(Card::getSuit)
68-
.collect(Collectors.toList());
30+
boolean isStraight = ranks.size() == 5 &&
31+
(ranks.get(0) - ranks.get(4) == 4 || ranks.equals(Arrays.asList(14, 5, 4, 3, 2)));
6932

70-
return calculatedScore(frequencyMap, cardsByRank, ranks, rankCounts, suits);
71-
}
72-
73-
private int calculatedScore(Map<Integer, Integer> frequencyMap, List<Card> cardsByRank, List<Integer> ranks,
74-
List<Integer> rankCounts, List<Integer> suits) {
7533
if (ranks.equals(Arrays.asList(14, 5, 4, 3, 2))) {
7634
ranks = Arrays.asList(5, 4, 3, 2, 1);
7735
}
7836

79-
boolean flush = suits
80-
.stream()
81-
.distinct()
82-
.count() == 1;
83-
boolean straight = ranks.stream().distinct().count() == 5
84-
&& ranks.get(0) - ranks.get(4) == 4;
85-
86-
Iterator<Integer> iteratorOverFrequencies = frequencyMap.keySet().iterator();
87-
88-
int highestFrequency = iteratorOverFrequencies.next();
37+
List<Long> frequencies = new ArrayList<>(rankFrequency.values());
38+
frequencies.sort(Collections.reverseOrder());
8939

90-
if (straight && flush) {
91-
return 800 + highestFrequency;
92-
}
93-
if (rankCounts.equals(Arrays.asList(4, 1))) {
94-
return 700 + cardsByRank.get(0).getRank();
95-
}
96-
if (rankCounts.equals(Arrays.asList(3, 2))) {
97-
int triplet = 0;
98-
int pair = 0;
99-
for (Integer key : frequencyMap.keySet()) {
100-
if (frequencyMap.get(key) == 2) {
101-
pair = (int) key;
102-
}
103-
if (frequencyMap.get(key) == 3) {
104-
triplet = 3 * (int) key;
105-
}
106-
}
107-
return 600 + 3 * triplet + pair;
108-
}
109-
if (flush) {
110-
return 500 + highestFrequency;
111-
}
112-
if (straight) {
113-
int maxValue = Collections.max(ranks);
114-
return 400 + maxValue;
115-
}
116-
if (rankCounts.equals(Arrays.asList(3, 1, 1))) {
117-
List<Integer> uniqueCards = new ArrayList<Integer>();
118-
int triplet = 0;
119-
for (Integer key : frequencyMap.keySet()) {
120-
if (frequencyMap.get(key) == 1) {
121-
uniqueCards.add((int) key);
122-
}
123-
if (frequencyMap.get(key) == 3) {
124-
triplet = 3 * (int) key;
125-
}
126-
}
127-
return 300 + triplet + Collections.max(uniqueCards);
128-
}
129-
if (rankCounts.equals(Arrays.asList(2, 2, 1))) {
130-
int productsOfFrequencyAndValue = 0;
131-
for (Integer key : frequencyMap.keySet()) {
132-
int frequencyKey = (int) key;
133-
int frequencyValue = frequencyMap.get(key);
134-
productsOfFrequencyAndValue += frequencyKey * frequencyValue;
135-
}
136-
return 200 + productsOfFrequencyAndValue + 2 * Math.max(highestFrequency, iteratorOverFrequencies.next());
137-
}
138-
if (rankCounts.equals(Arrays.asList(2, 1, 1, 1))) {
139-
return 100 + highestFrequency;
140-
}
141-
ranks.sort(Comparator.naturalOrder());
142-
int result = 0;
143-
for (int i = 0; i < ranks.size(); i++) {
144-
result += ranks.get(0) * (i + 1);
145-
}
146-
return result + ranks.get(ranks.size() - 1);
40+
if (isStraight && isFlush) return 800 + ranks.get(0);
41+
if (frequencies.equals(Arrays.asList(4L, 1L))) return 700 + ranks.get(0);
42+
if (frequencies.equals(Arrays.asList(3L, 2L))) return 600 + ranks.get(0) * 10 + ranks.get(1);
43+
if (isFlush) return 500 + ranks.get(0);
44+
if (isStraight) return 400 + ranks.get(0);
45+
if (frequencies.equals(Arrays.asList(3L, 1L, 1L))) return 300 + ranks.get(0) * 10 + ranks.get(1);
46+
if (frequencies.equals(Arrays.asList(2L, 2L, 1L))) return 200 + ranks.get(0) * 10 + ranks.get(1);
47+
if (frequencies.equals(Arrays.asList(2L, 1L, 1L, 1L))) return 100 + ranks.get(0);
48+
49+
return ranks.stream().reduce(0, (sum, rank) -> sum * 10 + rank);
50+
}
51+
52+
private List<Card> parseCards(String hand) {
53+
return Arrays.stream(hand.split(" "))
54+
.map(Card::new)
55+
.collect(Collectors.toList());
14756
}
148-
}
57+
}

exercises/practice/poker/.meta/src/reference/java/Poker.java

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,27 @@
44
class Poker {
55
private final List<String> bestHands;
66

7-
Poker(final List<String> hands) {
8-
bestHands = bestHands(hands);
7+
Poker(List<String> hands) {
8+
this.bestHands = evaluateBestHands(hands);
99
}
1010

1111
List<String> getBestHands() {
1212
return bestHands;
1313
}
1414

15-
private List<String> bestHands(final List<String> hands) {
16-
ArrayList<Hand> scoredHands = new ArrayList<>();
15+
private List<String> evaluateBestHands(List<String> hands) {
16+
List<Hand> parsedHands = hands.stream()
17+
.map(Hand::new)
18+
.collect(Collectors.toList());
1719

18-
for (String s : hands) {
19-
scoredHands.add(new Hand(s));
20-
}
21-
Optional<Integer> maxScoreIfAny = scoredHands
22-
.stream()
23-
.map(Hand::getScore)
24-
.max(Comparator.naturalOrder());
25-
return maxScoreIfAny
26-
.map(maxScore -> scoredHands
27-
.stream()
28-
.filter(h -> h.getScore() == maxScore)
29-
.map(Hand::getInput)
30-
.collect(Collectors.toList()))
31-
.orElseGet(Collections::emptyList);
20+
int maxScore = parsedHands.stream()
21+
.mapToInt(Hand::calculateScore)
22+
.max()
23+
.orElse(0);
3224

25+
return parsedHands.stream()
26+
.filter(hand -> hand.calculateScore() == maxScore)
27+
.map(Hand::getOriginal)
28+
.collect(Collectors.toList());
3329
}
3430
}

0 commit comments

Comments
 (0)