From a170fb9b50f68a9ab0b47a59b271a99b48a3d4a1 Mon Sep 17 00:00:00 2001 From: LordBaryhobal Date: Thu, 7 Dec 2023 11:16:53 +0100 Subject: [PATCH] day 7 puzzle 2 --- README.md | 16 ++++----- src/day7/Hand2.scala | 65 ++++++++++++++++++++++++++++++++++++ src/day7/Puzzle2.scala | 46 +++++++++++++++++++++++++ tests/day7/Puzzle2Test.scala | 9 +++++ 4 files changed, 128 insertions(+), 8 deletions(-) create mode 100644 src/day7/Hand2.scala create mode 100644 src/day7/Puzzle2.scala create mode 100644 tests/day7/Puzzle2Test.scala diff --git a/README.md b/README.md index 841f11e..1b51175 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,11 @@ This repo contains my attempt at this year's Advent of Code (2023) I will try and do some problems (probably not all of them) in Scala ## Progress: -#### Stars: 13 / 50 -| Mon | Tue | Wed | Thu | Fri | Sat | Sun | -|:-----------------:|:-----------------:|:-----------------:|:-----------:|:-----------------:|:-----------------:|:-----------------:| -| | | | | 1
:star::star: | 2
:star::star: | 3
:star::star: | -| 4
:star::star: | 5
:star::star: | 6
:star::star: | 7
:star: | 8 | 9 | 10 | -| 11 | 12 | 13 | 14 | 15 | 16 | 17 | -| 18 | 19 | 20 | 21 | 22 | 23 | 24 | -| 25 | | | | | | | \ No newline at end of file +#### Stars: 14 / 50 +| Mon | Tue | Wed | Thu | Fri | Sat | Sun | +|:-----------------:|:-----------------:|:-----------------:|:-----------------:|:-----------------:|:-----------------:|:-----------------:| +| | | | | 1
:star::star: | 2
:star::star: | 3
:star::star: | +| 4
:star::star: | 5
:star::star: | 6
:star::star: | 7
:star::star: | 8 | 9 | 10 | +| 11 | 12 | 13 | 14 | 15 | 16 | 17 | +| 18 | 19 | 20 | 21 | 22 | 23 | 24 | +| 25 | | | | | | | \ No newline at end of file diff --git a/src/day7/Hand2.scala b/src/day7/Hand2.scala new file mode 100644 index 0000000..d57ca7d --- /dev/null +++ b/src/day7/Hand2.scala @@ -0,0 +1,65 @@ +package day7 + +import scala.collection.mutable + +class Hand2(var cards: Array[Int], val bid: Int) { + + def getType(): Int = { + val cardsMap: mutable.Map[Int, Int] = new mutable.HashMap() + val jokers: Int = cards.count(c => c == 0) + for (card: Int <- cards) { + if (card != 0) { + if (!cardsMap.contains(card)) { + cardsMap(card) = 0 + } + cardsMap(card) += 1 + } + } + + val keys: Array[Int] = cardsMap.keys.toArray + val values: Array[Int] = cardsMap.values.toArray + + if (jokers == 5) return 6 + + // Five of a kind + for (value: Int <- values) { + if (value + jokers == 5) return 6 + } + + // Four of a kind + for (value: Int <- values) { + if (value + jokers == 4) return 5 + } + + // Full house + val sortedValues: Array[Int] = values.sorted(Ordering.Int.reverse) + if (sortedValues(0) + sortedValues(1) + jokers >= 5) return 4 + + // Three of a kind + if (sortedValues(0) + jokers >= 3) return 3 + + // Two pairs + if (sortedValues(0) + sortedValues(1) + jokers >= 4) return 2 + + // One pair + if (sortedValues(0) + jokers >= 2) return 1 + + return 0 + } + + def isBetter(hand: Hand2): Boolean = { + val t1: Int = getType() + val t2: Int = hand.getType() + if (t1 > t2) return true + if (t1 < t2) return false + + for ((c1: Int, c2: Int) <- cards.zip(hand.cards)) { + if (c1 != c2) { + return c1 > c2 + } + } + return false + } + + override def toString: String = s"Hand(${cards.mkString}, $bid, ${getType()})" +} diff --git a/src/day7/Puzzle2.scala b/src/day7/Puzzle2.scala new file mode 100644 index 0000000..f649a01 --- /dev/null +++ b/src/day7/Puzzle2.scala @@ -0,0 +1,46 @@ +package day7 + +import scala.io.{BufferedSource, Source} + +object Puzzle2 { + val CARDS: Array[Int] = Array('J', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'Q', 'K', 'A') + var hands: Array[Hand2] = Array.empty + + def loadInput(path: String): Unit = { + val source: BufferedSource = Source.fromFile(path) + val lines: Array[String] = source.getLines().toArray + + hands = new Array(lines.length) + + for ((line: String, i: Int) <- lines.zipWithIndex) { + val parts: Array[String] = line.split(" ") + val cards: Array[Int] = parts(0).map(c => CARDS.indexOf(c)).toArray + val bid: Int = parts(1).toInt + hands(i) = new Hand2(cards, bid) + } + + source.close() + } + + def sortHands(): Unit = { + hands = hands.sortWith((h1: Hand2, h2: Hand2) => h2.isBetter(h1)) + } + + def solve(path: String): Int = { + loadInput(path) + sortHands() + + var solution: Int = 0 + + for ((hand: Hand2, i: Int) <- hands.zipWithIndex) { + solution += hand.bid * (i+1) + } + + return solution + } + + def main(args: Array[String]): Unit = { + val solution: Int = solve("./res/day7/input1.txt") + println(solution) + } +} diff --git a/tests/day7/Puzzle2Test.scala b/tests/day7/Puzzle2Test.scala new file mode 100644 index 0000000..5ae327a --- /dev/null +++ b/tests/day7/Puzzle2Test.scala @@ -0,0 +1,9 @@ +package day7 + +import org.scalatest.funsuite.AnyFunSuite + +class Puzzle2Test extends AnyFunSuite { + test("Puzzle2.solve") { + assert(Puzzle2.solve("tests_res/day7/input1.txt") == 5905) + } +}