This commit is contained in:
Paul-Henri Froidmont 2023-12-04 11:45:17 +01:00
parent 44da9ddd56
commit caeb832cd5
Signed by: phfroidmont
GPG key ID: BE948AFD7E7873BE
2 changed files with 212 additions and 0 deletions

72
src/day03.scala Normal file
View file

@ -0,0 +1,72 @@
package aoc
package day03
import scala.annotation.tailrec
val dayNumber = "03"
@main def part1: Unit =
println(part1(loadInput(dayNumber)))
@main def part2: Unit =
println(part2(loadInput(dayNumber)))
final case class Coord(x: Int, y: Int)
final case class PartNumber(number: Int, coord: Coord, length: Int):
def isAdjacentTo(aCoord: Coord) =
coord.x - 1 <= aCoord.x && coord.x + length >= aCoord.x &&
coord.y - 1 <= aCoord.y && coord.y + 1 >= aCoord.y
def parseLine(line: String, y: Int): List[PartNumber] =
@tailrec def aux(startsAt: Int, acc: List[PartNumber]): List[PartNumber] =
if startsAt >= line.length - 1 then acc
else if line(startsAt).isDigit then
val number = parseNumber(startsAt, line, y)
aux(startsAt + number.length, number :: acc)
else aux(startsAt + 1, acc)
aux(0, List())
def findCoords(lines: Array[String], filter: Char => Boolean) =
for
x <- (0 to lines(0).length - 1)
y <- (0 to lines.length - 1)
if (filter(lines(y)(x)))
yield Coord(x, y)
def parseNumber(startsAt: Int, line: String, y: Int): PartNumber =
val digits = line.drop(startsAt).takeWhile(_.isDigit)
PartNumber(digits.toInt, Coord(startsAt, y), length = digits.length)
def part1(input: String): String =
val lines = input.split("\n")
def isSymbol(char: Char) = !(char.isDigit || char == '.')
val symbolsCoords = findCoords(lines, isSymbol)
lines.zipWithIndex
.flatMap(parseLine)
.filter(p => symbolsCoords.exists(p.isAdjacentTo(_)))
.map(_.number)
.sum
.toString
def part2(input: String): String =
def isGearSymbol(char: Char) = char == '*'
val lines = input.split("\n")
val gearsCoords = findCoords(lines, isGearSymbol)
val parts =
lines.zipWithIndex
.flatMap(parseLine)
gearsCoords
.map(g => parts.filter(_.isAdjacentTo(g)))
.collect {
case parts if parts.length == 2 => parts.map(_.number).product
}
.sum
.toString