Skip to content

Commit

Permalink
2024-08 Scala 2
Browse files Browse the repository at this point in the history
  • Loading branch information
jurisk committed Dec 8, 2024
1 parent 30488a3 commit 396db3c
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 28 deletions.
13 changes: 12 additions & 1 deletion scala2/src/main/resources/2024/08-test-00.txt
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
noop
............
........0...
.....0......
.......0....
....0.......
......A.....
............
............
........A...
.........A..
............
............
51 changes: 50 additions & 1 deletion scala2/src/main/resources/2024/08.txt
Original file line number Diff line number Diff line change
@@ -1 +1,50 @@
noop
....h.....Q..............Y........................
...............................Y........C.........
...............m..........x................B......
........................Y..............qB.........
......g4.........................h..Y.....q...c...
................n.....R...........................
.......................................w........5.
........g...m...........................w5........
..n...........R.1................W.......q.5......
.........h...n.................e..................
...............................R..........B....C..
.........4................................5.e.....
.......0..4......n.......x..w.....................
.......g.....m........x..b.....W.....B.......w....
..............m........................3......C...
........q...0.......h....................C.3......
..................3.....................D.........
...............R..........3.............X.........
..............................W............k2.....
..........7............................2..........
...............A.............................X...2
.......................c...x......................
....................................d.............
.....1......................d.....................
...........1...........................e..........
.........0.7K.........................2.........W.
...b......0.....A.................................
......................1....ic.....................
......b......................i....................
..Q.....b..........................A..E...........
...7.........................V....................
........A.....................v......d............
........v............c...................8E.......
..............................V........8.....E..N.
......................6...........................
.......I....M....................V................
...G......................a.......8...............
.........r.9........a...i..................X......
...............r..i...............e............N..
.....H...........k....9.....6...............8.....
.v.....................6................V.........
.........v.......a........k..........D............
Ha..........k.........K........E.......d..........
...............y.MG..............6....D...........
.........H..G...M......9.K..............N.........
.......G.........................K................
...............M.........I.......D................
..................................................
....r....y................9.......................
....y................................N............
118 changes: 96 additions & 22 deletions scala2/src/main/scala/jurisk/adventofcode/y2024/Advent08.scala
Original file line number Diff line number Diff line change
@@ -1,37 +1,111 @@
package jurisk.adventofcode.y2024

import cats.implicits._
import jurisk.adventofcode.y2024.Advent08.Square.Antenna
import jurisk.adventofcode.y2024.Advent08.Square.Empty
import jurisk.geometry.Coords2D
import jurisk.geometry.Field2D
import jurisk.utils.FileInput._
import jurisk.utils.Parsing.StringOps
import mouse.all._

import scala.annotation.tailrec

object Advent08 {
type Input = List[Command]
type N = Long

sealed trait Command extends Product with Serializable
object Command {
case object Noop extends Command
final case class Something(
values: List[N]
) extends Command
final case class Other(value: String) extends Command

def parse(s: String): Command =
s match {
case "noop" => Noop
case s"something $rem" => Something(rem.extractLongList)
case s if s.nonEmpty => Other(s)
case _ => s.failedToParse
}
private type Frequency = Char

sealed trait Square
object Square {
case object Empty extends Square
final case class Antenna(frequency: Frequency) extends Square

def parse(ch: Char): Square = ch match {
case '.' => Empty
case ch => Antenna(ch)
}
}

private type SquareAndAntiNodes = (Square, Set[Frequency])
type Input = Field2D[SquareAndAntiNodes]
type N = Long

def parse(input: String): Input =
input.parseLines(Command.parse)
Field2D.parseCharField(input).map(ch => (Square.parse(ch), Set.empty))

@tailrec
private def helper(
field: Input,
frequency: Char,
current: Coords2D,
diff: Coords2D,
limit: Option[Int],
count: Int = 0,
): Input =
if (field.isValidCoordinate(current) && limit.forall(count <= _)) {
val updated = if (limit.isEmpty || count != 0) {
field.modifyIgnoringInvalidCoords(
current,
{ case (ch, set) =>
(ch, set + frequency)
},
)
} else {
field
}

helper(updated, frequency, current + diff, diff, limit, count + 1)
} else {
field
}

private def update(
field: Input,
frequency: Char,
a: Coords2D,
b: Coords2D,
limit: Option[Int],
): Input =
List((a, a - b), (b, b - a)).foldLeft(field) {
case (field, (start, diff)) =>
helper(field, frequency, start, diff, limit)
}

private def processFrequency(
field: Input,
frequency: Char,
limit: Option[Int],
): Input = {
val locations = field.filterCoordsByValue { case (sq, _) =>
sq == Antenna(frequency)
}
val pairs = (locations, locations).mapN { case (a, b) =>
(a != b).option((a, b))
}.flatten

pairs.foldLeft(field) { case (field, (a, b)) =>
update(field, frequency, a, b, limit)
}
}

def solve(data: Input, limit: Option[Int]): N = {
val frequencies = data.values.flatMap { case (sq, _) =>
sq match {
case Antenna(frequency) => Some(frequency)
case Empty => None
}
}.toSet

val result = frequencies.foldLeft(data) { case (field, frequency) =>
processFrequency(field, frequency, limit)
}

result.count { case (_, s) => s.nonEmpty }
}

def part1(data: Input): N =
0
solve(data, 1.some)

def part2(data: Input): N =
0
solve(data, none)

def parseFile(fileName: String): Input =
parse(readFileText(fileName))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@ class Advent08Spec extends AnyFreeSpec {

"part 1" - {
"test" in {
part1(testData) shouldEqual 0
part1(testData) shouldEqual 14
}

"real" in {
part1(realData) shouldEqual 0
part1(realData) shouldEqual 256
}
}

"part 2" - {
"test" in {
part2(testData) shouldEqual 0
part2(testData) shouldEqual 34
}

"real" in {
part2(realData) shouldEqual 0
part2(realData) shouldEqual 1005
}
}
}

0 comments on commit 396db3c

Please sign in to comment.