Day 7
This commit is contained in:
parent
d1937c0846
commit
44eaf3037e
92
Day7.scala
Normal file
92
Day7.scala
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
package aoc.day7
|
||||||
|
|
||||||
|
import aoc._
|
||||||
|
|
||||||
|
val possibleCards = "AKQJT98765432".reverse
|
||||||
|
|
||||||
|
enum DeckKind:
|
||||||
|
case High
|
||||||
|
case Pair
|
||||||
|
case Pairs
|
||||||
|
case Three
|
||||||
|
case House
|
||||||
|
case Four
|
||||||
|
case Five
|
||||||
|
|
||||||
|
object DeckKind:
|
||||||
|
def apply(deck: String) =
|
||||||
|
val ranks = deck.sorted.toArray
|
||||||
|
if ranks(0) == ranks(4) then Five
|
||||||
|
else if ranks(0) == ranks(3) || ranks(1) == ranks(4) then Four
|
||||||
|
else if ranks(0) == ranks(2) && ranks(3) == ranks(4) || ranks(0) == ranks(
|
||||||
|
1
|
||||||
|
) && ranks(2) == ranks(4)
|
||||||
|
then House
|
||||||
|
else if ranks(0) == ranks(1) && ranks(2) == ranks(3) || ranks(0) == ranks(
|
||||||
|
1
|
||||||
|
) && ranks(3) == ranks(4) || ranks(1) == ranks(2) && ranks(3) == ranks(4)
|
||||||
|
then Pairs
|
||||||
|
else
|
||||||
|
lazy val three = (0 until ranks.length - 2)
|
||||||
|
.find(i => ranks(i) == ranks(i + 2))
|
||||||
|
.map(i => Three)
|
||||||
|
lazy val pair = (0 until ranks.length - 1)
|
||||||
|
.find(i => ranks(i) == ranks(i + 1))
|
||||||
|
.map(i => Pair)
|
||||||
|
three.orElse(pair).getOrElse(High)
|
||||||
|
|
||||||
|
import DeckKind._
|
||||||
|
|
||||||
|
case class Hand(deck: String, bet: Int):
|
||||||
|
def deckRank(using cardToRank: Map[Char, Int]) = deck.map(cardToRank(_))
|
||||||
|
val kind = DeckKind(deck)
|
||||||
|
|
||||||
|
lazy val bestKind =
|
||||||
|
deck.iterator
|
||||||
|
.foldLeft(Iterator("")) { (it, chr) =>
|
||||||
|
if chr == 'J' then it.flatMap(s => possibleCards.map(s + _))
|
||||||
|
else it.map(_ + chr)
|
||||||
|
}
|
||||||
|
.map(DeckKind(_))
|
||||||
|
.maxBy(_.ordinal)
|
||||||
|
|
||||||
|
inline def nonZero(ins: Int*) = ins.find(_ != 0).getOrElse(0)
|
||||||
|
|
||||||
|
object Parser extends CommonParser:
|
||||||
|
val deck = (s"[${possibleCards}]{5}").r
|
||||||
|
val hand = deck ~ num ^^ { case (deck ~ num) => Hand(deck, num) }
|
||||||
|
def apply(s: String) =
|
||||||
|
parse(hand, s).get
|
||||||
|
|
||||||
|
// part 1
|
||||||
|
|
||||||
|
def handOrdering(toKind: Hand => DeckKind)(using cardOrdering: Map[Char, Int]) =
|
||||||
|
new Ordering[Hand]:
|
||||||
|
override def compare(dx: Hand, dy: Hand): Int =
|
||||||
|
val (x, y) = (toKind(dx), toKind(dy))
|
||||||
|
if x.ordinal != y.ordinal then x.ordinal.compareTo(y.ordinal)
|
||||||
|
else nonZero(dx.deckRank.zip(dy.deckRank).map(_ compareTo _)*)
|
||||||
|
|
||||||
|
def print(using Ordering[Hand]) =
|
||||||
|
val hands = lines.map(Parser(_)).toSeq
|
||||||
|
val res =
|
||||||
|
hands.sorted.zipWithIndex
|
||||||
|
.map((h, idx) => h.bet * (idx + 1L))
|
||||||
|
.sum
|
||||||
|
println(res)
|
||||||
|
|
||||||
|
def part1 =
|
||||||
|
val ordering = possibleCards.zipWithIndex.toMap
|
||||||
|
val handOrd = handOrdering(_.kind)(using ordering)
|
||||||
|
print(using handOrd)
|
||||||
|
|
||||||
|
// part 2
|
||||||
|
|
||||||
|
def part2 =
|
||||||
|
val ordering = "J23456789TQKA".zipWithIndex.toMap
|
||||||
|
val handOrd = handOrdering(_.bestKind)(using ordering)
|
||||||
|
print(using handOrd)
|
||||||
|
|
||||||
|
@main def Day7(part: Int) = part match
|
||||||
|
case 1 => part1
|
||||||
|
case 2 => part2
|
1000
inputs/day7.input
Normal file
1000
inputs/day7.input
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue