-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay13.scala
48 lines (36 loc) · 1.38 KB
/
Day13.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package advent
import scala.io.Source
object Day13:
def main(args: Array[String]): Unit =
val input = Source.fromResource("day13.txt").getLines().toList
val paper = input
.takeWhile(_.nonEmpty)
.map(_.split(","))
.map(_.map(_.toInt))
.map { case Array(x, y) => Point(x, y) }
.toSet
val folds = input
.drop(paper.size + 1)
.map(_.split("="))
.map { case Array(f, n) => if f.last == 'x' then FoldLeft(n.toInt) else FoldUp(n.toInt) }
println(p1(paper, folds))
println(p2(paper, folds))
sealed trait Fold
case class FoldLeft(x: Int) extends Fold
case class FoldUp(y: Int) extends Fold
type Paper = Set[Point]
extension (paper: Paper)
def exec(fold: Fold): Paper = paper.map(_.fold(fold))
case class Point(x: Int, y: Int) {
def fold(fold: Fold): Point =
fold match
case FoldLeft(c) => if x > c then copy(x = c - (x - c)) else this
case FoldUp(c) => if y > c then copy(y = c - (y - c)) else this
}
def p1(paper: Paper, folds: Seq[Fold]): Int = paper.exec(folds.head).size
def p2(paper: Paper, folds: Seq[Fold]): String =
val r = folds.foldLeft(paper)((p, f) => p.exec(f))
val max = Point(r.map(_.x).max + 1, r.map(_.y).max + 1)
List.tabulate(max.y)(y => List.tabulate(max.x)(x => if r.contains(Point(x, y)) then '#' else '.'))
.map(_.mkString)
.mkString("\n")