|  | 
|  | 1 | +import io.Source | 
|  | 2 | +import scala.util.Using | 
|  | 3 | +import scala.collection.mutable.ListBuffer | 
|  | 4 | + | 
|  | 5 | +type Lock = List[Int] | 
|  | 6 | +type Key = List[Int] | 
|  | 7 | + | 
|  | 8 | +def readLocksAndKeys(filename: String) = | 
|  | 9 | +  val tmp = Using(Source.fromFile(filename)) { | 
|  | 10 | +    _.getLines.foldLeft((List[List[String]](), List[String]())) { (acc, l) => | 
|  | 11 | +      val (schemas, currentSchema) = acc | 
|  | 12 | +      if l.isEmpty then (schemas :+ currentSchema, List[String]()) | 
|  | 13 | +      else (schemas, currentSchema :+ l) | 
|  | 14 | +    } | 
|  | 15 | +  }.get | 
|  | 16 | +  val schemas = tmp._1 :+ tmp._2 | 
|  | 17 | + | 
|  | 18 | +  schemas.foldLeft((List[Lock](), List[Lock]())) { | 
|  | 19 | +    (lockAndKeyAcc, schemaLines) => | 
|  | 20 | +      val (locks, keys) = lockAndKeyAcc | 
|  | 21 | +      val schema = (0 until schemaLines(0).length) | 
|  | 22 | +        .map(i => schemaLines.filter(l => l(i) == '#').length - 1) | 
|  | 23 | +        .toList | 
|  | 24 | + | 
|  | 25 | +      if schemaLines(0).forall(_ == '#') then (locks :+ schema, keys) | 
|  | 26 | +      else (locks, keys :+ schema) | 
|  | 27 | +  } | 
|  | 28 | + | 
|  | 29 | +def solve(locks: List[Lock], keys: List[Key]) = | 
|  | 30 | +  locks | 
|  | 31 | +    .map(lock => | 
|  | 32 | +      keys | 
|  | 33 | +        .filter(key => lock.zip(key).map((l, k) => l + k).forall(_ <= 5)) | 
|  | 34 | +        .length | 
|  | 35 | +    ) | 
|  | 36 | +    .sum | 
|  | 37 | + | 
|  | 38 | +@main def main(filename: String) = | 
|  | 39 | +  val (locks, keys) = readLocksAndKeys(filename) | 
|  | 40 | +  println(solve(locks, keys)) | 
0 commit comments