Skip to content

Instantly share code, notes, and snippets.

@waynejo
Last active December 25, 2020 12:24
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 waynejo/6116d0a545fb44dce5f9600881c1f7b4 to your computer and use it in GitHub Desktop.
Save waynejo/6116d0a545fb44dce5f9600881c1f7b4 to your computer and use it in GitHub Desktop.
import java.io.FileInputStream
import scala.io.StdIn
@main def solve4() =
val validKeys: Set[String] = Set("byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid")
def isValid(passport: Vector[(String, String)]): Boolean = {
val keys = passport.map { _._1 }.toSet
val elemnts = passport.toMap
def checkRangedNumber(min: Int, max: Int, value: String): Boolean = {
value.nonEmpty && value.forall(_.isDigit) && min <= value.toInt && max >= value.toInt
}
def hasAllKeys: Boolean = {
(validKeys diff keys).isEmpty
}
def checkByr: Boolean = checkRangedNumber(1920, 2002, elemnts.getOrElse("byr", ""))
def checkIyr: Boolean = checkRangedNumber(2010, 2020, elemnts.getOrElse("iyr", ""))
def checkEyr: Boolean = checkRangedNumber(2020, 2030, elemnts.getOrElse("eyr", ""))
def checkHgt: Boolean = {
val hgt = elemnts.getOrElse("hgt", "")
if hgt.endsWith("cm") then
checkRangedNumber(150, 193, hgt.substring(0, hgt.size - 2))
else if hgt.endsWith("in") then
checkRangedNumber(59, 76, hgt.substring(0, hgt.size - 2))
else
false
}
def checkHcl: Boolean = {
val hcl = elemnts.getOrElse("hcl", "")
hcl.size == 7 && hcl(0) == '#' && hcl.tail.forall(c => c.isDigit || ('a' <= c && c <= 'f'))
}
def checkEcl: Boolean = {
val validElements = Set("amb", "blu", "brn", "gry", "grn", "hzl", "oth")
validElements.contains(elemnts.getOrElse("ecl", ""))
}
def checkPid: Boolean = {
val pid = elemnts.getOrElse("pid", "")
pid.size == 9 && pid.forall(_.isDigit)
}
val validators = Vector(
hasAllKeys,
checkByr,
checkIyr,
checkEyr,
checkHgt,
checkHcl,
checkEcl,
checkPid,
)
validators.forall(_ == true)
}
val in = new FileInputStream("example4-1.in")
System.setIn(in)
val inputs = Iterator.continually(StdIn.readLine()).takeWhile(_ != null).toVector
val passportElements = inputs.foldLeft(Vector[Vector[(String, String)]](Vector())) { (acc, line) =>
if line.trim.isEmpty then
acc :+ Vector()
else
acc.init :+ (acc.last ++ line.split(" ").map { x =>
val Array(key, value) = x.split(":")
(key, value)
}.toVector)
}
println(passportElements.count(isValid))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment