diff --git a/2021/03/main.kt b/2021/03/main.kt
index 1c98121..a58f182 100644
--- a/2021/03/main.kt
+++ b/2021/03/main.kt
@@ -2,18 +2,58 @@ import java.io.File
 
 fun main() {
 	val lines = File("input/1.txt").readLines().filter(String::isNotEmpty)
-	
+	val input = Input(lines)
+	part1(input)
+	part2(input)
+}
+
+class Input(val lines: List<String>) {
 	val totalRows = lines.size
 	val totalColumns = lines[0].length
+}
+
+private fun part1(input: Input) = with(input) {
 	val totalOnesPerColumn = Array(totalColumns) { column ->
 		lines.count { it[column] == '1' }
 	}
 	
 	val gammaRate = totalOnesPerColumn
-		.map { if (it > totalRows / 2) 1 else 0 }
+		.map { if (it > totalRows - it) 1 else 0 }
 		.foldIndexed(0) { index, total, bit -> total or (bit shl (totalColumns - index - 1)) }
 	
 	val epsilonRate = gammaRate xor ((1 shl totalColumns) - 1)
 	
 	println("Power consumption: ${gammaRate * epsilonRate}")
 }
+
+private fun part2(input: Input) = with(input) {
+	
+	fun findValueByCriteria(keepMostCommon: Boolean): Int {
+		val keptLines = lines.toMutableList()
+		
+		for (column in 0 until totalColumns) {
+			val ones = keptLines.count { it[column] == '1' }
+			val zeros = keptLines.size - ones
+			
+			val keptValue = if (keepMostCommon) {
+				if (ones >= zeros) '1' else '0'
+			}
+			else {
+				if (zeros <= ones) '0' else '1'
+			}
+			
+			keptLines.removeAll { it[column] != keptValue }
+			
+			if (keptLines.size == 1) {
+				return keptLines.single().toInt(radix = 2)
+			}
+		}
+		
+		throw IllegalStateException()
+	}
+	
+	val oxygenGeneratorRating = findValueByCriteria(keepMostCommon = true)
+	val co2ScrubberRating = findValueByCriteria(keepMostCommon = false)
+	
+	println("Life support rating: ${oxygenGeneratorRating * co2ScrubberRating}")
+}