Part 2
This commit is contained in:
parent
d80a8ce32f
commit
327aaf4fd7
2 changed files with 570 additions and 37 deletions
103
src/day09.scala
103
src/day09.scala
|
|
@ -20,45 +20,90 @@ def part1(input: String): Long =
|
|||
((a.x - b.x + 1) * (a.y - b.y + 1)).abs
|
||||
}.max
|
||||
|
||||
enum Edge:
|
||||
case H(fixedY: Int, range: Range)
|
||||
case V(fixedX: Int, range: Range)
|
||||
|
||||
def contains(x: Int, y: Int): Boolean =
|
||||
this match
|
||||
case H(fixedY, range) => fixedY == y && range.contains(x)
|
||||
case V(fixedX, range) => fixedX == x && range.contains(y)
|
||||
|
||||
object Edge:
|
||||
def apply(a: Point, b: Point): Edge =
|
||||
if a.y == b.y then Edge.H(a.y, min(a.x, b.x) to max(a.x, b.x))
|
||||
else if a.x == b.x then Edge.V(a.x, min(a.y, b.y) to max(a.y, b.y))
|
||||
else ???
|
||||
|
||||
case class Polygon(edges: List[Edge]):
|
||||
val minX = edges.map {
|
||||
case Edge.H(_, range) => range.min
|
||||
case Edge.V(fixedX, _) => fixedX
|
||||
}.min - 1
|
||||
|
||||
def contains(p: Point) =
|
||||
if edges.exists(_.contains(p.x, p.y)) then true
|
||||
else
|
||||
// println(p)
|
||||
val (count, _) = (minX to p.x).foldLeft((0, false)) { case ((count, switched), x) =>
|
||||
// println(x)
|
||||
// print("edge contains ")
|
||||
// println(edges.exists(_.contains(x, p.y)))
|
||||
// print("switched ")
|
||||
// println(switched)
|
||||
if edges.exists(_.contains(x, p.y)) && !switched then (count + 1, true)
|
||||
else (count, false)
|
||||
}
|
||||
// println("count")
|
||||
// println(count)
|
||||
count % 2 == 1
|
||||
|
||||
case class Point(x: Int, y: Int)
|
||||
|
||||
def part2(input: String): Long =
|
||||
val points = input.split('\n').map { case s"$x,$y" => (x = x.toLong, y = y.toLong) }
|
||||
val polygon = points
|
||||
val points = input.split('\n').map { case s"$x,$y" => Point(x.toInt, y.toInt) }
|
||||
val polygon = Polygon(
|
||||
(points :+ points.head).sliding(2).map { case Array(a, b) => Edge(a, b) }.toList
|
||||
)
|
||||
|
||||
def corners(ax: Long, ay: Long, bx: Long, by: Long) =
|
||||
List((ax, ay), (ax, by), (ay, bx), (bx, by))
|
||||
def corners(a: Point, b: Point) =
|
||||
List(
|
||||
Point(min(a.x, b.x), min(a.y, b.y)),
|
||||
Point(min(a.x, b.x), max(a.y, b.y)),
|
||||
Point(max(a.x, b.x), min(a.y, b.y)),
|
||||
Point(max(a.x, b.x), max(a.y, b.y))
|
||||
).distinct
|
||||
|
||||
def isInside(x: Long, y: Long) =
|
||||
val counter = polygon.sliding(2).foldLeft(0) { case (counter, Array(a, b)) =>
|
||||
if y > min(a.y, b.y) && y <= max(a.y, b.y) && x <= max(a.x, b.x) then
|
||||
val xinters = (y - a.y) * (b.x - a.x) / (b.y - a.y) + a.x
|
||||
counter + (if a.x == b.x || x <= xinters then 1 else 0)
|
||||
else counter
|
||||
}
|
||||
counter % 2 == 1
|
||||
// println(polygon.contains(Point(9, 3)))
|
||||
|
||||
println(isInside(7, 1))
|
||||
// println(polygon.edges.mkString("\n"))
|
||||
|
||||
println(isInside(7, 2))
|
||||
println(isInside(0, 0))
|
||||
// println(polygon.edges.exists(_.contains(9, 3)))
|
||||
// println(polygon.edges.exists(_.contains(9, 5)))
|
||||
// println(polygon.contains(Point(11, 1)))
|
||||
// println(polygon.contains(Point(11, 7)))
|
||||
// println(polygon.contains(Point(11, 8)))
|
||||
// println(polygon.contains(Point(11, 9)))
|
||||
|
||||
// corners(Point(9, 5), Point(2, 3)).foreach(p =>
|
||||
// println(p)
|
||||
// println(polygon.contains(p))
|
||||
// )
|
||||
|
||||
println(
|
||||
points
|
||||
.combinations(2)
|
||||
.map { case Array(a, b) =>
|
||||
corners(a, b)
|
||||
}.distinct.size
|
||||
)
|
||||
points
|
||||
.combinations(2)
|
||||
.collect {
|
||||
case Array(a, b) if a != b && corners(a.x, a.y, b.x, b.y).forall((x, y) => isInside(x, y)) =>
|
||||
println(corners(a.x, a.y, b.x, b.y))
|
||||
case Array(a, b) if a != b && corners(a, b).forall(polygon.contains) =>
|
||||
println(corners(a, b))
|
||||
(a, b)
|
||||
}
|
||||
.map((a, b) => ((a.x - b.x + 1) * (a.y - b.y + 1)).abs)
|
||||
.max
|
||||
|
||||
// if (p.y > MIN(p1.y,p2.y)) {
|
||||
// if (p.y <= MAX(p1.y,p2.y)) {
|
||||
// if (p.x <= MAX(p1.x,p2.x)) {
|
||||
// if (p1.y != p2.y) {
|
||||
// xinters = (p.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x;
|
||||
// if (p1.x == p2.x || p.x <= xinters)
|
||||
// counter++;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
end part2
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue