Skip to content

Instantly share code, notes, and snippets.

@segomin
Last active February 16, 2024 12:52
Show Gist options
  • Save segomin/a7b7a2e7d7748a23894c28fbd9bc7d8a to your computer and use it in GitHub Desktop.
Save segomin/a7b7a2e7d7748a23894c28fbd9bc7d8a to your computer and use it in GitHub Desktop.
aoc2023_day09.scala
import utils.loadInput
import scala.annotation.tailrec
@main def main: Unit =
val testInput = """0 3 6 9 12 15
|1 3 6 10 15 21
|10 13 16 21 30 45
|""".stripMargin
val input = loadInput("day09.txt")
assert(part1(testInput) == 114)
assert(part1(input) == 1921197370)
assert(part2(testInput) == 2)
assert(part2(input) == 1124)
def part1(testInput: String): Int = {
testInput.split("\n").foldLeft(0) { (acc, input) =>
val numbers = parseInput(input)
acc + calcLast1(numbers)
}
}
def part2(testInput: String): Int = {
testInput.split("\n").foldLeft(0) { (acc, input) =>
val numbers = parseInput(input)
acc + calcLast2(numbers)
}
}
def calcLast1(numbers: List[Int]): Int = calc(numbers, _.sum, items => items.last)
def calcLast2(numbers: List[Int]): Int = calc(numbers, _.reduce((left, right) => right - left), items => items.head)
def calc(numbers: List[Int], lastOp: List[Int] => Int, toAccItem: List[Int] => Int): Int =
@tailrec
def untilZero(numbers: List[Int], lasts: List[Int]): Int =
val next: List[Int] = numbers.sliding(2).map(pair => pair.last - pair.head).toList
if (next.forall(_ == 0)) {
lastOp(lasts.reverse)
} else {
untilZero(next, lasts :+ toAccItem(next))
}
untilZero(numbers, List(toAccItem(numbers)))
def parseInput(testInput: String): List[Int] = {
testInput.split(" ").toList.map(_.toInt)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment