Skip to content

Instantly share code, notes, and snippets.

@sungkmi
Created December 25, 2020 13:39
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 sungkmi/d4f30461f96c933bef09d3a97515a27f to your computer and use it in GitHub Desktop.
Save sungkmi/d4f30461f96c933bef09d3a97515a27f to your computer and use it in GitHub Desktop.
package sungkmi.aoc2020.day4
import scala.collection.JavaConverters._
import scala.util.Try
def parsePassport(lines: String): Map[String, String] =
lines.lines.iterator.asScala.flatMap(_ `split` " ").map{ (field: String) =>
val Array(k, v) = field `split` ":"
(k, v)
}.toMap
def isValid(map: Map[String, String]): Boolean =
val keys = Seq("byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid")
keys.forall(map.keySet.contains)
@main def part1: Unit =
val ans = passports.count(isValid)
println(ans)
def range(atLeast: Int, atMost: Int): String => Boolean = (v: String) =>
Try(v.toInt).toEither match
case Right(n) if atLeast <= n && n <= atMost => true
case _ => false
def regex(r: String): String => Boolean = _.matches(r)
val validations: Map[String, String => Boolean] = Map(
"byr" -> range(1920, 2002),
"iyr" -> range(2010, 2020),
"eyr" -> range(2020, 2030),
"hgt" -> {(s: String) =>
val (n, unit) = s.splitAt(s.size - 2)
unit match
case "cm" => range(150, 193)(n)
case "in" => range(59, 76)(n)
case _ => false
},
"hcl" -> regex("#([0-9]|[a-f]){6}"),
"ecl" -> regex("amb|blu|brn|gry|grn|hzl|oth"),
"pid" -> regex("[0-9]{9}"),
)
@main def part2: Unit =
val ans = passports.count{ (passport: Map[String, String]) =>
validations.forall{ (key, rule) =>
println((key, passport.get(key).map(rule)))
passport.get(key).map(rule).getOrElse(false)
}
}
println(ans)
lazy val passportStrings: Array[String] = input.split("\n\n")
lazy val passports = passportStrings `map` parsePassport
//lazy val input = """pid:827837505 byr:1976 ...
package sungkmi.aoc2020.day4
class Day4Test extends munit.FunSuite {
test("parse passport") {
val s = """ecl:gry pid:860033327 eyr:2020 hcl:#fffffd
byr:1937 iyr:2017 cid:147 hgt:183cm"""
val expected = Map(
"ecl" -> "gry",
"pid" -> "860033327",
"eyr" -> "2020",
"hcl" -> "#fffffd",
"byr" -> "1937",
"iyr" -> "2017",
"cid" -> "147",
"hgt" -> "183cm",
)
assertEquals(parsePassport(s), expected)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment