Commit 0a5e9798 authored by David's avatar David

Puzzle 3 part 1, before submitting

parent 10610d07
package is.kow.adventofcode._2019
import scala.annotation.tailrec
import scala.io.Source
import scala.util.matching.Regex
class Puzzle3 {
def distance(resource: String): Int = {
//load from resource
val source = Source.fromResource(resource)
try {
//Two lines
val lines = source.getLines().toList
val wire1String = lines.head
val wire2String = lines.tail.head
val wire1Path = wirePath(wire1String.split(",").toList).reverse
println()
val wire2Path = wirePath(wire2String.split(",").toList).reverse
println("WIRE 1: " + wire1Path)
println("WIRE 2: " + wire2Path)
//Find all the intersections
val points: List[Point] = wire1Path.iterator.flatMap { wire1 =>
//See if it intersects with any wire, and get that point
wire2Path.map { wire2 =>
wire1.intersects2(wire2)
}.filter(_.isDefined)
.map(_.get)
}.toList
//Don't count 0,0
val intersections = points.drop(1)
println("Intersecting points: " + intersections)
val distances = intersections.map(manhattanDistance(Point(0, 0), _));
val smallest = distances.foldLeft(distances.head) { (acc, v) =>
if (v < acc) {
v
} else {
acc
}
}
smallest
} finally {
source.close()
}
}
private def manhattanDistance(p: Point, q: Point): Int = {
Math.abs(p.x - q.x) + Math.abs(p.y - q.y)
}
private def wirePath(ins: List[String]): List[Wire] = {
val up: Regex = raw"U([0-9]+)".r
val down = raw"D([0-9]+)".r
val left = raw"L([0-9]+)".r
val right = raw"R([0-9]+)".r
@tailrec def mapPath(acc: List[Wire], startPoint: Point, ops: List[String]): List[Wire] = {
if (ops.isEmpty) {
acc
} else {
val wire = ops.head match {
case up(dist) =>
Wire(startPoint, startPoint.copy(y = startPoint.y + dist.toInt))
case down(dist) =>
Wire(startPoint, startPoint.copy(y = startPoint.y - dist.toInt))
case left(dist) =>
Wire(startPoint, startPoint.copy(x = startPoint.x - dist.toInt))
case right(dist) =>
Wire(startPoint, startPoint.copy(x = startPoint.x + dist.toInt))
}
println(s"${ops.head}: ${wire}")
//Got a wire, accumulate it, and get point
mapPath(wire :: acc, wire.end, ops.tail)
}
}
mapPath(List.empty, Point(0, 0), ins)
}
}
package is.kow.adventofcode._2019
case class Point(x: Int, y: Int)
object Point {
def apply(pair: (Int, Int)): Point = {
Point(pair._1, pair._2)
}
}
case class Wire(start: Point, end: Point) {
val isVertical: Boolean = start.x == end.x
val isHorizontal: Boolean = start.y == end.y
//BLECH I feel like this is super wrong and lame
val points: List[(Int, Int)] = {
if (isHorizontal) {
val range = if (start.x < end.x) {
(start.x to end.x)
} else {
end.x to start.x
}
range.map(x =>
(x, start.y)
).toList
} else {
val range = if (start.y < end.y) {
start.y to end.y
} else {
end.y to start.y
}
range.map(y =>
(start.x, y)).toList
}
}
def intersects2(other: Wire): Option[Point] = {
val intersection = this.points.intersect(other.points)
if (intersection.isEmpty) {
Option.empty
} else {
Option(Point(intersection.head))
}
}
}
R8,U5,L5,D3
U7,R6,D4,L4
\ No newline at end of file
R75,D30,R83,U83,L12,D49,R71,U7,L72
U62,R66,U55,R34,D71,R55,D58,R83
\ No newline at end of file
R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51
U98,R91,D20,R16,D67,R40,U7,R15,U6,R7
\ No newline at end of file
package is.kow.adventofcode._2019
import org.junit.runner.RunWith
import org.scalatest.funspec.AnyFunSpec
import org.scalatestplus.junit.JUnitRunner
case class Wires(wire1: List[String], wire2: List[String], distance: Int)
@RunWith(classOf[JUnitRunner])
class Puzzle3Spec extends AnyFunSpec {
def p3 = new Puzzle3
describe("Day 3 Part 1") {
List(
("test1.txt", 6),
("test2.txt", 159),
("test3.txt", 135)
).foreach {
case (resource, expected) => {
it(s"for input ${resource} expect $expected") {
assert(p3.distance(resource) == expected)
}
}
}
}
}
include("1", "2", "4")
include("1", "2", "3", "4")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment