generated from kotlin-hands-on/advent-of-code-kotlin-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay02.kt
97 lines (82 loc) · 2.78 KB
/
Day02.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
/**
* DAY 02 - Red-Nosed Reports
*
* Feels like there should be a more efficient way than my solution
* But it's late and I'm tired after having my latest COVID shot!
*/
package aoc2024
import utils.println
import utils.readInput
import kotlin.math.abs
import kotlin.math.sign
fun main() {
fun parseReports(input: List<String>): List<List<Int>> {
val reports = mutableListOf<List<Int>>()
for (line in input) {
val values = line.split(' ')
val levels = values.map { it.toInt() }
reports.add(levels)
}
return reports.toList()
}
fun safeReport(report: List<Int>): Boolean {
var isSafe = true
var directions = 0
// Work thru pairs of levels
for (i in 0 until report.size - 1) {
// Find difference
val diff = report[i + 1] - report[i]
// Bail out if too large
if (abs(diff) > 3) {
isSafe = false
break
}
// Otherwise sum the signs (to check if all in same direction)
directions += diff.sign
}
// Didn't fail already, and all diffs in same direction?
return isSafe && (abs(directions) == report.size - 1)
}
// Safe if all levels trending same way, and with differences <= 3
fun safeReportCount(reports: List<List<Int>>): Int {
var count = 0
for (report in reports) {
if (safeReport(report)) count++
}
return count
}
// Safe if all bar 0 or 1 levels trending same way, and with differences <= 3
fun safeDampedReportCount(reports: List<List<Int>>): Int {
var count = 0
for (report in reports) {
// Is this report safe already?
if (safeReport(report)) {
// Yep, so count and onto next
count++
continue
}
// Nope, so work thru removing a value and rechecking
for (i in report.indices) {
val dampedReport = report.toMutableList()
dampedReport.removeAt(i)
// Does this version work?
if (safeReport(dampedReport)) {
// Yep, so count and no point checking more versions
count++
break
}
}
}
return count
}
// Check given test values:
val testInput = readInput(2024, "Day02_test")
val testReports = parseReports(testInput)
check(safeReportCount(testReports) == 2)
check(safeDampedReportCount(testReports) == 4)
// Work through the real data
val input = readInput(2024, "Day02")
val reports = parseReports(input)
safeReportCount(reports).println()
safeDampedReportCount(reports).println()
}