Day 3
This commit is contained in:
parent
b0c1df3eb3
commit
1747cd8c93
2 changed files with 1084 additions and 0 deletions
1000
aoc/resources/day3Input.txt
Normal file
1000
aoc/resources/day3Input.txt
Normal file
File diff suppressed because it is too large
Load diff
84
aoc/src/Day3.scala
Normal file
84
aoc/src/Day3.scala
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
import scala.io.Source
|
||||||
|
|
||||||
|
object Day3 extends App:
|
||||||
|
|
||||||
|
val input = Source
|
||||||
|
.fromURL(getClass.getResource("day3Input.txt"))
|
||||||
|
.mkString
|
||||||
|
.split('\n')
|
||||||
|
.map(_.toArray.map(Bit.parse))
|
||||||
|
|
||||||
|
enum Bit:
|
||||||
|
case One, Zero
|
||||||
|
|
||||||
|
def flip() = this match
|
||||||
|
case One => Zero
|
||||||
|
case Zero => One
|
||||||
|
|
||||||
|
override def toString() = this match
|
||||||
|
case One => "1"
|
||||||
|
case Zero => "0"
|
||||||
|
|
||||||
|
object Bit:
|
||||||
|
def parse(char: Char): Bit = char match
|
||||||
|
case '1' => One
|
||||||
|
case '0' => Zero
|
||||||
|
|
||||||
|
import Bit._
|
||||||
|
|
||||||
|
def findMostCommonBit(bits: Array[Bit]): Bit =
|
||||||
|
if (bits.count(_ == One) > bits.count(_ == Zero)) One
|
||||||
|
else Zero
|
||||||
|
|
||||||
|
val gamma = input.transpose
|
||||||
|
.map(findMostCommonBit)
|
||||||
|
|
||||||
|
val epsilon = gamma.map(_.flip())
|
||||||
|
|
||||||
|
val part1 =
|
||||||
|
Integer.parseInt(gamma.mkString, 2) * Integer.parseInt(epsilon.mkString, 2)
|
||||||
|
|
||||||
|
println(s"Part 1: $part1")
|
||||||
|
|
||||||
|
// Part 2
|
||||||
|
|
||||||
|
enum BitCriteria(val selectBitByCount: (Int, Int) => Bit):
|
||||||
|
case OxygenGeneratorRating
|
||||||
|
extends BitCriteria((onesCount, zerosCount) =>
|
||||||
|
if (onesCount >= zerosCount) One else Zero
|
||||||
|
)
|
||||||
|
case CO2ScrubberRating
|
||||||
|
extends BitCriteria((onesCount, zerosCount) =>
|
||||||
|
if (onesCount < zerosCount) One else Zero
|
||||||
|
)
|
||||||
|
|
||||||
|
import BitCriteria._
|
||||||
|
|
||||||
|
def filterByBitCriteria(
|
||||||
|
filteredBitIndex: Int,
|
||||||
|
numbers: Array[Array[Bit]],
|
||||||
|
bitCriteria: BitCriteria
|
||||||
|
): Array[Bit] =
|
||||||
|
val filteredBits = numbers.map(_(filteredBitIndex))
|
||||||
|
val onesCount = filteredBits.count(_ == One)
|
||||||
|
val zeroesCount = filteredBits.count(_ == Zero)
|
||||||
|
val headToKeep = bitCriteria.selectBitByCount(onesCount, zeroesCount)
|
||||||
|
val filteredNumbers = numbers.filter(_(filteredBitIndex) == headToKeep)
|
||||||
|
|
||||||
|
if (filteredNumbers.length == 1)
|
||||||
|
filteredNumbers.head
|
||||||
|
else
|
||||||
|
filterByBitCriteria(filteredBitIndex + 1, filteredNumbers, bitCriteria)
|
||||||
|
|
||||||
|
val oxygenGeneratorRating =
|
||||||
|
Integer.parseInt(
|
||||||
|
filterByBitCriteria(0, input, OxygenGeneratorRating).mkString,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
val cO2ScrubberRating =
|
||||||
|
Integer.parseInt(
|
||||||
|
filterByBitCriteria(0, input, CO2ScrubberRating).mkString,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
|
||||||
|
println(s"Part 2: ${oxygenGeneratorRating * cO2ScrubberRating}")
|
||||||
Loading…
Add table
Add a link
Reference in a new issue