Skip to content

Commit

Permalink
feat: prepare for interactive 2024 solution (#729)
Browse files Browse the repository at this point in the history
* build: setup for 2024

* feat(2024): day 13
  • Loading branch information
scarf005 authored Dec 17, 2024
1 parent b4e27f5 commit 0a09b49
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 0 deletions.
48 changes: 48 additions & 0 deletions 2024/src/day13.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package day13

import locations.Directory.currentDir
import inputs.Input.loadFileSync

@main def part1: Unit =
println(s"The solution is ${part1(loadInput())}")

@main def part2: Unit =
println(s"The solution is ${part2(loadInput())}")

def loadInput(): String = loadFileSync(s"$currentDir/../input/day13")

case class Claw(ax: Long, ay: Long, bx: Long, by: Long, x: Long, y: Long):
def solve: Option[Long] = for
b <- (x * ay - y * ax) safeDiv (bx * ay - by * ax)
a <- (x - b * bx) safeDiv ax
yield a * 3 + b

object Claw:
def parse(xs: Seq[String]): Option[Claw] = xs match
case Seq(
s"Button A: X+${L(ax)}, Y+${L(ay)}",
s"Button B: X+${L(bx)}, Y+${L(by)}",
s"Prize: X=${L(x)}, Y=${L(y)}",
) =>
Some(Claw(ax, ay, bx, by, x, y))
case _ => None

def parse(input: String): Seq[Claw] =
input.split("\n+").toSeq.grouped(3).flatMap(Claw.parse).toSeq

extension (a: Long)
infix def safeDiv(b: Long): Option[Long] =
Option.when(b != 0 && a % b == 0)(a / b)

object L:
def unapply(s: String): Option[Long] = s.toLongOption

def part1(input: String): Long =
parse(input).flatMap(_.solve).sum

def part2(input: String): Long =
val diff = 10_000_000_000_000L
parse(input)
.map(c => c.copy(x = c.x + diff, y = c.y + diff))
.flatMap(_.solve)
.sum
9 changes: 9 additions & 0 deletions 2024/src/inputs.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package inputs

import scala.util.Using
import scala.io.Source

object Input:

def loadFileSync(path: String): String =
Using.resource(Source.fromFile(path))(_.mkString)
19 changes: 19 additions & 0 deletions 2024/src/locations.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package locations

import scala.quoted.*

object Directory:

/** The absolute path of the parent directory of the file that calls this method
* This is stable no matter which directory runs the program.
*/
inline def currentDir: String = ${ parentDirImpl }

private def parentDirImpl(using Quotes): Expr[String] =
// position of the call to `currentDir` in the source code
val position = quotes.reflect.Position.ofMacroExpansion
// get the path of the file calling this macro
val srcFilePath = position.sourceFile.getJPath.get
// get the parent of the path, which is the directory containing the file
val parentDir = srcFilePath.getParent().toAbsolutePath
Expr(parentDir.toString) // convert the String to Expr[String]

0 comments on commit 0a09b49

Please sign in to comment.