Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: 2015 day 17
Browse files Browse the repository at this point in the history
scarf005 committed Oct 2, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 0389e72 commit f72d102
Showing 2 changed files with 76 additions and 0 deletions.
60 changes: 60 additions & 0 deletions 2015/day17.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package `2015`.day17

import prelude.*
import scala.collection.mutable.Map

trait Pretty[A]:
extension (x: A) inline def pretty: String

inline given [A]: Pretty[IterableOnce[A]] with
extension (x: IterableOnce[A])
inline def pretty = x.iterator.mkString("[", ", ", "]")

extension [A](x: Iterable[A])
def combinationsRepeating(size: Int): Iterator[Seq[A]] =
x.zipWithIndex.toSeq.combinations(size).map(_.map(_._1))

trait Logger:
def log(msg: => Any): Unit

given Logger = NoopLogger

object NoopLogger extends Logger:
def log(msg: => Any): Unit = {}

object PrintLogger extends Logger:
def log(msg: => Any): Unit = println(msg)

def part1(target: Int, containers: Iterable[Int])(using logger: Logger) =
val dp = Map[Int, Int](0 -> 1)
logger.log(s"target: $target, containers: $containers, dp: ${dp.pretty}")

for currentSize <- containers do
for nextSize <- (target to currentSize by -1) do
for x <- dp.get(nextSize - currentSize) do
dp(nextSize) = dp.getOrElse(nextSize, 0) + x
logger.log(
f"ways to fit $nextSize%2dL => using $currentSize%2dL: x${dp(nextSize)} ($x%2d ways to fit leftover ${nextSize - currentSize}%2dL), dp: ${dp.pretty}",
)
dp(target)

def part2(target: Int, containers: Seq[Int])(using logger: Logger) =
def matches(kinds: Int) =
containers
.combinationsRepeating(kinds)
.tapEach(logger.log(_))
.count(_.sum == target)
.tap(logger.log(_))

(1 to containers.size)
.map(matches)
.tapEach(logger.log(_))
.find(_ > 0)
.getOrElse(throw new Exception("no match found"))

@main def main() =
val containers = fromFile(".cache/2015/17.txt").getLines.map(_.toInt).toSeq
val target = 150

println(part1(target, containers))
println(part2(target, containers))
16 changes: 16 additions & 0 deletions 2015/day17.test.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package `2015`.day17

import prelude.*
import munit.FunSuite
import `2015`.day17.*


class Tests extends FunSuite:
// given Logger = PrintLogger
test("part 1"):
val res = part1(target = 25, containers = Seq(20, 15, 10, 5, 5))
assertEquals(res, 4)

test("part2"):
val res = part2(target = 25, containers = Seq(20, 15, 10, 5, 5))
assertEquals(res, 3)

0 comments on commit f72d102

Please sign in to comment.