1. import scala.collection.mutable.Map
  2. import scala.collection.mutable.Set
  3. case class Field(name:String, a: Int, b:Int, c:Int, d:Int){
  4. def good(x: Int) = (x >= a && x <= b) || (x >= c && x <= d)
  5. }
  6. object Field {
  7. def apply(line: String) : Field = {
  8. val Array(name, values) = line.split(": ")
  9. val Array(a,b,c,d) = values.split(" or ").map(_.split("-")) .flatten.map(_.toInt)
  10. Field(name, a, b, c, d)
  11. }
  12. }
  13. val C = io.Source.fromFile("input").getLines.toList
  14. val fields = C.takeWhile(_.size>0).map(Field.apply)
  15. val mine = C.dropWhile(_.size>0).drop(2).head.split(",").map(_.toInt).toArray
  16. val nearBy= C.dropWhile(_.size>0).drop(5).map(_.split(",").map(_.toInt)).map(_.toList)
  17. val goods = Set[Int]()
  18. for(x <- 1 to 1000) {
  19. if(fields.exists(f => f.good(x))) goods.add(x)
  20. }
  21. val validNear = nearBy.filter{ near =>
  22. near.filterNot(goods).isEmpty
  23. }
  24. var order : List[(Int, List[Field])] = Nil
  25. for(col <- 0 until nearBy.head.size){
  26. val vertValues = validNear.map(_.drop(col).head)
  27. val chosenFields = fields.filter(f => vertValues.forall(f.good))
  28. println(col+ " => " + chosenFields.map(_.name).size)
  29. order = (col, chosenFields) :: order
  30. }
  31. val check = order.sortBy(_._2.size)
  32. val woozy = check.map(o => (o._1, o._2.map(_.name).toSet))
  33. val result = Map[Int, String]()
  34. val found = Set[String]()
  35. woozy.foreach {
  36. case (idx, wuss) => {
  37. val curr = wuss.diff(found)
  38. result(idx) = curr.head
  39. found.add(curr.head)
  40. }
  41. }
  42. val recipe = result.filter {
  43. case (k, v) => v.contains("departure")
  44. }
  45. println("Recipe " + recipe)
  46. val woah = recipe.keys.map(k => mine(k)).map(_.toLong).product
  47. println(woah)