-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay4.kt
108 lines (91 loc) · 3.33 KB
/
Day4.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package aoc2020.day04
import java.io.File
import java.io.InputStream
fun readInputFile(path: String): List<String> {
val inputStream: InputStream = File(path).inputStream()
val lineList = mutableListOf<String>()
inputStream.bufferedReader().forEachLine { lineList.add(it) }
val passportDataList = mutableListOf<String>()
var passportData = ""
for (line in lineList) {
if (line.isNotEmpty()) {
passportData += if (passportData.isBlank()) { line } else { " $line" }
} else {
passportDataList.add(passportData)
passportData = ""
}
}
return passportDataList
}
fun arePassportKeysValid(passportData: String): Boolean {
return listOf("byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid").all { passportData.contains(it) }
}
fun isYearValid(dataMap: Map<String, String>, key: String, min: Int, max: Int): Boolean {
val year: Int? = dataMap[key]?.toIntOrNull()
return !(year == null || year < min || year > max)
}
fun isHeightValid(height: String): Boolean {
if (height.endsWith("in")) {
val heightVal = height.replace("in", "").toInt()
if (heightVal < 59 || heightVal > 76) {
return false
}
} else if (height.endsWith("cm")) {
val heightVal = height.replace("cm", "").toInt()
if (heightVal < 150 || heightVal > 193) {
return false
}
} else {
return false
}
return true
}
fun isStringValid(dataMap: Map<String, String>, key: String, regex: Regex): Boolean {
val stringVal: String? = dataMap[key]
return stringVal != null && stringVal.matches(regex)
}
fun isPassportDataValid(passportData: String): Boolean {
if (!arePassportKeysValid(passportData)) {
return false
}
val dataMap = mutableMapOf<String, String>()
passportData.split(" ")
.asSequence()
.map { it.split(":") }
.forEach { dataMap[it[0]] = it[1] }
//byr (Birth Year) - four digits; at least 1920 and at most 2002.
if (!isYearValid(dataMap, "byr", 1920, 2002)) {
return false
}
//iyr (Issue Year) - four digits; at least 2010 and at most 2020.
if (!isYearValid(dataMap, "iyr", 2010, 2020)) {
return false
}
//eyr (Expiration Year) - four digits; at least 2020 and at most 2030.
if (!isYearValid(dataMap, "eyr", 2020, 2030)) {
return false
}
//hgt (Height) - a number followed by either cm or in:
// If cm, the number must be at least 150 and at most 193.
// If in, the number must be at least 59 and at most 76.
val height: String = dataMap["hgt"] ?: return false
if (!isHeightValid(height)) {
return false
}
//hcl (Hair Color) - a # followed by exactly six characters 0-9 or a-f.
if (!isStringValid(dataMap, "hcl", Regex("""#[0-9a-fA-F]{6}"""))) {
return false
}
//ecl (Eye Color) - exactly one of: amb blu brn gry grn hzl oth.
if (!isStringValid(dataMap, "ecl", Regex("""amb|blu|brn|gry|grn|hzl|oth"""))) {
return false
}
//pid (Passport ID) - a nine-digit number, including leading zeroes.
if (!isStringValid(dataMap, "pid", Regex("""[0-9]{9}"""))) {
return false
}
return true
}
fun countValidPassports(dataList: List<String>, validationMethod: (String) -> Boolean): Int {
return dataList.count { validationMethod(it) }
}