Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2023-25 #23

Merged
merged 29 commits into from
Dec 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/scala2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,17 @@ jobs:

steps:
- uses: actions/checkout@v3

- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
cache: 'sbt'

- name: Install Z3
run: sudo apt-get update && sudo apt-get install -y z3

- name: Run tests
working-directory: ./scala2
run: sbt test
5 changes: 5 additions & 0 deletions scala2/src/main/resources/2023/24-test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
19, 13, 30 @ -2, 1, -2
18, 19, 22 @ -1, -1, -2
20, 25, 34 @ -2, -2, -4
12, 31, 28 @ -1, -2, -1
20, 19, 15 @ 1, -5, -3
300 changes: 300 additions & 0 deletions scala2/src/main/resources/2023/24.txt

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import org.scalatest.matchers.should.Matchers._
object Advent03 {
type ClaimId = Int

final case class Claim(id: ClaimId, area: Area2D)
final case class Claim(id: ClaimId, area: Area2D[Int])
object Claim {
private val RegEx = """#(\d+) @ (\d+),(\d+): (\d+)x(\d+)""".r
def parse(s: String): Claim =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package jurisk.adventofcode.y2018

import cats.implicits._
import jurisk.geometry.Coordinates2D
import jurisk.geometry.Coords2D
import jurisk.utils.CollectionOps.IterableOps
import jurisk.utils.FileInput.parseFileLines
Expand All @@ -12,7 +13,7 @@ object Advent06 {
parseFileLines(fileName, _.parseCoords2D)

def part1(points: List[Coords2D]): Int = {
val boundingBox = Coords2D.boundingBoxInclusive(points)
val boundingBox = Coordinates2D.boundingBoxInclusive(points)
println(s"Bounding box: $boundingBox")

def onEdgeOfBoundingBox(point: Coords2D): Boolean =
Expand Down Expand Up @@ -47,7 +48,7 @@ object Advent06 {
}

def part2(points: List[Coords2D], limit: Int): Int =
Coords2D.boundingBoxInclusive(points).points.count { point =>
Coordinates2D.boundingBoxInclusive(points).points.count { point =>
val distanceToAll = points.map(_.manhattanDistance(point)).sum
distanceToAll < limit
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package jurisk.adventofcode.y2018

import cats.implicits._
import jurisk.geometry.Coordinates2D
import jurisk.geometry.Coords2D
import jurisk.geometry.SparseBooleanField
import jurisk.utils.FileInput._
Expand Down Expand Up @@ -34,7 +35,7 @@ object Advent10 {

Simulation.runWithIterationCount(()) { case ((), time) =>
val atTime = field.map(x => x.atTime(time.toInt))
val boundingBox = Coords2D.boundingBoxInclusive(atTime)
val boundingBox = Coordinates2D.boundingBoxInclusive(atTime)
if (boundingBox.height <= limit) {
val fieldAtTime = SparseBooleanField(atTime, 100).toDebugRepresentation
println(s"At time $time:")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import jurisk.adventofcode.y2018.Advent17.Square.Clay
import jurisk.adventofcode.y2018.Advent17.Square._
import jurisk.adventofcode.y2018.Advent17.State.consecutiveRanges
import jurisk.adventofcode.y2018.Advent17.State.isSolid
import jurisk.geometry.Coordinates2D
import jurisk.geometry.Coords2D
import jurisk.geometry.Field2D
import jurisk.utils.FileInput._
Expand Down Expand Up @@ -137,15 +138,15 @@ object Advent17 {
}
}

private def parsePoints(s: String): List[Coords2D] =
private def parsePoints(s: String): Seq[Coords2D] =
s match {
case s"x=$x, y=$y1..$y2" =>
Coords2D.allPointsInclusive(
Coordinates2D.allPointsInclusive(
Coords2D.of(x.toInt, y1.toInt),
Coords2D.of(x.toInt, y2.toInt),
)
case s"y=$y, x=$x1..$x2" =>
Coords2D.allPointsInclusive(
Coordinates2D.allPointsInclusive(
Coords2D.of(x1.toInt, y.toInt),
Coords2D.of(x2.toInt, y.toInt),
)
Expand All @@ -157,7 +158,7 @@ object Advent17 {
def parse(data: String): Field2D[Square] = {
val points = data.parseLines(parsePoints).flatten

val boundingBox = Coords2D
val boundingBox = Coordinates2D
.boundingBoxInclusive(SpringOfWater :: points)
.expandInEachDirectionBy(1)

Expand Down
21 changes: 9 additions & 12 deletions scala2/src/main/scala/jurisk/adventofcode/y2018/Advent23.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import jurisk.optimization.Optimizer
import jurisk.utils.FileInput._
import jurisk.utils.Parsing.StringOps

import scala.annotation.nowarn

object Advent23 {
type Input = List[Nanobot]

final case class Nanobot(
position: Coords3D,
position: Coords3D[Int],
radius: Int,
)

Expand Down Expand Up @@ -69,7 +71,7 @@ object Advent23 {
nanobot.position.y,
nanobot.position.z,
nanobot.radius,
).map(constant)
).map(intConstant)

val inRange = (x - nx).abs + (y - ny).abs + (z - nz).abs <= nr

Expand All @@ -83,19 +85,14 @@ object Advent23 {
distanceFromOrigin === sum(abs(x), abs(y), abs(z)),
)

// Objective - maximize nanobotsInRange and minimize distanceFromOrigin
val objective1 = maximize(nanobotsInRange)
val objective2 = minimize(distanceFromOrigin)

val model = checkAndGetModel()
// Objectives - maximize nanobotsInRange and minimize distanceFromOrigin
val _ = maximize(nanobotsInRange)
val _ = minimize(distanceFromOrigin)

println(model)

val List(xc, yc, zc, nir, dor) =
List(x, y, z, nanobotsInRange, distanceFromOrigin).map(extractInt)
val List(xc, yc, zc) = runExternal("x", "y", "z").map(resultToInt)

val found = Coords3D(xc, yc, zc)
println(s"$found: nanobots in range: $nir, distance from origin: $dor")

found.manhattanDistance(Coords3D.Zero)
}

Expand Down
12 changes: 6 additions & 6 deletions scala2/src/main/scala/jurisk/adventofcode/y2022/Advent18.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@ import jurisk.utils.Parsing.StringOps
import org.scalatest.matchers.should.Matchers._

object Advent18 {
private def sidesFree(cube: Coords3D, cubes: Set[Coords3D]): Int =
private def sidesFree(cube: Coords3D[Int], cubes: Set[Coords3D[Int]]): Int =
cube.adjacent6.count(n => !cubes.contains(n))

def parse(data: String): Set[Coords3D] =
data.parseLines(Coords3D.parse).toSet
def parse(data: String): Set[Coords3D[Int]] =
data.parseLines(Coords3D.parse[Int]).toSet

def part1(points: Set[Coords3D]): Int =
def part1(points: Set[Coords3D[Int]]): Int =
points.toList.map(sidesFree(_, points)).sum

def part2(points: Set[Coords3D]): Int = {
def part2(points: Set[Coords3D[Int]]): Int = {
val boundingBox = Coords3D.boundingBoxInclusive(points)
val expandedBoundingBox = boundingBox.expandInEachDirectionBy(1)

val startingPointForSearch = expandedBoundingBox.min
val reachable = Bfs
.bfsReachable[Coords3D](
.bfsReachable[Coords3D[Int]](
startingPointForSearch,
_.adjacent6.filter { n =>
!points.contains(n) && expandedBoundingBox.contains(n)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,8 @@ object Advent21 {
}
}

val model = checkAndGetModel()
println(model)

extractLong(calculate.labeledInt)
val List(result) = runExternal(calculate)
resultToLong(result)
}

private def solvePart1Optimizer(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package jurisk.adventofcode.y2022

import jurisk.geometry.Coordinates2D
import jurisk.geometry.Coords2D
import jurisk.geometry.Direction2D
import jurisk.geometry.Direction2D._
Expand Down Expand Up @@ -81,7 +82,7 @@ object Advent23 {
}

def debugPrint(): Unit = {
val box = Coords2D.boundingBoxInclusive(elves.map(_.location))
val box = Coordinates2D.boundingBoxInclusive(elves.map(_.location))
val field = Field2D.forArea(box, '.')
val resulting = elves.foldLeft(field) { case (acc, e) =>
acc.updatedAtUnsafe(e.location, e.charRep)
Expand All @@ -107,7 +108,7 @@ object Advent23 {
state.next(iteration.toInt)
}

val box = Coords2D.boundingBoxInclusive(result.allCoords)
val box = Coordinates2D.boundingBoxInclusive(result.allCoords)
(box.width * box.height) - result.allCoords.size
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ object Advent24 {
start: Coords2D,
blizzards: Set[Blizzard],
goal: Coords2D,
area: Area2D,
area: Area2D[Int],
) {
def freeAtTimeNear(time: Int, location: Coords2D): List[Coords2D] = {
val blizzardCoordinatesInNext = blizzardsAt(time)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package jurisk.adventofcode.y2023

import cats.implicits._
import jurisk.geometry.BigIntCoords2D
import jurisk.geometry.Coordinates2D
import jurisk.geometry.Field2D
import jurisk.utils.FileInput._
import jurisk.utils.Parsing.StringOps
Expand All @@ -12,15 +12,16 @@ import scala.collection.immutable.ArraySeq
import scala.collection.mutable

object Advent11 {
private type Galaxies = ArraySeq[BigIntCoords2D]
private type BigIntCoords2D = Coordinates2D[BigInt]
private type Galaxies = ArraySeq[BigIntCoords2D]

def parse(input: String): Galaxies = {
val field = Field2D.parseBooleanField(input)

val coords = field.filterCoordsByValue(_ == true)

val results = coords.map { c =>
BigIntCoords2D(c.x, c.y)
Coordinates2D[BigInt](c.x, c.y)
}

ArraySeq.from(results)
Expand Down
11 changes: 8 additions & 3 deletions scala2/src/main/scala/jurisk/adventofcode/y2023/Advent16.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import jurisk.utils.Parsing.StringOps
import jurisk.utils.Simulation
import mouse.all.booleanSyntaxMouse

import scala.annotation.nowarn
import scala.collection.immutable.ArraySeq

object Advent16 {
Expand Down Expand Up @@ -250,9 +251,9 @@ object Advent16 {
println(s"Upper:\n${objective.getUpper}")
}

val model = checkAndGetModel()

if (debug) {
@nowarn("cat=deprecation")
val model = checkAndGetModel()
println(s"Model:\n$model")

val debugField = field
Expand All @@ -261,7 +262,10 @@ object Advent16 {
val incoming = incomingBool(c, d)
val outgoing = outgoingBool(c, d)

@nowarn("cat=deprecation")
val incm = extractBoolean(incoming).getOrElse("Unknown".fail)

@nowarn("cat=deprecation")
val outg = extractBoolean(outgoing).getOrElse("Unknown".fail)

(incm, outg) match {
Expand All @@ -288,7 +292,8 @@ object Advent16 {
Field2D.printCharField(debugField)
}

extractLong(energizedVar)
val List(result) = runExternal("energized")
resultToLong(result)
}

private def edgeIncomings(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,10 @@ object Advent21 {

// Working but slow
def part2Simulation(data: Input, steps: Int): Long = {
def debugPrint(area: Area2D, map: mutable.HashMap[Coords2D, Long]): Long = {
def debugPrint(
area: Area2D[Int],
map: mutable.HashMap[Coords2D, Long],
): Long = {
var results = 0

val stringField = Field2D.forArea(area, ' ').mapByCoords { c =>
Expand Down Expand Up @@ -411,6 +414,8 @@ object Advent21 {
val realData: Input = parseFile(fileName(""))

println(s"Part 1: ${part1(realData, 64)}")

// TODO: Try solving Part 2 as extrapolating as a 2nd degree polynomial for 65 + n * 131 steps, where n = 0..4
println(s"Part 2: ${part2FieldClassification(realData, 26501365)}")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ object Advent22 {
type Input = Vector[Brick]
type BrickId = Int

final case class Brick(id: BrickId, blocks: Area3D) {
final case class Brick(id: BrickId, blocks: Area3D[Int]) {
def name: String = if (id < 26) {
('A'.toInt + id).toChar.toString
} else {
Expand Down
Loading