From 3a3720368116c389c05e5814fcd0239db55d38ef Mon Sep 17 00:00:00 2001 From: scarf Date: Tue, 17 Sep 2024 17:12:25 +0900 Subject: [PATCH] feat: day 13 --- 2015/Day13.scala | 56 +++++++++++++++++++++++++++++++++++++++++++ 2015/Day13.test.scala | 22 +++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 2015/Day13.scala create mode 100644 2015/Day13.test.scala diff --git a/2015/Day13.scala b/2015/Day13.scala new file mode 100644 index 0000000..924e579 --- /dev/null +++ b/2015/Day13.scala @@ -0,0 +1,56 @@ +package day13 + +import scala.io.Source.fromFile +import scala.util.chaining.* + +type Score = Map[String, Map[String, Int]] + +def parse(input: String) = input match + case s"$from would gain $n happiness units by sitting next to $to." => + from -> (to -> n.toInt) + case s"$from would lose $n happiness units by sitting next to $to." => + from -> (to -> -n.toInt) + +def parseToMap(xs: Iterable[String]) = xs + .map(parse) + .toSeq + .groupBy(_._1) + .view + .mapValues(_.map(_._2).toMap) + .toMap + +extension [A](xs: Seq[A]) + def slidingCyclic(size: Int) = + xs.concat(xs).sliding(size).take(xs.size) + + def permutationsCyclic = + xs.drop(1).permutations.map(xs.head +: _) + +def score(comb: Seq[String])(implicit scores: Score) = + comb + .slidingCyclic(3) + .collect { case Seq(left, center, right) => + val f = scores.getOrElse(center, Map.empty) + f.getOrElse(left, 0) + f.getOrElse(right, 0) + } + .sum + +def part1(scores: Score) = + val people = scores.keys.toSeq + val combination = people.permutationsCyclic.toSeq + + given Score = scores + combination.map(score).max + +def part2(scores: Score) = + val people = scores.keys.toSeq :+ "Me" + val combination = people.permutationsCyclic.toSeq + + given Score = scores + combination.map(score).max + +@main def main() = + val scores: Score = fromFile(".cache/13.txt").getLines.toSeq.pipe(parseToMap) + + println(part1(scores)) + println(part2(scores)) diff --git a/2015/Day13.test.scala b/2015/Day13.test.scala new file mode 100644 index 0000000..48aeb2f --- /dev/null +++ b/2015/Day13.test.scala @@ -0,0 +1,22 @@ +import scala.util.chaining.* +import munit.FunSuite +import day13.* + +class Day13Tests extends FunSuite: + test("Part 1"): + val scores = """ + Alice would gain 54 happiness units by sitting next to Bob. + Alice would lose 79 happiness units by sitting next to Carol. + Alice would lose 2 happiness units by sitting next to David. + Bob would gain 83 happiness units by sitting next to Alice. + Bob would lose 7 happiness units by sitting next to Carol. + Bob would lose 63 happiness units by sitting next to David. + Carol would lose 62 happiness units by sitting next to Alice. + Carol would gain 60 happiness units by sitting next to Bob. + Carol would gain 55 happiness units by sitting next to David. + David would gain 46 happiness units by sitting next to Alice. + David would lose 7 happiness units by sitting next to Bob. + David would gain 41 happiness units by sitting next to Carol. + """.trim.split("\n").map(_.trim).toSeq.pipe(parseToMap) + + assertEquals(part1(scores), 330)