1
+ package advent2021
2
+
3
+ import Resources
4
+ import kotlin.math.pow
5
+
6
+ class Day03 (private val input : List <String >) {
7
+
8
+ private val inputWidth = input.first().length
9
+
10
+ fun solvePart1 (): Int {
11
+ val gamma = (0 until inputWidth).sumOf { column ->
12
+ val columnValue = (inputWidth - column - 1 ).binaryColumnValue()
13
+ if (input.count { it[column] == ' 1' } > input.size / 2 ) columnValue else 0
14
+ }
15
+ return gamma * (inputWidth.maxBinaryValue() - gamma)
16
+ }
17
+
18
+ private fun Int.binaryColumnValue (): Int =
19
+ 2.0 .pow(this .toDouble()).toInt()
20
+
21
+ private fun Int.maxBinaryValue (): Int =
22
+ binaryColumnValue() - 1
23
+
24
+ fun solvePart2 (): Int =
25
+ input.bitwiseFilter(true ).toInt(2 ) * input.bitwiseFilter(false ).toInt(2 )
26
+
27
+ private fun List<String>.bitwiseFilter (keepMostCommon : Boolean ): String =
28
+ (0 until inputWidth).fold(this ) { inputs, column ->
29
+ if (inputs.size == 1 ) inputs else {
30
+ val split = inputs.partition { it[column] == ' 1' }
31
+ if (keepMostCommon) split.longest() else split.shortest()
32
+ }
33
+ }.first()
34
+
35
+ private fun <T > Pair <List <T >,List<T>>.longest (): List <T > =
36
+ if (first.size >= second.size) first else second
37
+
38
+ private fun <T > Pair <List <T >,List<T>>.shortest (): List <T > =
39
+ if (first.size < second.size) first else second
40
+ }
41
+
42
+ fun main () {
43
+ val input = Resources .resourceAsListOfString(" advent2021/day03.txt" )
44
+ val day = Day03 (input = input)
45
+ println (" Part 1: ${day.solvePart1()} " )
46
+ println (" Part 2: ${day.solvePart2()} " )
47
+ }
0 commit comments