Skip to content

Instantly share code, notes, and snippets.

@sungkmi
Last active January 1, 2022 14:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sungkmi/8f9ed15e8ff98eaa41bfaa78c81c6ea3 to your computer and use it in GitHub Desktop.
Save sungkmi/8f9ed15e8ff98eaa41bfaa78c81c6ea3 to your computer and use it in GitHub Desktop.
package lascala.aoc2021.day1_10.day3
import javax.tools.Diagnostic
case class DiagnosticReport(
width: Int,
bits: Seq[BigInt],
)
extension (d: DiagnosticReport)
def gammaRate: BigInt = BigInt((0 until d.width).map { i =>
if d.bits.map(_.testBit(i)).count(_ == true) * 2 > d.bits.size then "1" else "0"
}.reverse.mkString, 2)
def epsilonRate: BigInt = BigInt((0 until d.width).map { i =>
if d.bits.map(_.testBit(i)).count(_ == true) * 2 < d.bits.size then "1" else "0"
}.reverse.mkString, 2)
def powerComsumption: BigInt =
gammaRate * epsilonRate
def oxygen: BigInt =
def loop(index: Int, bits: Seq[BigInt]): BigInt =
if bits.size == 1 then bits.head else
val countSet = bits.map(_.testBit(index)).count(_ == true)
val mostCommon = if countSet * 2 >= bits.size then true else false
val nextBits = bits.filter(_.testBit(index) == mostCommon)
loop(index - 1, nextBits)
loop(d.width - 1, d.bits)
def co2: BigInt =
def loop(index: Int, bits: Seq[BigInt]): BigInt =
if bits.size == 1 then bits.head else
val countSet = bits.map(_.testBit(index)).count(_ == true)
val leastCommon = if countSet * 2 < bits.size then true else false
val nextBits = bits.filter(_.testBit(index) == leastCommon)
loop(index - 1, nextBits)
loop(d.width - 1, d.bits)
def lifeSupporting: BigInt = oxygen * co2
object DiagnosticReport:
def parse(s: String): DiagnosticReport =
val lines = s.split("\n")
DiagnosticReport(
width = lines.head.size,
bits = lines.map{ line => BigInt(line, 2) }
)
def solve1(s: String): BigInt = DiagnosticReport.parse(s).powerComsumption
def solve2(s: String): BigInt = DiagnosticReport.parse(s).lifeSupporting
@main def part1: Unit =
val ans = solve1(input)
println(ans)
@main def part2: Unit =
val ans = solve2(input)
println(ans)
//val input = """111111010011
package lascala.aoc2021.day1_10.day3
import minitest.SimpleTestSuite
import hedgehog.minitest.HedgehogSupport
import hedgehog.*
object Day3Test extends SimpleTestSuite with HedgehogSupport:
val exampleInput: String = """00100
11110
10110
10111
10101
01111
00111
11100
10000
11001
00010
01010"""
example("day3 - gammaRate") {
val d = DiagnosticReport.parse(exampleInput)
d.gammaRate.toString(2) ==== "10110"
}
example("day3 - epsilonRate") {
val d = DiagnosticReport.parse(exampleInput)
d.epsilonRate ==== 9
}
example("day3 - oxygen") {
val d = DiagnosticReport.parse(exampleInput)
d.oxygen ==== 23
}
example("day3 - co2") {
val d = DiagnosticReport.parse(exampleInput)
d.co2 ==== 10
}
example("day3 - solve1") {
solve1(exampleInput) ==== 198
}
example("day3 - solve2") {
solve2(exampleInput) ==== 230
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment