Dies ist eine alte Version des Dokuments!
Die Aufgabe ist schwierig zu beschreiben und entsprechend sind die hier gelisteten Tipps möglicherweise nur eingeschränkt hilfreich.
Dieser nachfolgende Lösungsvorschlag ist an einzelnen Stellen nicht besonders schön programmiert. Funktionieren tut er dennoch.
Lösungsvorschlag
Comparator<String[]> cardComparator = new Comparator<String[]>() {
// Die eigene Reihenfolge definieren
String customOrder = "AKQJT98765432"; // Hier deine gewünschte Reihenfolge einfügen
@Override
public int compare(String[] arr1, String[] arr2) {
String s1 = arr1[0];
String s2 = arr2[0];
int minLength = Math.min(s1.length(), s2.length());
for (int i = 0; i < minLength; i++) {
int index1 = customOrder.indexOf(s1.charAt(i));
int index2 = customOrder.indexOf(s2.charAt(i));
if (index1 != index2) {
return Integer.compare(index1, index2);
}
}
return Integer.compare(s1.length(), s2.length());
}
};
private int getType(String hand) {
boolean fiveOfAKind = false;
boolean fourOfAKind = false;
boolean threeOfAKind = false;
int pairs = 0;
char[] chars = hand.toCharArray();
Arrays.sort(chars);
char lastChar = chars[0];
int counter = 1;
for (int i = 1; i < chars.length; i++) {
if (chars[i] != lastChar) {
if (counter == 4) {
fourOfAKind = true;
} else if (counter == 3) {
threeOfAKind = true;
} else if (counter == 2) {
pairs++;
}
lastChar = chars[i];
counter = 1;
continue;
}
counter++;
}
if (counter == 5) {
fiveOfAKind = true;
} else if (counter == 4) {
fourOfAKind = true;
} else if (counter == 3) {
threeOfAKind = true;
} else if (counter == 2) {
pairs++;
}
if (fiveOfAKind) {
return 0;
} else if (fourOfAKind) {
return 1;
} else if (threeOfAKind && pairs == 1) {
return 2;
} else if (threeOfAKind && pairs == 0) {
return 3;
} else if (pairs == 2) {
return 4;
} else if (pairs == 1) {
return 5;
} else {
return 6;
}
}
public long partOne() {
ArrayList<String[]> lines = new ArrayList<String[]>();
for (String line: inputLines) {
lines.add(line.split(" "));
}
// Die folgende Datenstruktur enthält 7 ArrayLists für String[] (die einzelnen Zeilen).
// In der ersten ArrayList werden die stärksten Kartentypen gespeichert und in den darauffolgenden die schwächeren.
ArrayList<ArrayList<String[]>> ranks = new ArrayList<ArrayList<String[]>>();
for (int i = 0; i < 7; i++) {
ranks.add(new ArrayList<String[]>());
}
// sortiere die einzelnen Zeilen nach Karten-Typ-Rang. Es ist noch NICHT nach Kartenwert innerhalb eines Kartentyps sortiert.
for (String[] line: lines) {
ranks.get(getType(line[0])).add(line);
}
long result = 0;
int rankCounter = 1;
for (int r = ranks.size() - 1 ; r >= 0; r--) {
ArrayList<String[]> rank = ranks.get(r);
rank.sort(cardComparator);
for (int l = rank.size() - 1; l >= 0; l--) {
String line = rank.get(l)[1];
result += rankCounter * Integer.parseInt(line);
rankCounter++;
}
}
return result;
}
Für Teil 2 benötigt man an zwei Stellen kleinere Anpassungen.
Bei der Erfassung der Types muss anders vorgegangen werden. Man kann die Methode getType()
so umprogrammieren, dass sie nun die Joker J
zunächst bewusst ignoriert. Anschließend nimmt man den errechneten Karten-Typ und korrigiert ihn pro vorhandenen Joker 'nach oben'. Beispiel: 4JJKQ
wird zunächst exklusive der zwei J als 'High Card' klassifiziert. Nimmt man im ersten Durchlauf einen Joker hinzu, so muss aus einer 'High Card' immer Päärchen werden. Nimmt man im zweiten Durchlauf den zweiten Joker hinzu, so muss aus einem Päärchen ein Drilling werden. Das ist damit die finale Kategorie dieser Karte.
Der Comparator muss minimal umgeschrieben werden, indem man die Reihenfolge der Zeichen ändert.
Lösungsvorschlag
private int getType2(String hand) {
boolean fiveOfAKind = false;
boolean fourOfAKind = false;
boolean threeOfAKind = false;
int pairs = 0;
char[] chars = hand.toCharArray();
Arrays.sort(chars);
char lastChar = chars[0];
int counter = 1;
for (int i = 1; i < chars.length; i++) {
if (chars[i] == 'J') {
continue;
}
if (chars[i] != lastChar) {
if (counter == 4) {
fourOfAKind = true;
} else if (counter == 3) {
threeOfAKind = true;
} else if (counter == 2) {
pairs++;
}
lastChar = chars[i];
counter = 1;
continue;
}
counter++;
}
if (counter == 5) {
fiveOfAKind = true;
} else if (counter == 4) {
fourOfAKind = true;
} else if (counter == 3) {
threeOfAKind = true;
} else if (counter == 2) {
pairs++;
}
if (fiveOfAKind) {
return 0;
} else if (fourOfAKind) {
return 1;
} else if (threeOfAKind && pairs == 1) {
return 2;
} else if (threeOfAKind && pairs == 0) {
return 3;
} else if (pairs == 2) {
return 4;
} else if (pairs == 1) {
return 5;
} else {
return 6;
}
}
private int pimpType(int type, String card) {
int amountOfJ = 0;
for (int i = 0; i < card.length(); i++) {
if (card.charAt(i) == 'J') {
amountOfJ++;
}
}
int result = type;
for (int i = 0; i < amountOfJ; i++) {
if (type == 0 || type == 1) {
type = 0;
} else if (type == 2 || type == 3) {
type = 1;
} else if (type == 4) {
type = 2;
} else if (type == 5) {
type = 3;
} else {
type = 5;
}
}
return type;
}
public long partTwo() {
ArrayList<String[]> lines = new ArrayList<String[]>();
for (String line: inputLines) {
lines.add(line.split(" "));
}
// Die folgende Datenstruktur enthält 7 ArrayLists für String[] (die einzelnen Zeilen).
// In der ersten ArrayList werden die stärksten Kartentypen gespeichert und in den darauffolgenden die schwächeren.
ArrayList<ArrayList<String[]>> ranks = new ArrayList<ArrayList<String[]>>();
for (int i = 0; i < 7; i++) {
ranks.add(new ArrayList<String[]>());
}
// sortiere die einzelnen Zeilen nach Karten-Typ-Rang. Es ist noch NICHT nach Kartenwert innerhalb eines Kartentyps sortiert.
for (String[] line: lines) {
int type = getType2(line[0]);
type = pimpType(type, line[0]);
ranks.get(type).add(line);
System.out.println(line[0] + " " + type);
}
long result = 0;
int rankCounter = 1;
for (int r = ranks.size() - 1 ; r >= 0; r--) {
ArrayList<String[]> rank = ranks.get(r);
rank.sort(cardComparator2);
for (int l = rank.size() - 1; l >= 0; l--) {
String line = rank.get(l)[1];
result += rankCounter * Integer.parseInt(line);
rankCounter++;
}
}
return result;
}