advent-of-code-2021/src/main/scala/de.qwertyuiop.aoc/2021/day13.scala

42 lines
1.4 KiB
Scala
Raw Normal View History

package de.qwertyuiop.aoc.`2021`
import de.qwertyuiop.aoc.lib.*
import cats.*, cats.implicits.given
2021-12-13 12:49:47 +00:00
import Vectors.*
import Directions.*
import PaperFolding.*
def day13(using InputSource): Unit =
val (dotsRaw, _ :: foldsRaw) = input().span(_.nonEmpty)
val dots = dotsRaw.map(_.splitOnce(",").map((x,y) => Vec2D(x.toInt, y.toInt)).get).toSet
val maxX = dots.map(_.x).max
val maxY = dots.map(_.y).max
val folds = foldsRaw.map {
case s"fold along x=$x" => (true, x.toInt)
case s"fold along y=$y" => (false, y.toInt)
}
val firstFold = foldDots(dots, folds.head(0), folds.head(1))
println(s"\nPoints after first fold: ${firstFold.size}")
val fullyFolded = folds.foldLeft(dots){ case (dots, (vert, pos)) => foldDots(dots, vert, pos) }
printDots(fullyFolded)
object PaperFolding:
def printDots(dots: Set[Vec2D[Int]]) =
val maxX = dots.map(_.x).max
val maxY = dots.map(_.y).max
for y <- 0 to maxY do
for x <- 0 to maxX do
print(if dots.contains(Vec2D(x,y)) then '\u2588' else ' ')
println()
def foldDots(dots: Set[Vec2D[Int]], vertical: Boolean, position: Int) =
val axis: Vec2D[Int] => Int = if vertical then _.x else _.y
val dir: Dir = if vertical then West else South
val (staying, moving) = dots.partition(d => axis(d) < position)
val moved = moving.map(d => d.move(dir, 2 * math.abs(axis(d) - position)))
staying ++ moved