Skip to content

Instantly share code, notes, and snippets.

@sangkeon
Created January 15, 2021 17:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sangkeon/a840e2985073d48e4a86aab215bfac3c to your computer and use it in GitHub Desktop.
Save sangkeon/a840e2985073d48e4a86aab215bfac3c to your computer and use it in GitHub Desktop.
import scala.io.Source;
object Main {
def main(args: Array[String]): Unit = {
val nodes = for (line <- Source.fromFile("input.txt").getLines) yield parse(line)
val navigationMap = nodes.foldLeft(Map[String, Node]()) { (m, s) => m + (s.from -> s) }
val part1 = navigationMap.keySet.filter(containsBag(navigationMap, _, "shiny gold")).size
println("part1=" + part1)
val part2 = coountBag(navigationMap, "shiny gold")
println("part2=" + part2)
}
def containsBag(navigationMap: Map[String, Node], key:String, target: String): Boolean = {
if (navigationMap.contains(key)) {
if(navigationMap(key).to.contains(target)) true
else navigationMap(key).to.keySet.exists(k => containsBag(navigationMap, k, target))
} else {
false
}
}
def coountBag(navigationMap: Map[String, Node], key:String): Int = {
if (navigationMap.contains(key)) {
val childBags = navigationMap(key).to
// toList 하지 않으면 set으로 변환되어 중복된 카운트 값이 있으면 누락됨
childBags.keys.toList.map(k => childBags(k) + childBags(k) * coountBag(navigationMap,k)).sum
} else 0
}
def parse(line: String) = {
val toks = line.split("contain")
val from = extractColor(toks(0))
val toList = for {
to <- toks(1).split(",");
totoks = parseToToks(to);
if !totoks(0).isEmpty();
} yield (extractColor(totoks(1)), totoks(0).toInt)
val toMap = toList.foldLeft(Map[String, Int]()) { (m, s) => m + (s(0) -> s(1)) }
Node(from, toMap)
}
}
def parseToToks(toks: String) = {
toks.trim().span(_.isDigit)
}
def extractColor(bags: String): String = {
bags.split("bag")(0).trim
}
case class Node(from:String, to:Map[String, Int])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment