2023-12-03 15:50:17 +00:00
|
|
|
package aoc.day1
|
2023-12-01 15:01:45 +00:00
|
|
|
|
2023-12-02 14:31:39 +00:00
|
|
|
import aoc._
|
|
|
|
|
2023-12-03 15:50:17 +00:00
|
|
|
// Part 1
|
|
|
|
|
2023-12-01 15:01:45 +00:00
|
|
|
def literalDigits(s: String) =
|
|
|
|
s.toSeq.filter(_.isDigit).map(v => (v - '0').toInt)
|
|
|
|
|
|
|
|
def getValue(toDigits: String => Seq[Int])(s: String): Int =
|
|
|
|
val digits = toDigits(s)
|
|
|
|
digits.head * 10 + digits.last
|
|
|
|
|
|
|
|
def getSum(toDigits: String => Seq[Int]) =
|
|
|
|
val values =
|
2023-12-02 14:31:39 +00:00
|
|
|
lines.map(getValue(toDigits))
|
2023-12-01 15:01:45 +00:00
|
|
|
println(values.sum)
|
|
|
|
|
|
|
|
// Part 2
|
|
|
|
|
|
|
|
val englishDigits =
|
|
|
|
Seq("one", "two", "three", "four", "five", "six", "seven", "eight", "nine")
|
|
|
|
|
|
|
|
def literalOrEnglishDigits(s: String) =
|
|
|
|
@scala.annotation.tailrec
|
|
|
|
def loop(idx: Int, accum: Seq[Int]): Seq[Int] =
|
|
|
|
if idx < 0 then accum
|
|
|
|
else if s(idx).isDigit then loop(idx - 1, (s(idx) - '0').toInt +: accum)
|
|
|
|
else
|
|
|
|
val toMatch = s.slice(idx, idx + 5 /* enough to match english */ )
|
|
|
|
val digit = englishDigits.indexWhere(toMatch.startsWith _)
|
|
|
|
val nAccum = if digit == -1 then accum else (digit + 1) +: accum
|
|
|
|
loop(idx - 1, nAccum)
|
|
|
|
loop(s.length() - 1, Seq.empty)
|
|
|
|
|
2023-12-02 14:31:39 +00:00
|
|
|
@main def Day1(part: Int) = part match
|
2023-12-01 15:01:45 +00:00
|
|
|
case 1 => getSum(literalDigits)
|
|
|
|
case 2 => getSum(literalOrEnglishDigits)
|