Day 3
This commit is contained in:
parent
44da9ddd56
commit
caeb832cd5
2 changed files with 212 additions and 0 deletions
72
src/day03.scala
Normal file
72
src/day03.scala
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue