Commit 7e8149d4 authored by David's avatar David

Day 6!

parent 75d061ca
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %.15c{1.} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="is.kow.adventofcode._2019" level="DEBUG"/>
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
\ No newline at end of file
package is.kow.adventofcode._2019
import scala.io.Source
object Main extends App {
val source = Source.fromResource("input.txt")
try {
val orbitCodes = source.getLines().toList
val p = new Puzzle6()
val orbits = p.parseInput(orbitCodes)
val totalOrbits = p.countAllOrbits(orbits.values.toList)
println(s"Total orbits: $totalOrbits")
val transfers = p.orbitalTransfersFromYouToSAN(orbits)
println(s"Transfers: $transfers")
} finally {
source.close()
}
}
package is.kow.adventofcode._2019
import com.typesafe.scalalogging.LazyLogging
import scala.annotation.tailrec
sealed trait Node
case object COM extends Node
case class Body(name: String, orbits: Node) extends Node
class Puzzle6 extends LazyLogging {
def parseInput(orbitCode: List[String]): Map[String, Node] = {
// PARENT ) Node
//TODO: this algorithm is terribly inefficient!
@tailrec def buildOrbits(orbitCodes: List[String], acc: Map[String, Node] = Map("COM" -> COM)): Map[String, Node] = {
if (orbitCodes.isEmpty) {
acc
} else {
val code = orbitCodes.head
code.split(raw"\)").toList match {
case parent :: body :: xs =>
if (acc.contains(parent)) {
//Damnit, the list isn't sorted, may have to defer things
val orbitTarget = acc(parent) //NOTE: orbital body should always exist
val satellite = Body(body, orbitTarget)
buildOrbits(orbitCodes.tail, acc.updated(body, satellite))
} else {
//it's not there, defer it until later, not efficient, but lazy
buildOrbits(orbitCodes.tail :+ code, acc)
}
}
}
}
buildOrbits(orbitCode)
}
@tailrec private def buildPathToNode(end: Node, node: Node, acc: List[Node] = List.empty): List[Node] = {
node match {
case x if (x == end) => acc
case Body(_, orbits) => buildPathToNode(end, orbits, acc :+ orbits)
}
}
def pathToCOM(node: Node): List[Node] = {
buildPathToNode(COM, node)
}
def countAllOrbits(bodies: List[Node]): Int = {
bodies.foldLeft(0) { (acc, node) =>
acc + pathToCOM(node).length
}
}
def orbitalTransfersFromYouToSAN(bodyMap: Map[String, Node]): Int = {
val you = bodyMap("YOU")
val santa = bodyMap("SAN")
//find list of YOU to COM
val youPath = pathToCOM(you)
//find list of SAN to COM
val santaPath = pathToCOM(santa)
//find intersection
val intersection = youPath.intersect(santaPath).head
val youLength = youPath.takeWhile(_ != intersection).length
val santaLength = santaPath.takeWhile(_ != intersection).length
youLength + santaLength
}
}
COM)B
B)C
C)D
D)E
E)F
B)G
G)H
D)I
E)J
J)K
K)L
D)E
D)I
E)J
E)F
J)K
B)C
G)H
K)L
C)D
B)G
COM)B
COM)B
B)C
C)D
D)E
E)F
B)G
G)H
D)I
E)J
J)K
K)L
K)YOU
I)SAN
package is.kow.adventofcode._2019
import org.junit.runner.RunWith
import org.scalatest.funspec.AnyFunSpec
import org.scalatestplus.junit.JUnitRunner
import scala.io.Source
@RunWith(classOf[JUnitRunner])
class Puzzle6Spec extends AnyFunSpec {
describe("Puzzle 6 part 1") {
List(
("1", 42),
("2", 42),
).foreach { case (resource, expected) =>
it(s"should get ${expected} for test orbits $resource") {
val source = Source.fromResource(resource + ".txt")
try {
val lines = source.getLines().toList
val p = new Puzzle6
val nodes = p.parseInput(lines)
assert(p.countAllOrbits(nodes.values.toList) == expected )
} finally {
source.close()
}
}
}
}
describe("Puzzle 6 part 2") {
List(
("3", 4),
).foreach { case (resource, expected) =>
it(s"should get ${expected} to get to santa for $resource") {
val source = Source.fromResource(resource + ".txt")
try {
val lines = source.getLines().toList
val p = new Puzzle6
val nodes = p.parseInput(lines)
assert(p.orbitalTransfersFromYouToSAN(nodes) == expected )
} finally {
source.close()
}
}
}
}
}
include("01", "02", "03", "04", "05")
include("01", "02", "03", "04", "05", "06")
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