Skip to content

Commit 396db3c

Browse files
committed
2024-08 Scala 2
1 parent 30488a3 commit 396db3c

File tree

4 files changed

+162
-28
lines changed

4 files changed

+162
-28
lines changed
+12-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,12 @@
1-
noop
1+
............
2+
........0...
3+
.....0......
4+
.......0....
5+
....0.......
6+
......A.....
7+
............
8+
............
9+
........A...
10+
.........A..
11+
............
12+
............

scala2/src/main/resources/2024/08.txt

+50-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,50 @@
1-
noop
1+
....h.....Q..............Y........................
2+
...............................Y........C.........
3+
...............m..........x................B......
4+
........................Y..............qB.........
5+
......g4.........................h..Y.....q...c...
6+
................n.....R...........................
7+
.......................................w........5.
8+
........g...m...........................w5........
9+
..n...........R.1................W.......q.5......
10+
.........h...n.................e..................
11+
...............................R..........B....C..
12+
.........4................................5.e.....
13+
.......0..4......n.......x..w.....................
14+
.......g.....m........x..b.....W.....B.......w....
15+
..............m........................3......C...
16+
........q...0.......h....................C.3......
17+
..................3.....................D.........
18+
...............R..........3.............X.........
19+
..............................W............k2.....
20+
..........7............................2..........
21+
...............A.............................X...2
22+
.......................c...x......................
23+
....................................d.............
24+
.....1......................d.....................
25+
...........1...........................e..........
26+
.........0.7K.........................2.........W.
27+
...b......0.....A.................................
28+
......................1....ic.....................
29+
......b......................i....................
30+
..Q.....b..........................A..E...........
31+
...7.........................V....................
32+
........A.....................v......d............
33+
........v............c...................8E.......
34+
..............................V........8.....E..N.
35+
......................6...........................
36+
.......I....M....................V................
37+
...G......................a.......8...............
38+
.........r.9........a...i..................X......
39+
...............r..i...............e............N..
40+
.....H...........k....9.....6...............8.....
41+
.v.....................6................V.........
42+
.........v.......a........k..........D............
43+
Ha..........k.........K........E.......d..........
44+
...............y.MG..............6....D...........
45+
.........H..G...M......9.K..............N.........
46+
.......G.........................K................
47+
...............M.........I.......D................
48+
..................................................
49+
....r....y................9.......................
50+
....y................................N............

scala2/src/main/scala/jurisk/adventofcode/y2024/Advent08.scala

+96-22
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,111 @@
11
package jurisk.adventofcode.y2024
22

3+
import cats.implicits._
4+
import jurisk.adventofcode.y2024.Advent08.Square.Antenna
5+
import jurisk.adventofcode.y2024.Advent08.Square.Empty
6+
import jurisk.geometry.Coords2D
7+
import jurisk.geometry.Field2D
38
import jurisk.utils.FileInput._
4-
import jurisk.utils.Parsing.StringOps
9+
import mouse.all._
10+
11+
import scala.annotation.tailrec
512

613
object Advent08 {
7-
type Input = List[Command]
8-
type N = Long
9-
10-
sealed trait Command extends Product with Serializable
11-
object Command {
12-
case object Noop extends Command
13-
final case class Something(
14-
values: List[N]
15-
) extends Command
16-
final case class Other(value: String) extends Command
17-
18-
def parse(s: String): Command =
19-
s match {
20-
case "noop" => Noop
21-
case s"something $rem" => Something(rem.extractLongList)
22-
case s if s.nonEmpty => Other(s)
23-
case _ => s.failedToParse
24-
}
14+
private type Frequency = Char
15+
16+
sealed trait Square
17+
object Square {
18+
case object Empty extends Square
19+
final case class Antenna(frequency: Frequency) extends Square
20+
21+
def parse(ch: Char): Square = ch match {
22+
case '.' => Empty
23+
case ch => Antenna(ch)
24+
}
2525
}
2626

27+
private type SquareAndAntiNodes = (Square, Set[Frequency])
28+
type Input = Field2D[SquareAndAntiNodes]
29+
type N = Long
30+
2731
def parse(input: String): Input =
28-
input.parseLines(Command.parse)
32+
Field2D.parseCharField(input).map(ch => (Square.parse(ch), Set.empty))
33+
34+
@tailrec
35+
private def helper(
36+
field: Input,
37+
frequency: Char,
38+
current: Coords2D,
39+
diff: Coords2D,
40+
limit: Option[Int],
41+
count: Int = 0,
42+
): Input =
43+
if (field.isValidCoordinate(current) && limit.forall(count <= _)) {
44+
val updated = if (limit.isEmpty || count != 0) {
45+
field.modifyIgnoringInvalidCoords(
46+
current,
47+
{ case (ch, set) =>
48+
(ch, set + frequency)
49+
},
50+
)
51+
} else {
52+
field
53+
}
54+
55+
helper(updated, frequency, current + diff, diff, limit, count + 1)
56+
} else {
57+
field
58+
}
59+
60+
private def update(
61+
field: Input,
62+
frequency: Char,
63+
a: Coords2D,
64+
b: Coords2D,
65+
limit: Option[Int],
66+
): Input =
67+
List((a, a - b), (b, b - a)).foldLeft(field) {
68+
case (field, (start, diff)) =>
69+
helper(field, frequency, start, diff, limit)
70+
}
71+
72+
private def processFrequency(
73+
field: Input,
74+
frequency: Char,
75+
limit: Option[Int],
76+
): Input = {
77+
val locations = field.filterCoordsByValue { case (sq, _) =>
78+
sq == Antenna(frequency)
79+
}
80+
val pairs = (locations, locations).mapN { case (a, b) =>
81+
(a != b).option((a, b))
82+
}.flatten
83+
84+
pairs.foldLeft(field) { case (field, (a, b)) =>
85+
update(field, frequency, a, b, limit)
86+
}
87+
}
88+
89+
def solve(data: Input, limit: Option[Int]): N = {
90+
val frequencies = data.values.flatMap { case (sq, _) =>
91+
sq match {
92+
case Antenna(frequency) => Some(frequency)
93+
case Empty => None
94+
}
95+
}.toSet
96+
97+
val result = frequencies.foldLeft(data) { case (field, frequency) =>
98+
processFrequency(field, frequency, limit)
99+
}
100+
101+
result.count { case (_, s) => s.nonEmpty }
102+
}
29103

30104
def part1(data: Input): N =
31-
0
105+
solve(data, 1.some)
32106

33107
def part2(data: Input): N =
34-
0
108+
solve(data, none)
35109

36110
def parseFile(fileName: String): Input =
37111
parse(readFileText(fileName))

scala2/src/test/scala/jurisk/adventofcode/y2024/Advent08Spec.scala

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,21 @@ class Advent08Spec extends AnyFreeSpec {
1010

1111
"part 1" - {
1212
"test" in {
13-
part1(testData) shouldEqual 0
13+
part1(testData) shouldEqual 14
1414
}
1515

1616
"real" in {
17-
part1(realData) shouldEqual 0
17+
part1(realData) shouldEqual 256
1818
}
1919
}
2020

2121
"part 2" - {
2222
"test" in {
23-
part2(testData) shouldEqual 0
23+
part2(testData) shouldEqual 34
2424
}
2525

2626
"real" in {
27-
part2(realData) shouldEqual 0
27+
part2(realData) shouldEqual 1005
2828
}
2929
}
3030
}

0 commit comments

Comments
 (0)