This commit is contained in:
Paul-Henri Froidmont 2024-12-09 14:57:26 +01:00
parent 87c3869717
commit 2e76446786
Signed by: phfroidmont
GPG key ID: BE948AFD7E7873BE
2 changed files with 86 additions and 0 deletions

1
input/day09 Normal file

File diff suppressed because one or more lines are too long

85
src/day09.scala Normal file
View file

@ -0,0 +1,85 @@
package aoc
package day09
import scala.annotation.tailrec
val dayNumber = "09"
@main def part1: Unit =
println(part1(loadInput(dayNumber)))
@main def part2: Unit =
println(part2(loadInput(dayNumber)))
def part1(input: String): String =
val blocks = input
.map(_.asDigit)
.grouped(2)
.zipWithIndex
.flatMap {
case (IndexedSeq(fileSize), fileId) => List.fill(fileSize)(Some(fileId))
case (IndexedSeq(fileSize, freeSpace), fileId) =>
List.fill(fileSize)(Some(fileId)) ++ List.fill(freeSpace)(None)
}
.toVector
@tailrec def compact(blocks: Vector[Option[Int]], acc: List[Int]): List[Int] =
if blocks.isEmpty then acc.reverse
else
blocks.head match
case Some(fileId) => compact(blocks.tail, fileId :: acc)
case None => compact(blocks.last +: blocks.tail.init, acc)
compact(blocks, Nil).zipWithIndex
.map(_.toLong * _)
.sum
.toString
def part2(input: String): String =
enum Block:
val length: Int
case File(fileId: Int, override val length: Int)
case Empty(override val length: Int)
val blocks = input
.map(_.asDigit)
.grouped(2)
.zipWithIndex
.flatMap {
case (IndexedSeq(fileSize), fileId) =>
List(Block.File((fileId), fileSize))
case (IndexedSeq(fileSize, freeSpace), fileId) =>
List(Block.File(fileId, fileSize), Block.Empty(freeSpace))
}
.toVector
@tailrec def compact(blocks: Vector[Block], acc: List[Block]): List[Block] =
blocks.lastOption match
case Some(last: Block.File) =>
blocks.indexWhere {
case Block.Empty(length) => last.length <= length
case _: Block.File => false
} match
case -1 => compact(blocks.init, last :: acc)
case idx =>
val newBlocks = List(
Block.File(last.fileId, last.length),
Block.Empty(blocks(idx).length - last.length)
)
compact(
blocks.take(idx) ++ newBlocks ++ blocks.drop(idx + 1).init,
Block.Empty(last.length) :: acc
)
case Some(last: Block.Empty) => compact(blocks.init, last :: acc)
case None => acc
compact(blocks, Nil)
.flatMap {
case Block.File(fileId, length) => List.fill(length)(fileId.toLong)
case Block.Empty(length) => List.fill(length)(0L)
}
.zipWithIndex
.map(_ * _)
.sum
.toString