Last active
January 14, 2022 12:37
Star
You must be signed in to star a gist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package lascala.aoc2021.day1_10.day5 | |
opaque type Diagram = Map[(Int, Int), Int] | |
extension (d: Diagram) | |
def countValue(cond: Int => Boolean): Int = d.values.count(cond) | |
object Diagram: | |
def fromPoints(points: Seq[(Int, Int)]): Diagram = | |
points.foldLeft(Map.empty[(Int, Int), Int].withDefaultValue(0)) { | |
case (d, (x, y)) => d.updated((x, y), d((x, y)) + 1) | |
} | |
def parse(s: String): Diagram = | |
val points: Seq[(Int, Int)] = s.split("\n").map(Line.parse).flatMap{ | |
case Some(Line.Diagonal(_, _, _, _)) => Seq.empty | |
case Some(line) => line.toPoints | |
case None => Seq.empty | |
} | |
fromPoints(points) | |
end parse | |
def parseWithDiagonal(s: String): Diagram = | |
val points: Seq[(Int, Int)] = s.split("\n").map(Line.parse).flatMap{ | |
case Some(line) => line.toPoints | |
case None => Seq.empty | |
} | |
fromPoints(points) | |
end parseWithDiagonal | |
end Diagram | |
sealed trait Line | |
extension (l: Line) | |
def toPoints: Seq[(Int, Int)] = l match | |
case Line.Horizontal(x0, x1, y) => | |
(x0 to x1).map(x => (x, y)) | |
case Line.Vertical(y0, y1, x) => | |
(y0 to y1).map(y => (x, y)) | |
case Line.Diagonal(x0, y0, x1, y1) => | |
def points(i: Int, f: Int): List[Int] = | |
(if i <= f then i to f else i to f by -1).toList | |
points(x0, x1) `zip` points(y0, y1) | |
end toPoints | |
end extension | |
object Line: | |
final case class Horizontal(x0: Int, x1: Int, y: Int) extends Line | |
final case class Vertical(y0: Int, y1: Int, x: Int) extends Line | |
final case class Diagonal(x0: Int, y0: Int, x1: Int, y1: Int) extends Line | |
def parse(s: String): Option[Line] = | |
val Array(x0, y0, x1, y1) = for | |
pointString <- s.split(" -> ") | |
point <- pointString.split(",").map(_.toInt) | |
yield point | |
if x0 == x1 then Some(Vertical(y0 min y1, y0 max y1, x0)) | |
else if y0 == y1 then Some(Horizontal(x0 min x1, x0 max x1, y0)) | |
else if (x1 - x0).abs == (y1 - y0).abs then Some(Diagonal(x0, y0, x1, y1)) | |
else None | |
end parse | |
end Line | |
def solve1(s: String): BigInt = | |
val diagram = Diagram.parse(s) | |
diagram.countValue(_ >= 2) | |
end solve1 | |
def solve2(s: String): BigInt = | |
val diagram = Diagram.parseWithDiagonal(s) | |
diagram.countValue(_ >= 2) | |
end solve2 | |
@main def part1: Unit = | |
val ans = solve1(input) | |
println(ans) | |
@main def part2: Unit = | |
val ans = solve2(input) | |
println(ans) | |
//val input = """556,286 -> 341,71 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package lascala.aoc2021.day1_10.day5 | |
import minitest.SimpleTestSuite | |
import hedgehog.minitest.HedgehogSupport | |
import hedgehog.* | |
object Day5Test extends SimpleTestSuite with HedgehogSupport: | |
val testInput = """0,9 -> 5,9 | |
8,0 -> 0,8 | |
9,4 -> 3,4 | |
2,2 -> 2,1 | |
7,0 -> 7,4 | |
6,4 -> 2,0 | |
0,9 -> 2,9 | |
3,4 -> 1,4 | |
0,0 -> 8,8 | |
5,5 -> 8,2""" | |
example("day5 - solve1") { | |
solve1(testInput) ==== 5 | |
} | |
example("day5 - solve2") { | |
solve2(testInput) ==== 12 | |
} | |
end Day5Test |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment