diff --git a/java/src/main/java/day7/Hand.java b/java/src/main/java/day7/Hand.java new file mode 100644 index 0000000..55ac84e --- /dev/null +++ b/java/src/main/java/day7/Hand.java @@ -0,0 +1,46 @@ +package day7; + +import io.vavr.collection.HashMap; +import io.vavr.collection.List; +import io.vavr.collection.Map; +import lombok.Getter; + +import static day7.HandType.getHandType; + +@Getter +public class Hand implements Comparable { + private static final boolean ARE_JOKERS_ENABLED = true; + private static final Integer JOKERS_VALUE = ARE_JOKERS_ENABLED ? 1 : 11; + + private static final Map CARD_SYMBOLS_TO_VALUES = HashMap.of( + 'T', 10, + 'J', JOKERS_VALUE, + 'Q', 12, + 'K', 13, + 'A', 14 + ); + + private final List cards; + private final HandType type; + + public Hand(String handRepresentation) { + this.cards = List.ofAll(handRepresentation.toCharArray()) + .map(cardSymbol -> CARD_SYMBOLS_TO_VALUES + .get(cardSymbol) + .getOrElse(() -> Integer.parseInt(String.valueOf(cardSymbol)))); + this.type = getHandType(cards); + } + + @Override + public int compareTo(Hand other) { + if (!this.getType().getValue().equals(other.getType().getValue())) { + return this.type.getValue() - other.type.getValue(); + } + + return this.cards + .zip(other.getCards()) + .map(cardsPair -> cardsPair._1 - cardsPair._2) + .find(cardsDifference -> cardsDifference != 0) + .getOrElse(0); + } +} diff --git a/java/src/main/java/day7/HandType.java b/java/src/main/java/day7/HandType.java new file mode 100644 index 0000000..416f245 --- /dev/null +++ b/java/src/main/java/day7/HandType.java @@ -0,0 +1,71 @@ +package day7; + +import io.vavr.Tuple2; +import io.vavr.collection.List; +import io.vavr.collection.Map; +import lombok.Getter; + +import java.util.Collections; + +@Getter +public enum HandType { + RE_POKER(6), + POKER(5), + FULL_HOUSE(4), + THREE(3), + DOUBLE_PAIR(2), + PAIR(1), + NOTHING(0); + + private final Integer value; + HandType(Integer value) { + this.value = value; + } + + public static HandType getHandType(List cards) { + Map groupedCards = cards.toMap( + card -> card, + card -> Collections.frequency(cards.toJavaList(), card) + ); + + Integer jokersCount = groupedCards.get(1).getOrElse(0); + + java.util.List sortedCardCounts = groupedCards + .filterKeys(card -> card != 1) + .map(Tuple2::_2) + .sorted() + .toJavaList(); + + if (sortedCardCounts.size() != 0) { + sortedCardCounts.add( + sortedCardCounts.remove(sortedCardCounts.size() - 1) + jokersCount + ); + } else { + sortedCardCounts.add(groupedCards.get(1).getOrElseThrow(RuntimeException::new)); + } + + return determineHandTypeBasedOnCardCounts(List.ofAll(sortedCardCounts)); + } + + private static HandType determineHandTypeBasedOnCardCounts(List cardCounts) { + if (cardCounts.contains(5)) { + return RE_POKER; + } + if (cardCounts.contains(4)) { + return POKER; + } + if (cardCounts.contains(3) && cardCounts.contains(2)) { + return FULL_HOUSE; + } + if (cardCounts.contains(3)) { + return THREE; + } + if (cardCounts.contains(2) && cardCounts.length() == 3) { + return DOUBLE_PAIR; + } + if (cardCounts.contains(2)) { + return PAIR; + } + return NOTHING; + } +} diff --git a/java/src/main/java/day7/Main.java b/java/src/main/java/day7/Main.java new file mode 100644 index 0000000..c8c88f1 --- /dev/null +++ b/java/src/main/java/day7/Main.java @@ -0,0 +1,31 @@ +package day7; + +import io.vavr.Tuple2; +import io.vavr.collection.List; +import util.FileReader; + +public class Main { + + public static void main(String[] args) { + String inputFilePath = System.getProperty("user.dir") + "\\java\\src\\main\\java\\day7\\input.txt"; + FileReader reader = new FileReader(inputFilePath); + List inputData = List.ofAll(reader.readContents()); + + List> handsAndBids = inputData + .map(string -> string.split(" ")) + .map(List::of) + .map(splitInputLine -> new Tuple2<>( + new Hand(splitInputLine.get(0)), + Integer.parseInt(splitInputLine.get(1)) + )); + + Integer result = handsAndBids + .sorted() + .map(Tuple2::_2) + .zipWithIndex() + .map(bidAndValue -> bidAndValue._1 * ( bidAndValue._2 + 1 )) + .reduce(Integer::sum); + + System.out.println(result); + } +}