-
Notifications
You must be signed in to change notification settings - Fork 0
/
day07.groovy
131 lines (116 loc) · 3.83 KB
/
day07.groovy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import groovy.transform.TupleConstructor;
import groovy.transform.ToString;
enum HandType {
FiveOfAKind,
FourOfAKind,
FullHouse,
ThreeOfAKind,
TwoPair,
OnePair,
HighCard;
}
@ToString
class Hand {
int[] cards;
long value;
HandType type;
Hand(String hand, long value, boolean jokerMode = false) {
this.cards = hand.getChars().collect {
switch(it) {
case '0'..'9': return "$it".toInteger();
case 'T': return 10;
case 'J': return jokerMode ? 0 : 11;
case 'Q': return 12;
case 'K': return 13;
case 'A': return 14;
default:
assert false : "Hand parsing error"
}
}
this.value = value
this.type = getType();
}
private HandType getType() {
def cardCounts = cards.inject([:]) { acc, it ->
if (acc[it] != null) {
acc[it] += 1;
} else {
acc[it] = 1;
}
return acc;
};
def jokerCount = cardCounts[0];
if (jokerCount == 5) {
return HandType.FiveOfAKind;
}
cardCounts.remove(0);
cardCounts = cardCounts.values().sort();
cardCounts[-1] = cardCounts[-1] + (jokerCount ?: 0);
if (cardCounts[0] == 5) {
return HandType.FiveOfAKind;
} else if (cardCounts[0] == 1 && cardCounts[1] == 4) {
return HandType.FourOfAKind;
} else if (cardCounts[0] == 2 && cardCounts[1] == 3) {
return HandType.FullHouse;
} else if (cardCounts[0] == 1 && cardCounts[1] == 1 && cardCounts[2] == 3) {
return HandType.ThreeOfAKind;
} else if (cardCounts[0] == 1 && cardCounts[1] == 2 && cardCounts[2] == 2) {
return HandType.TwoPair;
} else if (cardCounts[-1] == 2) {
return HandType.OnePair;
} else if (cardCounts.findAll { it == 1 }.size() == 5) {
return HandType.HighCard;
} else {
assert false : "Unknown hand type";
}
}
int compareTo(Hand other) {
int handTypeCompare = this.type <=> other.type;
if (handTypeCompare != 0) {
return -handTypeCompare;
}
for (int i = 0; i < 5; i++) {
int cardCompare = this.cards[i] <=> other.cards[i]
if (cardCompare != 0) {
return cardCompare;
}
}
}
}
{ // Test: Hand.type
assert new Hand("AAAAA", 0L).type == HandType.FiveOfAKind;
assert new Hand("AA3AA", 0L).type == HandType.FourOfAKind;
assert new Hand("AA33A", 0L).type == HandType.FullHouse;
assert new Hand("AA3TA", 0L).type == HandType.ThreeOfAKind;
assert new Hand("AATT2", 0L).type == HandType.TwoPair;
assert new Hand("AAT32", 0L).type == HandType.OnePair;
assert new Hand("34567", 0L).type == HandType.HighCard;
}
{ // Test: Hand.compareTo
assert new Hand("AAAAA", 0L).compareTo(new Hand("AAAA2", 0L)) == 1;
assert new Hand("AAA22", 0L).compareTo(new Hand("AAAA2", 0L)) == -1;
assert new Hand("44444", 0L).compareTo(new Hand("33333", 0L)) == 1;
}
def input = new File("input/day07.txt").readLines()
def totalWinnings = input.collect { line ->
def parts = line.split(" ");
return new Hand(parts[0], parts[1].toLong());
}.sort { h1, h2 ->
h1.compareTo(h2)
}.withIndex().collect { hand, index ->
[index + 1, hand]
}.inject(0) { acc, it ->
acc += it[0] * it[1].value
}
println totalWinnings;
def totalWinnings2 = input.collect { line ->
def parts = line.split(" ");
return new Hand(parts[0], parts[1].toLong(), true);
}.sort { h1, h2 ->
h1.compareTo(h2)
}.withIndex().collect { hand, index ->
[index + 1, hand]
}.inject(0) { acc, it ->
acc += it[0] * it[1].value
}
println totalWinnings2;