Skip to content

Commit

Permalink
feat(2024/08): 2024 day 08
Browse files Browse the repository at this point in the history
  • Loading branch information
scarf005 committed Dec 8, 2024
1 parent 2071542 commit e0274be
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 0 deletions.
40 changes: 40 additions & 0 deletions 2024/day08.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package `2024`.day08

import prelude.*

extension (a: Pos)
infix def deltas(b: Pos): Iterator[Pos] =
val delta = (b - a)
Iterator.iterate(a + delta)(_ + delta)

case class Context(size: Size, antennaes: Map[Char, Vector[Pos]]):
def solve(fn: ((Pos, Pos)) => IterableOnce[Pos]) =
antennaes.values.flatMap(_.combinationsN(2).flatMap(fn)).toSet

lazy val part1 =
solve((a, b) => Vector(a + (a - b), b + (b - a))).filter(size.contains).size
lazy val part2 = solve((a, b) =>
(a deltas b).takeWhile(size.contains)
++ (b deltas a).takeWhile(size.contains),
).size

object Context:
def apply(input: String): Context =
apply(input.linesIterator.map(_.toCharArray).toArray)

def apply(grid: Array[Array[Char]]): Context =
val size = Size(grid)
val antennaes = (for
y <- 0 until size.height
x <- 0 until size.width
c = grid(y)(x)
if c != '.' && c != '#'
yield c -> Pos(x, y)).toVector.groupMap(_._1)(_._2)
Context(size, antennaes)

@main def main() =
val input = readInput(this).mkString
val ctx = Context(input)

println(ctx.part1)
println(ctx.part2)
65 changes: 65 additions & 0 deletions 2024/day08.test.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package `2024`.day08

import munit.FunSuite
import prelude.|>

val example =
"""|......#....#
|...#....0...
|....#0....#.
|..#....0....
|....0....#..
|.#....A.....
|...#........
|#......#....
|........A...
|.........A..
|..........#.
|..........#.""".stripMargin |> Context.apply

class Part1Test extends FunSuite:
test("two"):
"""|..........
|...#......
|..........
|....a.....
|..........
|.....a....
|..........
|......#...
|..........
|..........""".stripMargin
|> Context.apply |> (ctx => assertEquals(ctx.part1, 2))

test("three"):
"""|..........
|...#......
|#.........
|....a.....
|........a.
|.....a....
|..#.......
|......#...
|..........
|..........""".stripMargin
|> Context.apply |> (ctx => assertEquals(ctx.part1, 4))

test("example"):
assertEquals(example.part1, 14)

class Part2Test extends FunSuite:
test("T T T"):
"""|T....#....
|...T......
|.T....#...
|.........#
|..#.......
|..........
|...#......
|..........
|....#.....
|..........""".stripMargin
|> Context.apply |> (ctx => assertEquals(ctx.part2, 9))

test("example"):
assertEquals(example.part2, 34)
2 changes: 2 additions & 0 deletions prelude/math.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ extension (n: Int)

final case class Pos(x: Int, y: Int):
def +(p: Pos) = Pos(x + p.x, y + p.y)
def -(p: Pos) = Pos(x - p.x, y - p.y)
def *(n: Int) = Pos(x * n, y * n)

final case class Size(width: Int, height: Int):
inline def contains(p: Pos) =
Expand Down

0 comments on commit e0274be

Please sign in to comment.