From e21f725c87bca624d350d0f5a2b89b7ac20e779a Mon Sep 17 00:00:00 2001 From: nmcb Date: Thu, 26 Feb 2026 23:45:44 +0100 Subject: [PATCH 1/3] prefer (named) tupple instantiation over contructor --- 2016/src/main/scala/aoc2016/Day13.scala | 4 +- 2016/src/main/scala/aoc2016/Day17.scala | 4 +- 2016/src/main/scala/aoc2016/Day22.scala | 12 ++--- 2016/src/main/scala/aoc2016/Day24.scala | 52 +++++++++++++++------- 2017/src/main/scala/aoc2017/Day03.scala | 12 ++--- 2017/src/main/scala/aoc2017/Day14.scala | 2 +- 2017/src/main/scala/aoc2017/Day19.scala | 4 +- 2017/src/main/scala/aoc2017/Day22.scala | 6 +-- 2018/src/main/scala/aoc2018/Day03.scala | 4 +- 2018/src/main/scala/aoc2018/Day06.scala | 4 +- 2018/src/main/scala/aoc2018/Day10.scala | 4 +- 2018/src/main/scala/aoc2018/Day11.scala | 8 ++-- 2018/src/main/scala/aoc2018/Day13.scala | 10 ++--- 2018/src/main/scala/aoc2018/Day15.scala | 2 +- 2018/src/main/scala/aoc2018/Day17.scala | 8 ++-- 2018/src/main/scala/aoc2018/Day18.scala | 6 +-- 2019/src/main/scala/aoc2019/Day03.scala | 8 ++-- 2019/src/main/scala/aoc2019/Day10.scala | 6 +-- 2019/src/main/scala/aoc2019/Day11.scala | 8 ++-- 2019/src/main/scala/aoc2019/Day15.scala | 8 ++-- 2019/src/main/scala/aoc2019/Day17.scala | 18 ++++---- 2019/src/main/scala/aoc2019/Day18.scala | 2 +- 2019/src/main/scala/aoc2019/Day20.scala | 4 +- 2020/src/main/scala/aoc2020/Day20.scala | 30 ++++++------- 2021/src/main/scala/aoc2021/Day15.scala | 2 +- 2021/src/main/scala/aoc2021/Day20.scala | 4 +- 2021/src/main/scala/aoc2021/Day25.scala | 6 +-- 2022/src/main/scala/aoc2022/Day08.scala | 16 +++---- 2022/src/main/scala/aoc2022/Day09.scala | 2 +- 2022/src/main/scala/aoc2022/Day14.scala | 14 +++--- 2022/src/main/scala/aoc2022/Day17.scala | 16 +++---- 2022/src/main/scala/aoc2022/Day23.scala | 18 ++++---- 2022/src/main/scala/aoc2022/Day24.scala | 14 +++--- 2023/src/main/scala/aoc2023/Day03.scala | 8 ++-- 2023/src/main/scala/aoc2023/Day10.scala | 10 ++--- 2023/src/main/scala/aoc2023/Day11.scala | 2 +- 2023/src/main/scala/aoc2023/Day16.scala | 10 ++--- 2023/src/main/scala/aoc2023/Day17.scala | 2 +- 2023/src/main/scala/aoc2023/Day18.scala | 6 +-- 2023/src/main/scala/aoc2023/Day23.scala | 4 +- 2024/src/main/scala/aoc2024/Day04.scala | 16 +++---- 2024/src/main/scala/aoc2024/Day14.scala | 16 +++---- 2024/src/main/scala/aoc2024/Day15.scala | 10 +---- 2024/src/test/scala/aoc2024/Test2024.scala | 2 +- 2025/src/main/scala/aoc2025/Day04.scala | 2 +- nmcb/src/main/scala/nmcb/Grid.scala | 4 +- 46 files changed, 212 insertions(+), 198 deletions(-) diff --git a/2016/src/main/scala/aoc2016/Day13.scala b/2016/src/main/scala/aoc2016/Day13.scala index ebac03d..716567a 100644 --- a/2016/src/main/scala/aoc2016/Day13.scala +++ b/2016/src/main/scala/aoc2016/Day13.scala @@ -52,5 +52,5 @@ object Day13 extends AoC: cache.toMap - override lazy val answer1: Int = solve1(start = Pos.of(1, 1), target = Pos.of(31, 39)) - override lazy val answer2: Int = solve2(start = Pos.of(1,1)).size + override lazy val answer1: Int = solve1(start = (1, 1), target = (31, 39)) + override lazy val answer2: Int = solve2(start = (1,1)).size diff --git a/2016/src/main/scala/aoc2016/Day17.scala b/2016/src/main/scala/aoc2016/Day17.scala index c752949..d6c062d 100644 --- a/2016/src/main/scala/aoc2016/Day17.scala +++ b/2016/src/main/scala/aoc2016/Day17.scala @@ -22,13 +22,13 @@ object Day17 extends AoC: /** hardcoded for 4x4 grid */ - case class Path(passcode: String, path: String = "", target: Pos = Pos.of(0, 0)): + case class Path(passcode: String, path: String = "", target: Pos = (0, 0)): def withinGrid: Boolean = target.x >= 0 && target.x < 4 && target.y >= 0 && target.y < 4 def reachedVault: Boolean = - target == Pos.of(3, 3) + target == (3, 3) def openDoors: String = md5 diff --git a/2016/src/main/scala/aoc2016/Day22.scala b/2016/src/main/scala/aoc2016/Day22.scala index c25ce01..2667c83 100644 --- a/2016/src/main/scala/aoc2016/Day22.scala +++ b/2016/src/main/scala/aoc2016/Day22.scala @@ -21,7 +21,7 @@ object Day22 extends AoC: .filter(_.startsWith("/dev/grid/node")) .map: line => val Array(x, y, _, used, avail, _) = line.split("\\D+").tail.map(_.toInt) - Pos.of(x, y) -> Node(used, avail) + (x, y) -> Node(used, avail) .toMap def viable(nodes: Map[Pos, Node]): Vector[(Node, Node)] = @@ -42,10 +42,10 @@ object Day22 extends AoC: y <- 0 to maxY x <- 0 to maxX do - val pos = Pos.of(x, y) + val pos = (x, y) val node = nodes(pos) - if pos == Pos.of(0, 0) then sb.append('T') - else if pos == Pos.of(maxX, 0) then sb.append('S') + if pos == (0, 0) then sb.append('T') + else if pos == (maxX, 0) then sb.append('S') else sb.append(node.toChar) if x == maxX then sb.append('\n') sb.append('\n').toString @@ -100,8 +100,8 @@ object Day22 extends AoC: * */ - val source: Pos = Pos.of(nodes.maxX, 0) - val target: Pos = Pos.of(0, 0) + val source: Pos = (nodes.maxX, 0) + val target: Pos = (0, 0) val empty: Pos = nodes.find(_.element.isEmpty).map(_.pos).get val massive: Vector[Pos] = nodes.filter(_.element.isMassive).map(_.pos).toVector diff --git a/2016/src/main/scala/aoc2016/Day24.scala b/2016/src/main/scala/aoc2016/Day24.scala index 156be14..467f88a 100644 --- a/2016/src/main/scala/aoc2016/Day24.scala +++ b/2016/src/main/scala/aoc2016/Day24.scala @@ -3,17 +3,32 @@ package aoc2016 import nmcb.* import nmcb.pos.{*, given} +import scala.util.control.Breaks._ + object Day24 extends AoC: type Grid = Set[Pos] - type Nodes = Map[Int,Pos] - type Distances = Map[Int,Map[Int,Int]] + type Nodes = Map[Int, Pos] + type Distances = Map[Int, Map[Int, Int]] type Routes = Vector[Vector[Int]] - val(grid: Grid, nodes: Nodes) = - val grid = for y <- lines.indices ; x <- lines.head.indices if lines(y)(x) != '#' yield Pos.of(x, y) - val nodes = for y <- lines.indices ; x <- lines.head.indices if lines(y)(x).isDigit yield lines(y)(x).asDigit -> Pos.of(x, y) - (grid.toSet, nodes.toMap) + val grid: Grid = + val grid = + for + y <- lines.indices + x <- lines.head.indices if lines(y)(x) != '#' + yield + (x = x, y = y) + grid.toSet + + val nodes: Nodes = + val nodes = + for + y <- lines.indices + x <- lines.head.indices if lines(y)(x).isDigit + yield + lines(y)(x).asDigit -> Pos.of(x, y) + nodes.toMap /** breath first search */ def distance(grid: Grid, start: Pos, end: Pos): Int = @@ -21,15 +36,22 @@ object Day24 extends AoC: val steps = mutable.Map(start -> 0) val todo = mutable.Queue(start) - while todo.nonEmpty do - val current = todo.dequeue - if current == end then return steps(current) - val update = steps(current) + 1 - current.adjoint4.intersect(grid).foreach: next => - if !steps.contains(next) || update < steps(next) then - steps(next) = update - todo.enqueue(next) - sys.error("boom!") + var result: Int = 0 + breakable: + while todo.nonEmpty do + val current = todo.dequeue + + if current == end then + result = steps(current) + break() + + val update = steps(current) + 1 + + current.adjoint4.intersect(grid).foreach: next => + if !steps.contains(next) || update < steps(next) then + steps(next) = update + todo.enqueue(next) + result def distances(grid: Grid, nodes: Nodes): Distances = nodes.transform: (_, start) => diff --git a/2017/src/main/scala/aoc2017/Day03.scala b/2017/src/main/scala/aoc2017/Day03.scala index 5a6bc2b..cae4b84 100644 --- a/2017/src/main/scala/aoc2017/Day03.scala +++ b/2017/src/main/scala/aoc2017/Day03.scala @@ -16,10 +16,10 @@ object Day03 extends AoC: val quadrant = base / size val offset = base % size quadrant match - case 0 => Pos.of(half, offset + 1 - half) - case 1 => Pos.of(half - 1 - offset, half) - case 2 => Pos.of(-half, half - 1 - offset) - case 3 => Pos.of(offset + 1 - half, -half) + case 0 => (half, offset + 1 - half) + case 1 => (half - 1 - offset, half) + case 2 => (-half, half - 1 - offset) + case 3 => (offset + 1 - half, -half) def spiralSquares(to: Int):Int = @@ -29,10 +29,10 @@ object Day03 extends AoC: x <- -1 to 1 if !(x == 0 && y == 0) yield - Pos.of(x, y) + (x, y) @tailrec - def loop(n: Int, squares: Map[Pos,Int] = Map(Pos.of(0,0) -> 1)): Int = + def loop(n: Int, squares: Map[Pos,Int] = Map((0,0) -> 1)): Int = val point = position(n) val result = spiralScan.map(_ + point).flatMap(squares.get).sum if result > to then diff --git a/2017/src/main/scala/aoc2017/Day14.scala b/2017/src/main/scala/aoc2017/Day14.scala index efd3706..5633c0c 100644 --- a/2017/src/main/scala/aoc2017/Day14.scala +++ b/2017/src/main/scala/aoc2017/Day14.scala @@ -41,7 +41,7 @@ object Day14 extends AoC: case (acc,(row, y)) => row.foldLeft(acc): case (acc, (square, x)) => - if square == '1' then acc + Pos.of(x,y) else acc + if square == '1' then acc + Pos.of(x, y) else acc def regions(used: Set[Pos]): Set[Set[Pos]] = val graph = used.map(square => square -> square.adjacent.intersect(used)).toMap diff --git a/2017/src/main/scala/aoc2017/Day19.scala b/2017/src/main/scala/aoc2017/Day19.scala index 5102957..4bb97ca 100644 --- a/2017/src/main/scala/aoc2017/Day19.scala +++ b/2017/src/main/scala/aoc2017/Day19.scala @@ -14,7 +14,7 @@ object Day19 extends AoC: extension (g: Grid) def start: Pos = - Pos.of(g.head.indexOf('|'), 0) + (g.head.indexOf('|'), 0) def charAt(p: Pos): Char = grid.lift(p.y).flatMap(_.lift(p.x)).getOrElse(' ') @@ -38,7 +38,7 @@ object Day19 extends AoC: object Tracer: def start(grid: Grid): Tracer = - Tracer(grid, grid.start, Pos.of(0,1)) + Tracer(grid, grid.start, (0,1)) val tracer: Tracer = Tracer.start(grid) val path: Seq[Tracer] = Iterator.iterate(tracer)(_.next).takeWhile(_.isPath).toList diff --git a/2017/src/main/scala/aoc2017/Day22.scala b/2017/src/main/scala/aoc2017/Day22.scala index e467ca5..037f11a 100644 --- a/2017/src/main/scala/aoc2017/Day22.scala +++ b/2017/src/main/scala/aoc2017/Day22.scala @@ -66,7 +66,7 @@ object Day22 extends AoC: private val carrier: Carrier = val current: Pos = - Pos.of(lines(0).length / 2, lines.length / 2) + (lines(0).length / 2, lines.length / 2) val nodes: Map[Pos,Status] = lines @@ -75,8 +75,8 @@ object Day22 extends AoC: row .zipWithIndex .collect: - case ('#',x) => Pos.of(x,y) -> Infected - case ('.',x) => Pos.of(x,y) -> Clean + case ('#',x) => (x,y) -> Infected + case ('.',x) => (x,y) -> Clean .toMap .withDefaultValue(Clean) diff --git a/2018/src/main/scala/aoc2018/Day03.scala b/2018/src/main/scala/aoc2018/Day03.scala index d40c084..2f66465 100644 --- a/2018/src/main/scala/aoc2018/Day03.scala +++ b/2018/src/main/scala/aoc2018/Day03.scala @@ -6,7 +6,7 @@ import nmcb.pos.* object Day03 extends AoC: type Claims = Vector[Vector[Pos]] - type Overlaps = Map[Pos,Int] + type Overlaps = Map[Pos, Int] val (claims: Claims, overlaps: Overlaps) = val claims = lines.map: @@ -15,7 +15,7 @@ object Day03 extends AoC: val x1 = w.toInt + x0 val y0 = y.toInt val y1 = h.toInt + y0 - (for x <- x0 until x1 ; y <- y0 until y1 yield Pos.of(x,y)).toVector + (for x <- x0 until x1 ; y <- y0 until y1 yield (x = x, y = y)).toVector val overlaps = claims.flatten.groupMapReduce(identity)(_ => 1)(_ + _) (claims, overlaps) diff --git a/2018/src/main/scala/aoc2018/Day06.scala b/2018/src/main/scala/aoc2018/Day06.scala index 5324601..f005c16 100644 --- a/2018/src/main/scala/aoc2018/Day06.scala +++ b/2018/src/main/scala/aoc2018/Day06.scala @@ -18,7 +18,7 @@ object Day06 extends AoC: val maxY: Int = coordinates.maxBy(_.y).y val positions: Vector[Pos] = - (for x <- minX to maxX ; y <- minY to maxY yield Pos.of(x,y)).toVector + (for x <- minX to maxX ; y <- minY to maxY yield (x,y)).toVector type UnitDistance = (Pos, Long) @@ -51,7 +51,7 @@ object Day06 extends AoC: val coordinates: Vector[Pos] = lines.map: - case s"$x, $y" => Pos.of(x.toInt, y.toInt) + case s"$x, $y" => (x.toInt, y.toInt) override lazy val answer1: Long = Grid(coordinates).largestAreaSize override lazy val answer2: Int = Grid(coordinates).withinManhattanSumLimit(10000).size diff --git a/2018/src/main/scala/aoc2018/Day10.scala b/2018/src/main/scala/aoc2018/Day10.scala index c9c8abd..81730ce 100644 --- a/2018/src/main/scala/aoc2018/Day10.scala +++ b/2018/src/main/scala/aoc2018/Day10.scala @@ -32,7 +32,7 @@ object Day10 extends AoC: def fromString(s: String): Point = s.trim match case s"position=<$x, $y> velocity=<$vx, $vy>" => - Point(Pos.of(x.trim.toInt, y.trim.toInt), Pos.of(vx.trim.toInt, vy.trim.toInt)) + Point((x.trim.toInt, y.trim.toInt), (vx.trim.toInt, vy.trim.toInt)) // returns the range containing the first domain which yields at least `x` as its codomain, starting from `min`. @@ -77,7 +77,7 @@ object Day10 extends AoC: val positionsSet = positions.toSet (min.y to max.y).foldLeft(StringBuffer())((sb,y) => (min.x to max.x).foldLeft(sb)((sb,x) => - if positionsSet.contains(Pos.of(x,y)) then sb.append('#') else sb.append('.') + if positionsSet.contains((x,y)) then sb.append('#') else sb.append('.') ).append('\n')).toString val (sky, fastest) = diff --git a/2018/src/main/scala/aoc2018/Day11.scala b/2018/src/main/scala/aoc2018/Day11.scala index 2ecd8f3..47177b7 100644 --- a/2018/src/main/scala/aoc2018/Day11.scala +++ b/2018/src/main/scala/aoc2018/Day11.scala @@ -35,7 +35,7 @@ object Day11 extends AoC: /** (x,y) cells for a 1 to 300 grid */ val cells: Seq[Cell] = - for y <- 1 to 300 ; x <- 1 to 300 yield Pos.of(x,y) + for y <- 1 to 300 ; x <- 1 to 300 yield (x,y) /** power level value table, i.e. the i(x,y) value table for named cells */ val grid: Map[Cell,Int] = @@ -44,7 +44,7 @@ object Day11 extends AoC: /** summed power level table, i.e. the summed area table I(x,y) for named grid */ val table: Map[Cell,Int] = cells.foldLeft(immutable.Map.empty[Cell,Int].withDefaultValue(0)): (result, cell) => - result + (cell -> (grid(cell) + result(cell + Pos.of(-1,0)) + result(cell + Pos.of(0,-1)) - result(cell + Pos.of(-1,-1)))) + result + (cell -> (grid(cell) + result(cell + (-1,0)) + result(cell + (0,-1)) - result(cell + (-1,-1)))) /** the area sizes, cells and total power levels for named summed power level table and given area size */ def area(size: Int): Iterator[(Int,Cell,Int)] = @@ -52,8 +52,8 @@ object Day11 extends AoC: y <- (size to 300).iterator x <- (size to 300).iterator yield - val cell = Pos.of(x,y) - val total = table(cell) + table(cell + Pos.of(-size,-size)) - table(cell + Pos.of(-size,0)) - table(cell + Pos.of(0,-size)) + val cell = (x,y) + val total = table(cell) + table(cell + (-size,-size)) - table(cell + (-size,0)) - table(cell + (0,-size)) (size, cell, total) extension (result: (Int,Cell,Int)) diff --git a/2018/src/main/scala/aoc2018/Day13.scala b/2018/src/main/scala/aoc2018/Day13.scala index 9f579a5..6bb84c8 100644 --- a/2018/src/main/scala/aoc2018/Day13.scala +++ b/2018/src/main/scala/aoc2018/Day13.scala @@ -68,11 +68,11 @@ object Day13 extends AoC: y <- (0 until matrix.sizeY).toVector x <- (0 until matrix.sizeX).toVector yield - matrix.charAt(Pos.of(x,y)) match - case Some(c) if c == '^' => Some(Cart(Pos.of(x,y), N)) - case Some(c) if c == '>' => Some(Cart(Pos.of(x,y), E)) - case Some(c) if c == 'v' => Some(Cart(Pos.of(x,y), S)) - case Some(c) if c == '<' => Some(Cart(Pos.of(x,y), W)) + matrix.charAt((x,y)) match + case Some(c) if c == '^' => Some(Cart((x,y), N)) + case Some(c) if c == '>' => Some(Cart((x,y), E)) + case Some(c) if c == 'v' => Some(Cart((x,y), S)) + case Some(c) if c == '<' => Some(Cart((x,y), W)) case _ => None val grid = diff --git a/2018/src/main/scala/aoc2018/Day15.scala b/2018/src/main/scala/aoc2018/Day15.scala index a965cc7..5641075 100644 --- a/2018/src/main/scala/aoc2018/Day15.scala +++ b/2018/src/main/scala/aoc2018/Day15.scala @@ -182,7 +182,7 @@ object Day15 extends AoC: for (row,y) <- parseGrid(input).view.zipWithIndex.toList (tile,x) <- row.view.zipWithIndex - fighter <- parseFighter(tile, Pos.of(x,y)) + fighter <- parseFighter(tile, (x,y)) yield fighter val grid: Grid = diff --git a/2018/src/main/scala/aoc2018/Day17.scala b/2018/src/main/scala/aoc2018/Day17.scala index 0e2f3f6..c51827e 100644 --- a/2018/src/main/scala/aoc2018/Day17.scala +++ b/2018/src/main/scala/aoc2018/Day17.scala @@ -38,7 +38,7 @@ object Day17 extends AoC: case Stopped => val minX = iterate(p)(_.e).dropWhile(next => go(next.s) == Stopped && !blocked(next.e)).next val maxX = iterate(p)(_.w).dropWhile(next => go(next.s) == Stopped && !blocked(next.w)).next - val surface = for x <- minX.x to maxX.x yield Pos.of(x, p.y) + val surface = for x <- minX.x to maxX.x yield (x, p.y) if blocked(minX.e) && blocked(maxX.w) then stopped ++= surface Stopped @@ -54,15 +54,15 @@ object Day17 extends AoC: val clay = lines .flatMap: - case s"x=$x, y=$start..$end" => (start.toInt to end.toInt).map(y => Pos.of(x.toInt, y)) - case s"y=$y, x=$start..$end" => (start.toInt to end.toInt).map(x => Pos.of(x, y.toInt)) + case s"x=$x, y=$start..$end" => (start.toInt to end.toInt).map(y => (x = x.toInt, y = y)) + case s"y=$y, x=$start..$end" => (start.toInt to end.toInt).map(x => (x = x, y = y.toInt)) .toSet Area( clay = clay, minY = clay.map(_.y).min, maxY = clay.map(_.y).max, - spring = Pos.of(500,0) + spring = (500,0) ) def solve1(area: Area): Int = diff --git a/2018/src/main/scala/aoc2018/Day18.scala b/2018/src/main/scala/aoc2018/Day18.scala index ca0dc63..e06ac43 100644 --- a/2018/src/main/scala/aoc2018/Day18.scala +++ b/2018/src/main/scala/aoc2018/Day18.scala @@ -18,7 +18,7 @@ object Day18 extends AoC: for y <- 0 until sizeX x <- 0 until sizeX - p = Pos.of(x,y) + p = (x,y) do sb.append(area(p)) sb.toString.grouped(sizeX).mkString("\n","\n","\n") @@ -44,7 +44,7 @@ object Day18 extends AoC: for y <- 0 until sizeY x <- 0 until sizeX - p = Pos.of(x,y) + p = (x,y) do val c = area(p) match case '.' => if surroundedBy(p, '|') >= 3 then '|' else '.' @@ -58,7 +58,7 @@ object Day18 extends AoC: val landscape: Landscape = val sizeX = lines(0).length val sizeY = lines.size - val area = List.tabulate(sizeX, sizeY)((x,y) => Pos.of(x,y) -> lines(y)(x)).flatten.toMap + val area = List.tabulate(sizeX, sizeY)((x, y) => (x = x, y = y) -> lines(y)(x)).flatten.toMap Landscape(area, sizeX, sizeY) override lazy val answer1: Int = Iterator.iterate(landscape)(_.tick).nth(10).resourceValue diff --git a/2019/src/main/scala/aoc2019/Day03.scala b/2019/src/main/scala/aoc2019/Day03.scala index 76d93d0..edec964 100644 --- a/2019/src/main/scala/aoc2019/Day03.scala +++ b/2019/src/main/scala/aoc2019/Day03.scala @@ -13,10 +13,10 @@ object Day03 extends AoC: val next: Pos = wire.lastOption.getOrElse(Pos.origin) cmd.head match - case 'R' => wire ++ (1 to length).map(i => Pos.of(next.x + i, next.y)) - case 'L' => wire ++ (1 to length).map(i => Pos.of(next.x - i, next.y)) - case 'U' => wire ++ (1 to length).map(i => Pos.of(next.x, next.y + i)) - case 'D' => wire ++ (1 to length).map(i => Pos.of(next.x, next.y - i)) + case 'R' => wire ++ (1 to length).map(i => (next.x + i, next.y)) + case 'L' => wire ++ (1 to length).map(i => (next.x - i, next.y)) + case 'U' => wire ++ (1 to length).map(i => (next.x, next.y + i)) + case 'D' => wire ++ (1 to length).map(i => (next.x, next.y - i)) def wire(description: String): Vector[Pos] = description.split(',').foldLeft(Vector.empty)((wire,cmd) => append(wire, cmd)) diff --git a/2019/src/main/scala/aoc2019/Day10.scala b/2019/src/main/scala/aoc2019/Day10.scala index 3c59317..743d331 100644 --- a/2019/src/main/scala/aoc2019/Day10.scala +++ b/2019/src/main/scala/aoc2019/Day10.scala @@ -14,7 +14,7 @@ object Day10 extends AoC: val sizeX = lines(0).length val sizeY = lines.length List - .tabulate(sizeX, sizeY)((x,y) => if lines(y)(x) == '#' then Some(Pos.of(x,y)) else None) + .tabulate(sizeX, sizeY)((x,y) => if lines(y)(x) == '#' then Some((x,y)) else None) .flatten .flatten @@ -29,7 +29,7 @@ object Day10 extends AoC: val d = gcd(math.abs(x), math.abs(y)) val nx = x / d val ny = y / d - (1 until d).exists(m => astroids.contains(Pos.of(a.x + (m * nx), a.y + (m * ny)))) + (1 until d).exists(m => astroids.contains((a.x + (m * nx), a.y + (m * ny)))) def maxBlockedByCount(astroids: List[Pos]): Int = @@ -72,4 +72,4 @@ object Day10 extends AoC: fireAll(nr)(right, done ++ left, count + 1, Option.when (count == nr)(aim.target).orElse(result)) override lazy val answer1: Int = maxBlockedByCount(astroids) - override lazy val answer2: Int = fireAll(200)(testLaser(Pos.of(8,16))(astroids)).get.part2 + override lazy val answer2: Int = fireAll(200)(testLaser((8,16))(astroids)).get.part2 diff --git a/2019/src/main/scala/aoc2019/Day11.scala b/2019/src/main/scala/aoc2019/Day11.scala index cc95c35..5e13995 100644 --- a/2019/src/main/scala/aoc2019/Day11.scala +++ b/2019/src/main/scala/aoc2019/Day11.scala @@ -13,7 +13,7 @@ object Day11 extends AoC: object Panels: val empty: Panels = Map.empty.withDefaultValue(0L) - case class Robot(cpu: CPU, pos: Pos = Pos.of(0,0), dir: Dir = N, panels: Panels = Panels.empty): + case class Robot(cpu: CPU, pos: Pos = (0,0), dir: Dir = N, panels: Panels = Panels.empty): @tailrec final def paint: Panels = cpu.withInput(panels(pos)).outputStates match @@ -32,7 +32,7 @@ object Day11 extends AoC: val program: Mem = Mem.parse(input) Robot( cpu = CPU(program), - pos = Pos.of(0,0), + pos = (0,0), dir = N, panels = Panels.empty ) @@ -47,9 +47,9 @@ object Day11 extends AoC: val sb = StringBuffer() for y <- minY to maxY do for x <- minX to maxX do - sb.append(if panels(Pos.of(x,y)) == 1 then '█' else '░') + sb.append(if panels((x,y)) == 1 then '█' else '░') sb.append("\n") sb.toString override lazy val answer1: Int = robot.paint.size - override lazy val answer2: String = robot.copy(panels = Map(Pos.of(0,0) -> 1L).withDefaultValue(0L)).paint.asString + override lazy val answer2: String = robot.copy(panels = Map((0,0) -> 1L).withDefaultValue(0L)).paint.asString diff --git a/2019/src/main/scala/aoc2019/Day15.scala b/2019/src/main/scala/aoc2019/Day15.scala index 8643137..6d2f37a 100644 --- a/2019/src/main/scala/aoc2019/Day15.scala +++ b/2019/src/main/scala/aoc2019/Day15.scala @@ -11,15 +11,15 @@ object Day15 extends AoC: import cpu.* val neighbours: Vector[(Pos,Int)] = - Vector(Pos.of(0, -1) -> 1, Pos.of(0, 1) -> 2, Pos.of(-1, 0) -> 3, Pos.of(1, 0) -> 4) + Vector((0, -1) -> 1, (0, 1) -> 2, (-1, 0) -> 3, (1, 0) -> 4) def move(pos: Pos, cpu: CPU)(delta: Pos, command: Int): (Pos,CPU,Long) = val (next, status) = cpu.withInput(command).outputStates.last (pos + delta, next, status) - def dijkstra(cpu: CPU): (Map[Pos,Int], Option[(Pos,CPU)]) = - val steps = mutable.Map(Pos.of(0,0) -> 0) - val todo = mutable.PriorityQueue(Pos.of(0,0) -> cpu)(using Ordering.by((point, _) => steps(point))) + def dijkstra(cpu: CPU): (Map[Pos, Int], Option[(Pos, CPU)]) = + val steps = mutable.Map((0,0) -> 0) + val todo = mutable.PriorityQueue[(Pos, CPU)]((0,0) -> cpu)(using Ordering.by((point, _) => steps(point))) var target = Option.empty[(Pos,CPU)] while todo.nonEmpty do diff --git a/2019/src/main/scala/aoc2019/Day17.scala b/2019/src/main/scala/aoc2019/Day17.scala index cb9dc9a..7d26c85 100644 --- a/2019/src/main/scala/aoc2019/Day17.scala +++ b/2019/src/main/scala/aoc2019/Day17.scala @@ -10,8 +10,8 @@ object Day17 extends AoC: val program: Mem = Mem.parse(input) extension (p: Pos) - def left: Pos = Pos.of(p.y, -p.x) - def right: Pos = Pos.of(-p.y, p.x) + def left: Pos = (p.y, -p.x) + def right: Pos = (-p.y, p.x) def solve1(memory: Mem): Int = val output = CPU(memory).outputs.map(_.toChar).mkString.split("\n") @@ -20,9 +20,9 @@ object Day17 extends AoC: x <- 0 until output(0).length if output(y)(x) == '#' yield - Pos.of(x, y) + (x = x, y = y) - points.foldLeft(0): (total,next) => + points.foldLeft(0): (total, next) => if Pos.offset4.map(next + _).forall(points.contains) then total + (next.x * next.y) else total @@ -47,10 +47,10 @@ object Day17 extends AoC: def findRobot: (Pos,Pos) = def parseRobotDir(tile: Char): Option[Pos] = tile match - case '>' => Some(Pos.of(1,0)) - case '<' => Some(Pos.of(-1,0)) - case 'v' => Some(Pos.of(0,1)) - case '^' => Some(Pos.of(0,-1)) + case '>' => Some((1,0)) + case '<' => Some((-1,0)) + case 'v' => Some((0,1)) + case '^' => Some((0,-1)) case _ => None val robots = @@ -59,7 +59,7 @@ object Day17 extends AoC: (tile, x) <- row.view.zipWithIndex direction <- parseRobotDir(tile) yield - (Pos.of(x,y), direction) + ((x,y), direction) robots.head diff --git a/2019/src/main/scala/aoc2019/Day18.scala b/2019/src/main/scala/aoc2019/Day18.scala index 1ea0a3e..8b91c9a 100644 --- a/2019/src/main/scala/aoc2019/Day18.scala +++ b/2019/src/main/scala/aoc2019/Day18.scala @@ -76,7 +76,7 @@ object Day18 extends AoC: ) def parse(lines: Vector[String]): (tunnels: Map[Pos,Char], keys: Set[Pos], robots: Set[Pos]) = - val tunnels = for y <- lines.indices; x <- lines(0).indices yield Pos.of(x, y) -> lines(y)(x) + val tunnels = for y <- lines.indices; x <- lines(0).indices yield (x, y) -> lines(y)(x) val keys = tunnels.filter(_.symbol.isKey).map(_.pos) val robots = tunnels.filter(_.symbol.isRobot).map(_.pos) (tunnels.toMap, keys.toSet, robots.toSet) diff --git a/2019/src/main/scala/aoc2019/Day20.scala b/2019/src/main/scala/aoc2019/Day20.scala index cbc21d9..b845d7b 100644 --- a/2019/src/main/scala/aoc2019/Day20.scala +++ b/2019/src/main/scala/aoc2019/Day20.scala @@ -19,7 +19,7 @@ object Day20 extends AoC: def peek(x: Int, y: Int): Char = lines.lift(y).flatMap(_.lift(x)).getOrElse(' ') val sizeX = lines.maxBy(_.length).length val sizeY = lines.length - val maze = Seq.tabulate(sizeX, sizeY)((x,y) => Pos.of(x,y) -> peek(x,y)).flatten.toMap + val maze = Seq.tabulate(sizeX, sizeY)((x,y) => (x = x, y = y) -> peek(x,y)).flatten.toMap val portals = findPortals(sizeX - 3, sizeY - 3, maze) val routes = @@ -46,7 +46,7 @@ object Day20 extends AoC: y <- 2 to sizeY pattern <- patterns yield - val pos = Pos.of(x,y) + val pos = (x,y) val Seq(first,second) = pattern.map(pos.translate).map(maze) if maze(pos) == '.' && first.isLetter && second.isLetter then val label = s"$first$second" diff --git a/2020/src/main/scala/aoc2020/Day20.scala b/2020/src/main/scala/aoc2020/Day20.scala index 2b3605d..c35db8a 100644 --- a/2020/src/main/scala/aoc2020/Day20.scala +++ b/2020/src/main/scala/aoc2020/Day20.scala @@ -22,23 +22,23 @@ object Day20 extends AoC: line .zipWithIndex .collect: - case (c,x)if c == '#' => Pos.of(x, y) + case (c,x)if c == '#' => (x, y) /** note that images are squares */ case class Image(size: Int, pixels: Map[Pos, Char]): - val top: IndexedSeq[Char] = (0 until size).map(x => pixels(Pos.of(x, 0))) - val left: IndexedSeq[Char] = (0 until size).map(y => pixels(Pos.of(0, y))) - val bottom: IndexedSeq[Char] = (0 until size).map(x => pixels(Pos.of(x, size - 1))) - val right: IndexedSeq[Char] = (0 until size).map(y => pixels(Pos.of(size - 1, y))) + val top: IndexedSeq[Char] = (0 until size).map(x => pixels((x, 0))) + val left: IndexedSeq[Char] = (0 until size).map(y => pixels((0, y))) + val bottom: IndexedSeq[Char] = (0 until size).map(x => pixels((x, size - 1))) + val right: IndexedSeq[Char] = (0 until size).map(y => pixels((size - 1, y))) private def rotateCW: Image = - Image(size, pixels.map((pos, pixel) => Pos.of(size - pos.y - 1, pos.x) -> pixel)) + Image(size, pixels.map((pos, pixel) => (size - pos.y - 1, pos.x) -> pixel)) private def flipH: Image = - Image(size, pixels.map((pos, pixel) => Pos.of(size - pos.x - 1, pos.y) -> pixel)) + Image(size, pixels.map((pos, pixel) => (size - pos.x - 1, pos.y) -> pixel)) private def flipV: Image = - Image(size, pixels.map((pos, pixel) => Pos.of(pos.x, size - pos.y - 1) -> pixel)) + Image(size, pixels.map((pos, pixel) => (pos.x, size - pos.y - 1) -> pixel)) def permutations: Vector[Image] = import Iterator.* @@ -79,7 +79,7 @@ object Day20 extends AoC: .map: tile => val id = tile.head.slice(5, 9).toLong val data = tile.drop(1) - val pixels = for y <- 0 to 9; x <- 0 to 9 yield Pos.of(x, y) -> data(y)(x) + val pixels = for y <- 0 to 9; x <- 0 to 9 yield (x, y) -> data(y)(x) Tile(id, Image(10, pixels.toMap)) .toVector @@ -88,7 +88,7 @@ object Day20 extends AoC: def unscrambleTiles(tiles: Vector[Tile]): Map[Pos, Tile] = val size = math.sqrt(tiles.size).toInt - val positions = for x <- 0 until size; y <- 0 until size yield Pos.of(x, y) + val positions = for x <- 0 until size; y <- 0 until size yield (x, y) val corner = corners(tiles).head.permutations val occurrences = tiles.flatMap(_.edges).groupMapReduce(identity)(_ => 1)(_ + _) @@ -99,8 +99,8 @@ object Day20 extends AoC: else val tile = positions.head match case (x = 0, y = 0) => corner.filter(tile => occurrences(tile.top) == 1 && occurrences(tile.left) == 1).head - case (x = 0, y = y) => remaining.filter(tile => tile.top == ordered(Pos.of(0, y - 1)).bottom).head - case (x = x, y = y) => remaining.filter(tile => tile.left == ordered(Pos.of(x - 1, y)).right).head + case (x = 0, y = y) => remaining.filter(tile => tile.top == ordered((0, y - 1)).bottom).head + case (x = x, y = y) => remaining.filter(tile => tile.left == ordered((x - 1, y)).right).head go(remaining.filterNot(_.id == tile.id), positions.tail, ordered.updated(positions.head, tile)) go(tiles.flatMap(_.permutations), positions.toVector, Map.empty) @@ -111,7 +111,7 @@ object Day20 extends AoC: x <- 0 until size y <- 0 until size yield - Pos.of(x, y) -> unscrambled(Pos.of(x / 8, y / 8)).image.pixels(Pos.of(1 + x % 8, 1 + y % 8)) + (x, y) -> unscrambled((x / 8, y / 8)).image.pixels((1 + x % 8, 1 + y % 8)) Image(size, pixels.toMap) @@ -122,9 +122,9 @@ object Day20 extends AoC: val matches = for x <- 0 until image.size - 20 // monster dimensions are 20 x 3 y <- 0 until image.size - 3 - if monster.map(_ + Pos.of(x, y)).forall(pos => candidate.pixels(pos) == '#') + if monster.map(_ + (x, y)).forall(pos => candidate.pixels(pos) == '#') yield (x, y) - val monsters = matches.map(Pos.of(_, _)).flatMap(pos => monster.map(_ + pos)).toSet + val monsters = matches.map((_, _)).flatMap(pos => monster.map(_ + pos)).toSet candidate.pixels.keys.count(pos => candidate.pixels(pos) == '#' && !monsters.contains(pos)) def solve2(tiles: Vector[Tile]): Long = diff --git a/2021/src/main/scala/aoc2021/Day15.scala b/2021/src/main/scala/aoc2021/Day15.scala index 43c90fb..ab9479e 100644 --- a/2021/src/main/scala/aoc2021/Day15.scala +++ b/2021/src/main/scala/aoc2021/Day15.scala @@ -19,7 +19,7 @@ object Day15 extends AoC: val matrix = Vector.tabulate(5 * grid.sizeX, 5 * grid.sizeY): (y, x) => val (mx, px) = x /% grid.sizeX val (my, py) = y /% grid.sizeY - val pv = grid.peek(Pos.of(px, py)) + val pv = grid.peek((px, py)) 1 + (pv - 1 + mx + my) % 9 Grid.fromMatrix(matrix) diff --git a/2021/src/main/scala/aoc2021/Day20.scala b/2021/src/main/scala/aoc2021/Day20.scala index 9b9998c..8ab56a9 100644 --- a/2021/src/main/scala/aoc2021/Day20.scala +++ b/2021/src/main/scala/aoc2021/Day20.scala @@ -12,7 +12,7 @@ object Day20 extends AoC: dy <- -1 to 1 dx <- -1 to 1 yield - Pos.of(dx, dy) + (dx, dy) def within(grid: Vector[Vector[Boolean]], pos: Pos): Boolean = 0 <= pos.x && 0 <= pos.y && pos.y < grid.size && pos.x < grid(pos.y).size @@ -30,7 +30,7 @@ object Day20 extends AoC: val enhanced = for ((row, y) <- framed.zipWithIndex) yield for ((_, x) <- row.zipWithIndex) yield - val pos = Pos.of(x, y) + val pos = (x, y) val area = offsets.map(_ + pos) val bin = area.map(cell => if within(framed, cell) then peek(framed, cell) else canvas) algorithm(int(bin.toVector)) diff --git a/2021/src/main/scala/aoc2021/Day25.scala b/2021/src/main/scala/aoc2021/Day25.scala index fc528ed..c9d2c53 100644 --- a/2021/src/main/scala/aoc2021/Day25.scala +++ b/2021/src/main/scala/aoc2021/Day25.scala @@ -28,9 +28,9 @@ object Day25 extends AoC: copy(tiles = southTiles) val floor: Floor = - val sizeX = lines.head.size - val sizeY = lines.size - val tiles = Vector.tabulate(sizeX, sizeY)((x, y) => Pos.of(x, y) -> lines(y)(x)).flatten.toMap + val sizeX = lines.head.length + val sizeY = lines.length + val tiles = Vector.tabulate(sizeX, sizeY)((x, y) => (x = x, y = y) -> lines(y)(x)).flatten.toMap Floor(tiles, sizeX, sizeY) @tailrec diff --git a/2022/src/main/scala/aoc2022/Day08.scala b/2022/src/main/scala/aoc2022/Day08.scala index a593b74..928c60e 100644 --- a/2022/src/main/scala/aoc2022/Day08.scala +++ b/2022/src/main/scala/aoc2022/Day08.scala @@ -11,10 +11,10 @@ object Day08 extends AoC: p.x == 0 || p.x == grid.maxPos.x | p.y == 0 || p.y == grid.maxPos.y def visible(p: Pos): Boolean = - def pathL(p: Pos): Vector[Int] = (0 to p.x).map(x => grid.peek(Pos.of(x, p.y))).toVector - def pathR(p: Pos): Vector[Int] = (p.x to grid.maxPos.x).map(x => grid.peek(Pos.of(x, p.y))).toVector.reverse - def pathT(p: Pos): Vector[Int] = (0 to p.y).map(y => grid.peek(Pos.of(p.x, y))).toVector - def pathB(p: Pos): Vector[Int] = (p.y to grid.maxPos.y).map(y => grid.peek(Pos.of(p.x, y))).toVector.reverse + def pathL(p: Pos): Vector[Int] = (0 to p.x).map(x => grid.peek((x, p.y))).toVector + def pathR(p: Pos): Vector[Int] = (p.x to grid.maxPos.x).map(x => grid.peek((x, p.y))).toVector.reverse + def pathT(p: Pos): Vector[Int] = (0 to p.y).map(y => grid.peek((p.x, y))).toVector + def pathB(p: Pos): Vector[Int] = (p.y to grid.maxPos.y).map(y => grid.peek((p.x, y))).toVector.reverse def visible(todo: Vector[Int]): Boolean = todo.init.max < todo.last val vl = visible(pathL(p)) val vr = visible(pathR(p)) @@ -29,10 +29,10 @@ object Day08 extends AoC: else c def scenicScore(p: Pos): Int = - def pathL(p: Pos): Vector[Int] = (0 to p.x).map(x => grid.peek(Pos.of(x, p.y))).toVector.reverse - def pathR(p: Pos): Vector[Int] = (p.x to grid.maxPos.x).map(x => grid.peek(Pos.of(x, p.y))).toVector - def pathT(p: Pos): Vector[Int] = (0 to p.y).map(y => grid.peek(Pos.of(p.x, y))).toVector.reverse - def pathB(p: Pos): Vector[Int] = (p.y to grid.maxPos.y).map(y => grid.peek(Pos.of(p.x, y))).toVector + def pathL(p: Pos): Vector[Int] = (0 to p.x).map(x => grid.peek((x, p.y))).toVector.reverse + def pathR(p: Pos): Vector[Int] = (p.x to grid.maxPos.x).map(x => grid.peek((x, p.y))).toVector + def pathT(p: Pos): Vector[Int] = (0 to p.y).map(y => grid.peek((p.x, y))).toVector.reverse + def pathB(p: Pos): Vector[Int] = (p.y to grid.maxPos.y).map(y => grid.peek((p.x, y))).toVector def score(todo: Vector[Int]): Int = val index = todo.tail.indexWhere(_ >= todo.head) if index != -1 then index + 1 else todo.tail.length diff --git a/2022/src/main/scala/aoc2022/Day09.scala b/2022/src/main/scala/aoc2022/Day09.scala index 30fee06..c203ef6 100644 --- a/2022/src/main/scala/aoc2022/Day09.scala +++ b/2022/src/main/scala/aoc2022/Day09.scala @@ -75,7 +75,7 @@ object Day09 extends AoC: object Bacterium: def of(size: Int): Bacterium = - Bacterium(Vector.fill(size)(Pos.of(0, 0))) + Bacterium(Vector.fill(size)((0, 0))) def solve(commands: Vector[Command], size: Int): Int = commands diff --git a/2022/src/main/scala/aoc2022/Day14.scala b/2022/src/main/scala/aoc2022/Day14.scala index 2d1b0d0..39a7324 100644 --- a/2022/src/main/scala/aoc2022/Day14.scala +++ b/2022/src/main/scala/aoc2022/Day14.scala @@ -18,7 +18,7 @@ object Day14 extends AoC: line.trim .split(""" -> """) .foldLeft(Vector.empty[Pos]): - case (path, s"$x,$y") => path :+ Pos.of(x.toInt, y.toInt) + case (path, s"$x,$y") => path :+ (x.toInt, y.toInt) case (_, e) => sys.error(s"unable to parse $e") @@ -27,10 +27,10 @@ object Day14 extends AoC: val paths = lines.map(parseLine) def segment(from: Pos, to: Pos): Vector[Pos] = - (if from.x == to.x && from.y < to.y then (from.y to to.y).map(y => Pos.of(to.x, y)) - else if from.x == to.x && from.y > to.y then (to.y to from.y).map(y => Pos.of(to.x, y)) - else if from.y == to.y && from.x < to.x then (from.x to to.x).map(x => Pos.of(x, to.y)) - else if from.y == to.y && from.x > to.x then (to.x to from.x).map(x => Pos.of(x, to.y)) + (if from.x == to.x && from.y < to.y then (from.y to to.y).map(y => (to.x, y)) + else if from.x == to.x && from.y > to.y then (to.y to from.y).map(y => (to.x, y)) + else if from.y == to.y && from.x < to.x then (from.x to to.x).map(x => (x, to.y)) + else if from.y == to.y && from.x > to.x then (to.x to from.x).map(x => (x, to.y)) else sys.error("boom!")).toVector @tailrec @@ -53,7 +53,7 @@ object Day14 extends AoC: @tailrec private def land(current: Pos): (Pos, Boolean) = def find(p: Pos): Option[Pos] = - val below: Vector[Pos] = Vector(Pos.of(p.x, p.y + 1), Pos.of(p.x - 1, p.y + 1), Pos.of(p.x + 1, p.y + 1)) + val below: Vector[Pos] = Vector((p.x, p.y + 1), (p.x - 1, p.y + 1), (p.x + 1, p.y + 1)) below.find(p => get(p).isEmpty || get(p).contains(Air)) find(current) match case None => (current, false) @@ -94,7 +94,7 @@ object Day14 extends AoC: row.updated(p.y, row(p.y).updated(p.x, Rock)) :+ Vector.fill(1000)(Air) :+ Vector.fill(1000)(Rock) Cave(view, 0) - private val drip: Pos = Pos.of(500, 0) + private val drip: Pos = (500, 0) override lazy val answer1: Int = Cave.fromRocks1(rocks).solve1 diff --git a/2022/src/main/scala/aoc2022/Day17.scala b/2022/src/main/scala/aoc2022/Day17.scala index eb2a170..12b42e4 100644 --- a/2022/src/main/scala/aoc2022/Day17.scala +++ b/2022/src/main/scala/aoc2022/Day17.scala @@ -12,7 +12,7 @@ object Day17 extends AoC: val moves: Vector[Move] = input.toVector - val origin: Pos = Pos.of(0,0) + val origin: Pos = (0,0) type Move = Char val L = '<' @@ -23,13 +23,13 @@ object Day17 extends AoC: val pattern: LazyList[Move] = moves.to(LazyList) #::: pattern sealed abstract class Rock(val relative: List[Pos]): - def withOrigin(o: Pos): List[Pos] = relative.map(p => Pos.of(p.x + o.x, p.y + o.y)) + def withOrigin(o: Pos): List[Pos] = relative.map(p => (p.x + o.x, p.y + o.y)) - case object Min extends Rock(List(Pos.of(0,0), Pos.of(1,0), Pos.of(2,0), Pos.of(3,0))) - case object Plus extends Rock(List(Pos.of(1,0), Pos.of(0,1), Pos.of(1,1), Pos.of(2,1), Pos.of(1,2))) - case object El extends Rock(List(Pos.of(0,0), Pos.of(1,0), Pos.of(2,0), Pos.of(2,1), Pos.of(2,2))) - case object Stack extends Rock(List(Pos.of(0,0), Pos.of(0,1), Pos.of(0,2), Pos.of(0,3))) - case object Box extends Rock(List(Pos.of(0,0), Pos.of(1,0), Pos.of(0,1), Pos.of(1,1))) + case object Min extends Rock(List((0,0), (1,0), (2,0), (3,0))) + case object Plus extends Rock(List((1,0), (0,1), (1,1), (2,1), (1,2))) + case object El extends Rock(List((0,0), (1,0), (2,0), (2,1), (2,2))) + case object Stack extends Rock(List((0,0), (0,1), (0,2), (0,3))) + case object Box extends Rock(List((0,0), (1,0), (0,1), (1,1))) object Rock: val sequence: LazyList[Rock] = LazyList(Min, Plus, El, Stack, Box) #::: sequence @@ -83,7 +83,7 @@ object Day17 extends AoC: Chamber(rocks = rocks.tail, pattern = consumed, stopped = dropped.filter(_.y >= maxY - slidingWindow), height = maxY) def cycleInvariant: Set[Pos] = - stopped.map(_ - Pos.of(0, height - slidingWindow)) + stopped.map(_ - (0, height - slidingWindow)) object Chamber: diff --git a/2022/src/main/scala/aoc2022/Day23.scala b/2022/src/main/scala/aoc2022/Day23.scala index 052d0b3..0faaba5 100644 --- a/2022/src/main/scala/aoc2022/Day23.scala +++ b/2022/src/main/scala/aoc2022/Day23.scala @@ -27,18 +27,18 @@ object Day23 extends AoC: def valid(f: Pos, d: Dir): Boolean = val offset = Set(-1, 0, 1) d match - case N => offset.forall(d => !elves.contains(f + Pos.of( d,-1))) - case S => offset.forall(d => !elves.contains(f + Pos.of( d, 1))) - case W => offset.forall(d => !elves.contains(f + Pos.of(-1, d))) - case E => offset.forall(d => !elves.contains(f + Pos.of( 1, d))) + case N => offset.forall(d => !elves.contains(f + ( d,-1))) + case S => offset.forall(d => !elves.contains(f + ( d, 1))) + case W => offset.forall(d => !elves.contains(f + (-1, d))) + case E => offset.forall(d => !elves.contains(f + ( 1, d))) def propose(f: Pos, ds: Seq[Dir]): Option[Pos] = def proposal(d: Dir): Pos = d match - case N => f + Pos.of( 0,-1) - case S => f + Pos.of( 0, 1) - case W => f + Pos.of(-1, 0) - case E => f + Pos.of( 1, 0) + case N => f + ( 0,-1) + case S => f + ( 0, 1) + case W => f + (-1, 0) + case E => f + ( 1, 0) ds.find(d => valid(f,d)).map(proposal) val proposals: Map[Pos,Option[Pos]] = @@ -60,7 +60,7 @@ object Day23 extends AoC: for x <- minX to maxX y <- minY to maxY - if !elves.contains(Pos.of(x, y)) + if !elves.contains((x, y)) yield 1 size.sum diff --git a/2022/src/main/scala/aoc2022/Day24.scala b/2022/src/main/scala/aoc2022/Day24.scala index 6ecad40..c3b1db9 100644 --- a/2022/src/main/scala/aoc2022/Day24.scala +++ b/2022/src/main/scala/aoc2022/Day24.scala @@ -12,7 +12,7 @@ object Day24 extends AoC: val sizeY: Int = max.y + 1 val fieldSize: Int = sizeX * sizeY def isField(p: Pos): Boolean = p.x >= 0 && p.x <= max.x && p.y >= 0 && p.y <= max.y - def transpose: Bounds = copy(max = Pos.of(max.y, max.x)) + def transpose: Bounds = copy(max = (max.y, max.x)) enum Dir(val char: Char) derives CanEqual: @@ -99,7 +99,7 @@ object Day24 extends AoC: type Paths = Set[Pos] object Paths: - def start: Paths = Set(Pos.of(-1, 0)) + def start: Paths = Set((-1, 0)) case class World( target: Pos, @@ -125,7 +125,7 @@ object Day24 extends AoC: found.flatMap: p => val ms = p.adjoint4.filter(free(nextField)) val test = free(nextField)(p) && p.adjoint4.exists(free(streams.futureField)) && bounds.isField(p) - if test || p == bounds.max + Pos.of(0, 1) || p == Pos.of(0, -1) then ms + p else ms + if test || p == bounds.max + (0, 1) || p == (0, -1) then ms + p else ms def reachedGoal: Boolean = found.contains(target) @@ -148,7 +148,7 @@ object Day24 extends AoC: val sizeX = initField.head.size val sizeY = initField.size - val bounds: Bounds = Bounds(Pos.of(sizeX - 1 , sizeY - 1)) + val bounds: Bounds = Bounds((sizeX - 1 , sizeY - 1)) def make(dir: Dir, f: Field[Char]): Vector[Stream] = def stream(line: Vector[Char]): LazyList[Char] = @@ -182,12 +182,12 @@ object Day24 extends AoC: val (w1, m1) = loop(world) val w2 = w1.copy( - target = Pos.of(0,0), + target = (0,0), currentField = w1.nextField, nextField = w1.streams.futureField, streams = w1.streams.next, minutes = m1 + 1, - found = Set(w1.bounds.max + Pos.of(0, 1)) + found = Set(w1.bounds.max + (0, 1)) ) val (w3, m3) = loop(w2) @@ -197,7 +197,7 @@ object Day24 extends AoC: nextField = w3.streams.futureField, streams = w3.streams.next, minutes = m3 + 1, - found = Set(Pos.of(0,-1)) + found = Set((0,-1)) ) val (_, m5) = loop(w4) diff --git a/2023/src/main/scala/aoc2023/Day03.scala b/2023/src/main/scala/aoc2023/Day03.scala index 29a50ee..1a90b41 100644 --- a/2023/src/main/scala/aoc2023/Day03.scala +++ b/2023/src/main/scala/aoc2023/Day03.scala @@ -46,17 +46,17 @@ object Day03 extends AoC: lazy val numbers: Vector[Num] = @tailrec - def compute(pos: Pos = Pos.of(0,0), cur: String = "", loc: Vector[Pos] = Vector.empty, acc: Vector[Num] = Vector.empty): Vector[Num] = + def compute(pos: Pos = (0,0), cur: String = "", loc: Vector[Pos] = Vector.empty, acc: Vector[Num] = Vector.empty): Vector[Num] = if pos.y >= chars.sizeY then acc else if pos.x >= chars.sizeX then - compute(Pos.of(0, pos.y + 1), "", Vector.empty, if cur.nonEmpty then acc :+ Num(loc) else acc) + compute((0, pos.y + 1), "", Vector.empty, if cur.nonEmpty then acc :+ Num(loc) else acc) else if pos.isDigit then - compute(Pos.of(pos.x + 1, pos.y), s"$cur${chars.peek(pos)}", loc :+ pos, acc) + compute((pos.x + 1, pos.y), s"$cur${chars.peek(pos)}", loc :+ pos, acc) else - compute(Pos.of(pos.x + 1, pos.y), "", Vector.empty, if cur.nonEmpty then acc :+ Num(loc) else acc) + compute((pos.x + 1, pos.y), "", Vector.empty, if cur.nonEmpty then acc :+ Num(loc) else acc) compute() lazy val numbersWithAdjacentSymbols: Vector[Num] = diff --git a/2023/src/main/scala/aoc2023/Day10.scala b/2023/src/main/scala/aoc2023/Day10.scala index cf82dda..692f861 100644 --- a/2023/src/main/scala/aoc2023/Day10.scala +++ b/2023/src/main/scala/aoc2023/Day10.scala @@ -50,7 +50,7 @@ object Day10 extends AoC: case (a,(l,y)) => l.zipWithIndex.foldLeft(a): case (a,(c,x)) => - a + (Pos.of(x,y) -> Tile.fromChar(c)) + a + ((x,y) -> Tile.fromChar(c)) lazy val maxX: Int = tiles.keys.map(_.x).max lazy val maxY: Int = tiles.keys.map(_.y).max @@ -90,16 +90,16 @@ object Day10 extends AoC: dir match case N if pos.y > 0 => val r = cacheY.filter(p => p.x == pos.x && p.y < pos.y) - if r.nonEmpty then (r.last.y + 1 until pos.y).map(y => Pos.of(pos.x, y)).toSet else Set.empty + if r.nonEmpty then (r.last.y + 1 until pos.y).map(y => (pos.x, y)).toSet else Set.empty case E if pos.x < maxX => val r = cacheX.filter(p => p.y == pos.y && p.x > pos.x) - if r.nonEmpty then (pos.x + 1 until r.head.x).map(x => Pos.of(x, pos.y)).toSet else Set.empty + if r.nonEmpty then (pos.x + 1 until r.head.x).map(x => (x, pos.y)).toSet else Set.empty case S if pos.y < maxY => val r = cacheY.filter(p => p.x == pos.x && p.y > pos.y) - if r.nonEmpty then (pos.y + 1 until r.head.y).map(y => Pos.of(pos.x, y)).toSet else Set.empty + if r.nonEmpty then (pos.y + 1 until r.head.y).map(y => (pos.x, y)).toSet else Set.empty case W if pos.x > 0 => val r = cacheX.filter(p => p.y == pos.y && p.x < pos.x) - if r.nonEmpty then (r.last.x + 1 until pos.x).map(x => Pos.of(x, pos.y)).toSet else Set.empty + if r.nonEmpty then (r.last.x + 1 until pos.x).map(x => (x, pos.y)).toSet else Set.empty case _ => Set.empty @tailrec diff --git a/2023/src/main/scala/aoc2023/Day11.scala b/2023/src/main/scala/aoc2023/Day11.scala index 02ffe5b..f600922 100644 --- a/2023/src/main/scala/aoc2023/Day11.scala +++ b/2023/src/main/scala/aoc2023/Day11.scala @@ -12,7 +12,7 @@ object Day11 extends AoC: lazy val positions: Vector[Pos] = galaxies.zipWithIndex.flatMap((l,y) => l.zipWithIndex.flatMap((c,x) => - Option.when(c == '#')(Pos.of(x, y)))) + Option.when(c == '#')((x, y)))) def empty(gs: Vector[Vector[Char]]): Set[Int] = gs.zipWithIndex.flatMap((line,i) => if line.forall(_ == '.') then Some(i) else None).toSet diff --git a/2023/src/main/scala/aoc2023/Day16.scala b/2023/src/main/scala/aoc2023/Day16.scala index 23fa218..e646dbc 100644 --- a/2023/src/main/scala/aoc2023/Day16.scala +++ b/2023/src/main/scala/aoc2023/Day16.scala @@ -61,14 +61,14 @@ object Day16 extends AoC: trace(start, direction).toMap.keys.size def maxEnergized: Int = - val north = List.tabulate(sizeX)(x => Pos.of(x, 0) -> S) - val east = List.tabulate(sizeY)(y => Pos.of(sizeX - 1, y) -> W) - val south = List.tabulate(sizeX)(x => Pos.of(x, sizeY - 1) -> N) - val west = List.tabulate(sizeY)(y => Pos.of(0, y) -> E) + val north = List.tabulate(sizeX)(x => (x, 0) -> S) + val east = List.tabulate(sizeY)(y => (sizeX - 1, y) -> W) + val south = List.tabulate(sizeX)(x => (x, sizeY - 1) -> N) + val west = List.tabulate(sizeY)(y => (0, y) -> E) val entries = List(north, east, south, west).flatten entries.map((p,d) => energized(p,d)).max lazy val grid: Grid = Grid(lines.map(_.toVector)) - override lazy val answer1: Long = grid.energized(start = Pos.of(0,0), direction = E) + override lazy val answer1: Long = grid.energized(start = (0,0), direction = E) override lazy val answer2: Long = grid.maxEnergized diff --git a/2023/src/main/scala/aoc2023/Day17.scala b/2023/src/main/scala/aoc2023/Day17.scala index ebd97b7..d62ac49 100644 --- a/2023/src/main/scala/aoc2023/Day17.scala +++ b/2023/src/main/scala/aoc2023/Day17.scala @@ -23,7 +23,7 @@ object Day17 extends AoC: (current = next, direction = direction, steps = steps) -> city.peek(next) val start = (current = Pos.origin, direction = Pos.origin, steps = 0) - val target = (n: Crucible) => n.current == Pos.of(city.sizeX - 1, city.sizeY - 1) && canStop(n) + val target = (n: Crucible) => n.current == (city.sizeX - 1, city.sizeY - 1) && canStop(n) Dijkstra.run(start, target, reachable).map(_.right) diff --git a/2023/src/main/scala/aoc2023/Day18.scala b/2023/src/main/scala/aoc2023/Day18.scala index 51453e0..5560ced 100644 --- a/2023/src/main/scala/aoc2023/Day18.scala +++ b/2023/src/main/scala/aoc2023/Day18.scala @@ -49,13 +49,13 @@ object Day18 extends AoC: x <- min.x to max.x y <- min.y to max.y yield - Pos.of(x, y) + (x, y) /** cubic meter = one point - data driven flood algorithm with some set arithmetic */ def dig1(operations: Vector[Op]): Long = val holes: Set[Pos] = operations.foldLeft(Vector(Pos.origin))((a,o) => a ++ a.last.move1(o)).toSet - val min = holes.reduce(_ minimize _) - Pos.of(1, 1) - val max = holes.reduce(_ maximize _) + Pos.of(1, 1) + val min = holes.reduce(_ minimize _) - (1, 1) + val max = holes.reduce(_ maximize _) + (1, 1) @tailrec def flood(todo: List[Pos], visited: Set[Pos] = Set.empty): Set[Pos] = diff --git a/2023/src/main/scala/aoc2023/Day23.scala b/2023/src/main/scala/aoc2023/Day23.scala index a9ba47f..7e493c1 100644 --- a/2023/src/main/scala/aoc2023/Day23.scala +++ b/2023/src/main/scala/aoc2023/Day23.scala @@ -46,8 +46,8 @@ object Day23 extends AoC: result.toMap def solve1(grid: Grid[Char]): Int = - val from = Pos.of(0, 1) - val to = Pos.of(grid.sizeX - 2, grid.sizeY - 1) + val from = (0, 1) + val to = (grid.sizeX - 2, grid.sizeY - 1) val graph = grid.computeGraph(from, to) def loop(p: Pos, visited: Set[Pos], length: Int, longest: Int): Int = if p == to then diff --git a/2024/src/main/scala/aoc2024/Day04.scala b/2024/src/main/scala/aoc2024/Day04.scala index c4c8aea..7b41fc9 100644 --- a/2024/src/main/scala/aoc2024/Day04.scala +++ b/2024/src/main/scala/aoc2024/Day04.scala @@ -9,14 +9,14 @@ object Day04 extends AoC: type Dir = Pos => Pos - val N: Dir = p => Pos.of(p.x, p.y - 1) - val E: Dir = p => Pos.of(p.x + 1, p.y) - val S: Dir = p => Pos.of(p.x, p.y + 1) - val W: Dir = p => Pos.of(p.x - 1, p.y) - val NE: Dir = p => Pos.of(p.x + 1, p.y - 1) - val SE: Dir = p => Pos.of(p.x + 1, p.y + 1) - val NW: Dir = p => Pos.of(p.x - 1, p.y - 1) - val SW: Dir = p => Pos.of(p.x - 1, p.y + 1) + val N: Dir = p => (p.x, p.y - 1) + val E: Dir = p => (p.x + 1, p.y) + val S: Dir = p => (p.x, p.y + 1) + val W: Dir = p => (p.x - 1, p.y) + val NE: Dir = p => (p.x + 1, p.y - 1) + val SE: Dir = p => (p.x + 1, p.y + 1) + val NW: Dir = p => (p.x - 1, p.y - 1) + val SW: Dir = p => (p.x - 1, p.y + 1) val grid: Grid[Char] = Grid.fromLines(lines) diff --git a/2024/src/main/scala/aoc2024/Day14.scala b/2024/src/main/scala/aoc2024/Day14.scala index a412ddf..9ae67d9 100644 --- a/2024/src/main/scala/aoc2024/Day14.scala +++ b/2024/src/main/scala/aoc2024/Day14.scala @@ -12,7 +12,7 @@ object Day14 extends AoC: val space: Space = val robots: Vector[Robot] = lines.map: - case s"p=$px,$py v=$vx,$vy" => Robot(Pos.of(px.toInt, py.toInt), Pos.of(vx.toInt, vy.toInt)) + case s"p=$px,$py v=$vx,$vy" => Robot((px.toInt, py.toInt), (vx.toInt, vy.toInt)) Space(robots, sizeX = 101, sizeY = 103) @@ -32,13 +32,13 @@ object Day14 extends AoC: y <- 0 until sizeY x <- 0 until sizeX yield - Pos.of(x, y) + (x, y) def move(r: Robot): Robot = val n = r.p + r.v val nx = if n.x < 0 then sizeX + n.x else if n.x >= sizeX then n.x - sizeX else n.x val ny = if n.y < 0 then sizeY + n.y else if n.y >= sizeY then n.y - sizeY else n.y - Robot(Pos.of(nx, ny), r.v) + Robot((nx, ny), r.v) def next: Space = copy(robots = robots.map(move)) @@ -48,11 +48,11 @@ object Day14 extends AoC: def robotsIn(min: Pos, max: Pos): Vector[Robot] = robots.filter(r => r.p.x >= min.x & r.p.x <= max.x & r.p.y >= min.y & r.p.y <= max.y) - val mid = Pos.of(sizeX / 2, sizeY / 2) - val robotsInQ1: Vector[Robot] = robotsIn(Pos.of(0, 0), Pos.of(mid.x - 1, mid.y - 1)) - val robotsInQ2: Vector[Robot] = robotsIn(Pos.of(mid.x + 1, 0), Pos.of(sizeX - 1, mid.y - 1)) - val robotsInQ3: Vector[Robot] = robotsIn(Pos.of(0, mid.y + 1), Pos.of(mid.x - 1, sizeY - 1)) - val robotsInQ4: Vector[Robot] = robotsIn(Pos.of(mid.x + 1, mid.y+1), Pos.of(sizeX - 1, sizeY - 1)) + val mid = (x = sizeX / 2, y = sizeY / 2) + val robotsInQ1: Vector[Robot] = robotsIn((0, 0), (mid.x - 1, mid.y - 1)) + val robotsInQ2: Vector[Robot] = robotsIn((mid.x + 1, 0), (sizeX - 1, mid.y - 1)) + val robotsInQ3: Vector[Robot] = robotsIn((0, mid.y + 1), (mid.x - 1, sizeY - 1)) + val robotsInQ4: Vector[Robot] = robotsIn((mid.x + 1, mid.y+1), (sizeX - 1, sizeY - 1)) Vector(robotsInQ1, robotsInQ2, robotsInQ3, robotsInQ4).map(_.size.toLong).product def robotClusters: Set[Set[Pos]] = diff --git a/2024/src/main/scala/aoc2024/Day15.scala b/2024/src/main/scala/aoc2024/Day15.scala index 97895e1..fe2593f 100644 --- a/2024/src/main/scala/aoc2024/Day15.scala +++ b/2024/src/main/scala/aoc2024/Day15.scala @@ -33,14 +33,6 @@ object Day15 extends AoC: lazy val robotPosition: Pos = grid.find((_, c) => c == '@').map(_.pos).head lazy val boxPositions: Set[Pos] = grid.filter((_, c) => c == 'O' | c == '[').keySet - override def toString: String = - val representation = for { - y <- 0 until sizeY - x <- 0 until sizeX - p = Pos.of(x, y) - } yield grid(p) - representation.mkString("").grouped(sizeX).mkString("\n") - def isFree(p: Pos): Boolean = grid(p) == '.' def isWall(p: Pos): Boolean = grid(p) == '#' def isBox(p: Pos): Boolean = grid(p) == 'O' | grid(p) == ']' | grid(p) == '[' @@ -103,7 +95,7 @@ object Day15 extends AoC: val positions = for { (l, y) <- top.split("\n").zipWithIndex (c, x) <- l.trim.zipWithIndex - } yield Pos.of(x, y) -> c + } yield (x, y) -> c val moves = bottom.filterNot(_ == '\n').toList (Grid(positions.toMap), moves) diff --git a/2024/src/test/scala/aoc2024/Test2024.scala b/2024/src/test/scala/aoc2024/Test2024.scala index 8f51ca8..0606e97 100644 --- a/2024/src/test/scala/aoc2024/Test2024.scala +++ b/2024/src/test/scala/aoc2024/Test2024.scala @@ -60,7 +60,7 @@ class Test2024 extends AnyFunSuite: assertResult(37221261688308L)(Day17.answer2) test("Day 18: RAM Run"): assertResult(436)(Day18.answer1) - assertResult(Pos.of(61, 50))(Day18.answer2) + assertResult((61, 50))(Day18.answer2) test("Day 19: Linen Layout"): assertResult(353)(Day19.answer1) assertResult(880877787214477L)(Day19.answer2) diff --git a/2025/src/main/scala/aoc2025/Day04.scala b/2025/src/main/scala/aoc2025/Day04.scala index 6e1c74f..1a654b8 100644 --- a/2025/src/main/scala/aoc2025/Day04.scala +++ b/2025/src/main/scala/aoc2025/Day04.scala @@ -8,7 +8,7 @@ import scala.annotation.tailrec object Day04 extends AoC: val (minPos, maxPos, rolls) = - val ps = for y <- lines.indices ; x <- lines.head.indices yield Pos.of(x, y) + val ps = for y <- lines.indices ; x <- lines.head.indices yield (x = x, y = y) (ps.min, ps.max, ps.filter(p => lines(p.y)(p.x) == '@').toSet) extension (p: Pos) diff --git a/nmcb/src/main/scala/nmcb/Grid.scala b/nmcb/src/main/scala/nmcb/Grid.scala index c4c0d0a..5521c73 100644 --- a/nmcb/src/main/scala/nmcb/Grid.scala +++ b/nmcb/src/main/scala/nmcb/Grid.scala @@ -7,12 +7,12 @@ case class Grid[+A](matrix: Vector[Vector[A]]): val sizeY: Int = matrix.size val sizeX: Int = matrix.head.size val minPos: Pos = Pos.origin - val maxPos: Pos = Pos.of(sizeX - 1, sizeY - 1) + val maxPos: Pos = (sizeX - 1, sizeY - 1) assert(matrix.forall(row => row.size == sizeX)) lazy val positions: Set[Pos] = - (for {x <- 0 until sizeX; y <- 0 until sizeY} yield Pos.of(x, y)).toSet + (for {x <- 0 until sizeX; y <- 0 until sizeY} yield (x, y)).toSet inline def elements[A1 >: A]: Set[(Pos,A1)] = positions.map(p => p -> peek(p)) From 615ef3cda601d017a21471f4ac0d81cd5badfe39 Mon Sep 17 00:00:00 2001 From: nmcb Date: Fri, 27 Feb 2026 00:01:48 +0100 Subject: [PATCH 2/3] layout --- 2015/src/main/scala/aoc2015/Day18.scala | 16 +++++++++------- 2017/src/main/scala/aoc2017/Day03.scala | 2 +- 2017/src/main/scala/aoc2017/Day22.scala | 4 ++-- 2017/src/main/scala/aoc2017/Day23.scala | 8 ++++---- 2018/src/main/scala/aoc2018/Day06.scala | 2 +- 2018/src/main/scala/aoc2018/Day10.scala | 2 +- 2018/src/main/scala/aoc2018/Day11.scala | 21 +++++++++++---------- 2018/src/main/scala/aoc2018/Day13.scala | 10 +++++----- 2018/src/main/scala/aoc2018/Day15.scala | 2 +- 2018/src/main/scala/aoc2018/Day18.scala | 4 ++-- 2018/src/main/scala/aoc2018/Day20.scala | 4 ++-- 2018/src/main/scala/aoc2018/Day22.scala | 2 +- 2019/src/main/scala/aoc2019/Day10.scala | 2 +- 2019/src/main/scala/aoc2019/Day11.scala | 8 ++++---- 2019/src/main/scala/aoc2019/Day13.scala | 4 ++-- 2019/src/main/scala/aoc2019/Day15.scala | 4 ++-- 2019/src/main/scala/aoc2019/Day17.scala | 2 +- 2019/src/main/scala/aoc2019/Day19.scala | 4 ++-- 2019/src/main/scala/aoc2019/Day20.scala | 4 ++-- 2020/src/main/scala/aoc2020/Day11.scala | 14 +++++++------- 2021/src/main/scala/aoc2021/Day11.scala | 10 +++++----- 2021/src/main/scala/aoc2021/Day13.scala | 2 +- 2022/src/main/scala/aoc2022/Day17.scala | 12 ++++++------ 2022/src/main/scala/aoc2022/Day24.scala | 4 ++-- 2023/src/main/scala/aoc2023/Day03.scala | 2 +- 2023/src/main/scala/aoc2023/Day10.scala | 20 ++++++++++---------- 2023/src/main/scala/aoc2023/Day16.scala | 2 +- 2025/src/main/scala/aoc2025/Day10.scala | 4 ++-- nmcb/src/main/scala/nmcb/Grid.scala | 2 +- 29 files changed, 90 insertions(+), 87 deletions(-) diff --git a/2015/src/main/scala/aoc2015/Day18.scala b/2015/src/main/scala/aoc2015/Day18.scala index 9b51478..7bde01c 100644 --- a/2015/src/main/scala/aoc2015/Day18.scala +++ b/2015/src/main/scala/aoc2015/Day18.scala @@ -1,6 +1,7 @@ package aoc2015 import nmcb.* +import nmcb.pos.{*, given} import scala.annotation.tailrec @@ -37,7 +38,7 @@ object Day18 extends AoC: Vector.empty[Row] /** grid encapsulates the animation of a light configuration */ - case class Grid(conf: Conf, overlay: Set[(Int,Int)] = Set.empty): + case class Grid(conf: Conf, overlay: Set[Pos] = Set.empty): val sizeX: Int = conf.map(_.size).max val sizeY: Int = conf.size val minX: Int = 0 @@ -45,13 +46,13 @@ object Day18 extends AoC: val maxX: Int = sizeX - 1 val maxY: Int = sizeY - 1 - def withOverlay(on: (Int,Int)*): Grid = + def withOverlay(on: Pos*): Grid = copy(overlay = Set.from(on)) - def fold[A](zero: A)(inc: A => A)(f: (Int,Int,A) => A): A = + def fold[A](zero: A)(inc: A => A)(f: (Int, Int, A) => A): A = (minY to maxY).foldLeft(zero): (z, y) => (minX to maxX).foldLeft(inc(z)): (z, x) => - f(x,y,z) + f(x, y, z) def count: Int = fold(0)(identity): (x, y, n) => @@ -61,15 +62,16 @@ object Day18 extends AoC: if overlay(y, x) then on else conf(y)(x) def neighbours(x: Int, y: Int): Vector[Light] = - Vector((-1,-1),(0,-1),(1,-1),(-1, 0),(1, 0),(-1,1),(0, 1),(1, 1)) + Pos.offset8 .map((dx, dy) => (x + dx, y + dy)) .filter((px, py) => px >= minX && px <= maxX && py >= minY && py <= maxY) .map(light) + .toVector def next: Grid = val step: Conf = - fold(Conf.empty)(_ :+ Row.empty)((x,y,conf) => - conf.init :+ (conf.last :+ light(x,y).next(neighbours(x,y)))) + fold(Conf.empty)(_ :+ Row.empty)((x, y, conf) => + conf.init :+ (conf.last :+ light(x, y).next(neighbours(x, y)))) copy(conf = step) @tailrec diff --git a/2017/src/main/scala/aoc2017/Day03.scala b/2017/src/main/scala/aoc2017/Day03.scala index cae4b84..90c98b8 100644 --- a/2017/src/main/scala/aoc2017/Day03.scala +++ b/2017/src/main/scala/aoc2017/Day03.scala @@ -32,7 +32,7 @@ object Day03 extends AoC: (x, y) @tailrec - def loop(n: Int, squares: Map[Pos,Int] = Map((0,0) -> 1)): Int = + def loop(n: Int, squares: Map[Pos,Int] = Map((0, 0) -> 1)): Int = val point = position(n) val result = spiralScan.map(_ + point).flatMap(squares.get).sum if result > to then diff --git a/2017/src/main/scala/aoc2017/Day22.scala b/2017/src/main/scala/aoc2017/Day22.scala index 037f11a..dee9056 100644 --- a/2017/src/main/scala/aoc2017/Day22.scala +++ b/2017/src/main/scala/aoc2017/Day22.scala @@ -75,8 +75,8 @@ object Day22 extends AoC: row .zipWithIndex .collect: - case ('#',x) => (x,y) -> Infected - case ('.',x) => (x,y) -> Clean + case ('#',x) => (x, y) -> Infected + case ('.',x) => (x, y) -> Clean .toMap .withDefaultValue(Clean) diff --git a/2017/src/main/scala/aoc2017/Day23.scala b/2017/src/main/scala/aoc2017/Day23.scala index 4abe0b4..ef33f03 100644 --- a/2017/src/main/scala/aoc2017/Day23.scala +++ b/2017/src/main/scala/aoc2017/Day23.scala @@ -38,10 +38,10 @@ object Day23 extends AoC: def step: CPU = if running then prog(pc) match - case SET(x,y) => copy(mem = mem + (x -> y.get), pc = pc + 1) - case SUB(x,y) => copy(mem = mem + (x -> (x.get - y.get)), pc = pc + 1) - case MUL(x,y) => copy(mem = mem + (x -> (x.get * y.get)), pc = pc + 1, countMUL = countMUL + 1) - case JNZ(x,y) => copy(pc = if x.get != 0 then pc + y.get.toInt else pc + 1) + case SET(x, y) => copy(mem = mem + (x -> y.get), pc = pc + 1) + case SUB(x, y) => copy(mem = mem + (x -> (x.get - y.get)), pc = pc + 1) + case MUL(x, y) => copy(mem = mem + (x -> (x.get * y.get)), pc = pc + 1, countMUL = countMUL + 1) + case JNZ(x, y) => copy(pc = if x.get != 0 then pc + y.get.toInt else pc + 1) else this diff --git a/2018/src/main/scala/aoc2018/Day06.scala b/2018/src/main/scala/aoc2018/Day06.scala index f005c16..e828d9e 100644 --- a/2018/src/main/scala/aoc2018/Day06.scala +++ b/2018/src/main/scala/aoc2018/Day06.scala @@ -18,7 +18,7 @@ object Day06 extends AoC: val maxY: Int = coordinates.maxBy(_.y).y val positions: Vector[Pos] = - (for x <- minX to maxX ; y <- minY to maxY yield (x,y)).toVector + (for x <- minX to maxX ; y <- minY to maxY yield (x, y)).toVector type UnitDistance = (Pos, Long) diff --git a/2018/src/main/scala/aoc2018/Day10.scala b/2018/src/main/scala/aoc2018/Day10.scala index 81730ce..ef42dd0 100644 --- a/2018/src/main/scala/aoc2018/Day10.scala +++ b/2018/src/main/scala/aoc2018/Day10.scala @@ -77,7 +77,7 @@ object Day10 extends AoC: val positionsSet = positions.toSet (min.y to max.y).foldLeft(StringBuffer())((sb,y) => (min.x to max.x).foldLeft(sb)((sb,x) => - if positionsSet.contains((x,y)) then sb.append('#') else sb.append('.') + if positionsSet.contains((x, y)) then sb.append('#') else sb.append('.') ).append('\n')).toString val (sky, fastest) = diff --git a/2018/src/main/scala/aoc2018/Day11.scala b/2018/src/main/scala/aoc2018/Day11.scala index 47177b7..dc3ab9d 100644 --- a/2018/src/main/scala/aoc2018/Day11.scala +++ b/2018/src/main/scala/aoc2018/Day11.scala @@ -22,29 +22,30 @@ object Day11 extends AoC: def asIdString(size: Int): String = s"${cell.x - size + 1},${cell.y - size + 1}" - /* Note: + /** + * Note: * - * Given a value table i(x,y) a summed area table can be computed as: + * Given a value table i(x, y) a summed area table can be computed as: * - * I(x,y) = i(x,y) + I(x-1,y) + I(x,y-1) - I(x-1,y-1) + * I(x, y) = i(x, y) + I(x-1, y) + I(x, y-1) - I(x-1, y-1) * * After which the sum of an area can be computed as: * - * A(x0,y0,x1,y1) = I(x0,y0) + I(x1,y1) - I(x1,y0) - I(x0,y1) + * A(x0, y0, x1, y1) = I(x0, y0) + I(x1, y1) - I(x1, y0) - I(x0, y1) */ - /** (x,y) cells for a 1 to 300 grid */ + /** (x, y) cells for a 1 to 300 grid */ val cells: Seq[Cell] = - for y <- 1 to 300 ; x <- 1 to 300 yield (x,y) + for y <- 1 to 300 ; x <- 1 to 300 yield (x, y) - /** power level value table, i.e. the i(x,y) value table for named cells */ + /** power level value table, i.e. the i(x, y) value table for named cells */ val grid: Map[Cell,Int] = cells.map(c => c -> c.powerLevel).toMap - /** summed power level table, i.e. the summed area table I(x,y) for named grid */ + /** summed power level table, i.e. the summed area table I(x, y) for named grid */ val table: Map[Cell,Int] = cells.foldLeft(immutable.Map.empty[Cell,Int].withDefaultValue(0)): (result, cell) => - result + (cell -> (grid(cell) + result(cell + (-1,0)) + result(cell + (0,-1)) - result(cell + (-1,-1)))) + result + (cell -> (grid(cell) + result(cell + (-1, 0)) + result(cell + (0, -1)) - result(cell + (-1, -1)))) /** the area sizes, cells and total power levels for named summed power level table and given area size */ def area(size: Int): Iterator[(Int,Cell,Int)] = @@ -52,7 +53,7 @@ object Day11 extends AoC: y <- (size to 300).iterator x <- (size to 300).iterator yield - val cell = (x,y) + val cell = (x, y) val total = table(cell) + table(cell + (-size,-size)) - table(cell + (-size,0)) - table(cell + (0,-size)) (size, cell, total) diff --git a/2018/src/main/scala/aoc2018/Day13.scala b/2018/src/main/scala/aoc2018/Day13.scala index 6bb84c8..ebb9afa 100644 --- a/2018/src/main/scala/aoc2018/Day13.scala +++ b/2018/src/main/scala/aoc2018/Day13.scala @@ -68,11 +68,11 @@ object Day13 extends AoC: y <- (0 until matrix.sizeY).toVector x <- (0 until matrix.sizeX).toVector yield - matrix.charAt((x,y)) match - case Some(c) if c == '^' => Some(Cart((x,y), N)) - case Some(c) if c == '>' => Some(Cart((x,y), E)) - case Some(c) if c == 'v' => Some(Cart((x,y), S)) - case Some(c) if c == '<' => Some(Cart((x,y), W)) + matrix.charAt((x, y)) match + case Some(c) if c == '^' => Some(Cart((x, y), N)) + case Some(c) if c == '>' => Some(Cart((x, y), E)) + case Some(c) if c == 'v' => Some(Cart((x, y), S)) + case Some(c) if c == '<' => Some(Cart((x, y), W)) case _ => None val grid = diff --git a/2018/src/main/scala/aoc2018/Day15.scala b/2018/src/main/scala/aoc2018/Day15.scala index 5641075..d27b68b 100644 --- a/2018/src/main/scala/aoc2018/Day15.scala +++ b/2018/src/main/scala/aoc2018/Day15.scala @@ -182,7 +182,7 @@ object Day15 extends AoC: for (row,y) <- parseGrid(input).view.zipWithIndex.toList (tile,x) <- row.view.zipWithIndex - fighter <- parseFighter(tile, (x,y)) + fighter <- parseFighter(tile, (x, y)) yield fighter val grid: Grid = diff --git a/2018/src/main/scala/aoc2018/Day18.scala b/2018/src/main/scala/aoc2018/Day18.scala index e06ac43..ecda8b2 100644 --- a/2018/src/main/scala/aoc2018/Day18.scala +++ b/2018/src/main/scala/aoc2018/Day18.scala @@ -18,7 +18,7 @@ object Day18 extends AoC: for y <- 0 until sizeX x <- 0 until sizeX - p = (x,y) + p = (x, y) do sb.append(area(p)) sb.toString.grouped(sizeX).mkString("\n","\n","\n") @@ -44,7 +44,7 @@ object Day18 extends AoC: for y <- 0 until sizeY x <- 0 until sizeX - p = (x,y) + p = (x, y) do val c = area(p) match case '.' => if surroundedBy(p, '|') >= 3 then '|' else '.' diff --git a/2018/src/main/scala/aoc2018/Day20.scala b/2018/src/main/scala/aoc2018/Day20.scala index c21afb0..e509f0a 100644 --- a/2018/src/main/scala/aoc2018/Day20.scala +++ b/2018/src/main/scala/aoc2018/Day20.scala @@ -24,8 +24,8 @@ object Day20 extends AoC: case '^' => go( todo = todo.tail, - maxDoorsTo = Map(Location(0,0) -> 0), - visited = Set(Location(0,0)), + maxDoorsTo = Map(Location(0, 0) -> 0), + visited = Set(Location(0, 0)), branches = Vector.empty ) case '$' => diff --git a/2018/src/main/scala/aoc2018/Day22.scala b/2018/src/main/scala/aoc2018/Day22.scala index 609ad22..b4ac64b 100644 --- a/2018/src/main/scala/aoc2018/Day22.scala +++ b/2018/src/main/scala/aoc2018/Day22.scala @@ -46,7 +46,7 @@ object Day22 extends AoC: def sumOfRiskLevels(min: Region, max: Region): Int = var result = 0 - for y <- min.y to max.y ; x <- min.x to max.x do result = result + Region(x,y).regionType.riskLevel + for y <- min.y to max.y ; x <- min.x to max.x do result = result + Region(x, y).regionType.riskLevel result enum Tool derives CanEqual: diff --git a/2019/src/main/scala/aoc2019/Day10.scala b/2019/src/main/scala/aoc2019/Day10.scala index 743d331..d663283 100644 --- a/2019/src/main/scala/aoc2019/Day10.scala +++ b/2019/src/main/scala/aoc2019/Day10.scala @@ -14,7 +14,7 @@ object Day10 extends AoC: val sizeX = lines(0).length val sizeY = lines.length List - .tabulate(sizeX, sizeY)((x,y) => if lines(y)(x) == '#' then Some((x,y)) else None) + .tabulate(sizeX, sizeY)((x, y) => Option.when(lines(y)(x) == '#')((x, y))) .flatten .flatten diff --git a/2019/src/main/scala/aoc2019/Day11.scala b/2019/src/main/scala/aoc2019/Day11.scala index 5e13995..0d58b5e 100644 --- a/2019/src/main/scala/aoc2019/Day11.scala +++ b/2019/src/main/scala/aoc2019/Day11.scala @@ -13,7 +13,7 @@ object Day11 extends AoC: object Panels: val empty: Panels = Map.empty.withDefaultValue(0L) - case class Robot(cpu: CPU, pos: Pos = (0,0), dir: Dir = N, panels: Panels = Panels.empty): + case class Robot(cpu: CPU, pos: Pos = (0, 0), dir: Dir = N, panels: Panels = Panels.empty): @tailrec final def paint: Panels = cpu.withInput(panels(pos)).outputStates match @@ -32,7 +32,7 @@ object Day11 extends AoC: val program: Mem = Mem.parse(input) Robot( cpu = CPU(program), - pos = (0,0), + pos = (0, 0), dir = N, panels = Panels.empty ) @@ -47,9 +47,9 @@ object Day11 extends AoC: val sb = StringBuffer() for y <- minY to maxY do for x <- minX to maxX do - sb.append(if panels((x,y)) == 1 then '█' else '░') + sb.append(if panels((x, y)) == 1 then '█' else '░') sb.append("\n") sb.toString override lazy val answer1: Int = robot.paint.size - override lazy val answer2: String = robot.copy(panels = Map((0,0) -> 1L).withDefaultValue(0L)).paint.asString + override lazy val answer2: String = robot.copy(panels = Map((0, 0) -> 1L).withDefaultValue(0L)).paint.asString diff --git a/2019/src/main/scala/aoc2019/Day13.scala b/2019/src/main/scala/aoc2019/Day13.scala index 1fa7362..47af892 100644 --- a/2019/src/main/scala/aoc2019/Day13.scala +++ b/2019/src/main/scala/aoc2019/Day13.scala @@ -73,7 +73,7 @@ object Day13 extends AoC: for y <- 0 to maxY do for x <- 0 to maxX do - buffer += sprites(display(Location(x,y))) + buffer += sprites(display(Location(x, y))) buffer += "\n" buffer += Reset @@ -90,7 +90,7 @@ object Day13 extends AoC: else val outputs = executions.flatMap(_.outputOption) val frame = outputs.grouped(3).foldLeft(game): - case (result, LazyList(x,y,value)) => result.updated(Location(x,y), value) + case (result, LazyList(x,y,value)) => result.updated(Location(x, y), value) case (_, _) => sys.error("incomplete output") val ballX = frame.ball.get.x diff --git a/2019/src/main/scala/aoc2019/Day15.scala b/2019/src/main/scala/aoc2019/Day15.scala index 6d2f37a..f505a83 100644 --- a/2019/src/main/scala/aoc2019/Day15.scala +++ b/2019/src/main/scala/aoc2019/Day15.scala @@ -18,8 +18,8 @@ object Day15 extends AoC: (pos + delta, next, status) def dijkstra(cpu: CPU): (Map[Pos, Int], Option[(Pos, CPU)]) = - val steps = mutable.Map((0,0) -> 0) - val todo = mutable.PriorityQueue[(Pos, CPU)]((0,0) -> cpu)(using Ordering.by((point, _) => steps(point))) + val steps = mutable.Map((0, 0) -> 0) + val todo = mutable.PriorityQueue[(Pos, CPU)]((0, 0) -> cpu)(using Ordering.by((point, _) => steps(point))) var target = Option.empty[(Pos,CPU)] while todo.nonEmpty do diff --git a/2019/src/main/scala/aoc2019/Day17.scala b/2019/src/main/scala/aoc2019/Day17.scala index 7d26c85..ed46c02 100644 --- a/2019/src/main/scala/aoc2019/Day17.scala +++ b/2019/src/main/scala/aoc2019/Day17.scala @@ -59,7 +59,7 @@ object Day17 extends AoC: (tile, x) <- row.view.zipWithIndex direction <- parseRobotDir(tile) yield - ((x,y), direction) + ((x, y), direction) robots.head diff --git a/2019/src/main/scala/aoc2019/Day19.scala b/2019/src/main/scala/aoc2019/Day19.scala index 2b447d3..b8db7bb 100644 --- a/2019/src/main/scala/aoc2019/Day19.scala +++ b/2019/src/main/scala/aoc2019/Day19.scala @@ -12,12 +12,12 @@ object Day19 extends AoC: y <- ys x <- xs yield - CPU(program).withInput(x,y).outputs.last + CPU(program).withInput(x, y).outputs.last def wiggleSouthEast(program: Mem, maxX: Value, maxY: Value): Long = def isPulled(x: Value, y: Value): Boolean = - CPU(program).withInput(x,y).outputs.head == 1 + CPU(program).withInput(x, y).outputs.head == 1 @tailrec def go(x: Value, y: Value): Value = diff --git a/2019/src/main/scala/aoc2019/Day20.scala b/2019/src/main/scala/aoc2019/Day20.scala index b845d7b..4e0f125 100644 --- a/2019/src/main/scala/aoc2019/Day20.scala +++ b/2019/src/main/scala/aoc2019/Day20.scala @@ -19,7 +19,7 @@ object Day20 extends AoC: def peek(x: Int, y: Int): Char = lines.lift(y).flatMap(_.lift(x)).getOrElse(' ') val sizeX = lines.maxBy(_.length).length val sizeY = lines.length - val maze = Seq.tabulate(sizeX, sizeY)((x,y) => (x = x, y = y) -> peek(x,y)).flatten.toMap + val maze = Seq.tabulate(sizeX, sizeY)((x, y) => (x = x, y = y) -> peek(x, y)).flatten.toMap val portals = findPortals(sizeX - 3, sizeY - 3, maze) val routes = @@ -46,7 +46,7 @@ object Day20 extends AoC: y <- 2 to sizeY pattern <- patterns yield - val pos = (x,y) + val pos = (x, y) val Seq(first,second) = pattern.map(pos.translate).map(maze) if maze(pos) == '.' && first.isLetter && second.isLetter then val label = s"$first$second" diff --git a/2020/src/main/scala/aoc2020/Day11.scala b/2020/src/main/scala/aoc2020/Day11.scala index 237c670..92b3e6d 100644 --- a/2020/src/main/scala/aoc2020/Day11.scala +++ b/2020/src/main/scala/aoc2020/Day11.scala @@ -16,7 +16,7 @@ object Day11 extends AoC: x >= 0 && x < sizeX && y >= 0 && y < sizeY def seat(x: Int, y: Int): Option[Char] = - Option.when(within(x,y))(floor(y)(x)).filter(c => c == 'L' || c == '#') + Option.when(within(x, y))(floor(y)(x)).filter(c => c == 'L' || c == '#') def count1(x: Int, y: Int): Int = val N = seat(x , y - 1) @@ -50,10 +50,10 @@ object Day11 extends AoC: List(NW,N,NE,E,SE,S,SW,W).flatten.count(_ == '#') private def nextState(max: Int, count: (Int,Int) => Int)(x: Int, y: Int): Option[Char] = - seat(x,y) match - case Some('L') if count(x,y) == 0 => Some('#') - case Some('#') if count(x,y) >= max => Some('L') - case unchanged => unchanged + seat(x, y) match + case Some('L') if count(x, y) == 0 => Some('#') + case Some('#') if count(x, y) >= max => Some('L') + case unchanged => unchanged def nextState1: (Int,Int) => Option[Char] = nextState(max = 4, count = count1) @@ -62,14 +62,14 @@ object Day11 extends AoC: nextState(max = 5, count = count2) def next(step: (Int, Int) => Option[Char]): Floor = - Vector.tabulate(sizeY,sizeX)((y,x) => step(x,y).getOrElse('.')).map(_.mkString) + Vector.tabulate(sizeY, sizeX)((y, x) => step(x, y).getOrElse('.')).map(_.mkString) def totalOccupied: Int = var count = 0 for y <- 0 until sizeY x <- 0 until sizeX - if seat(x,y).contains('#') + if seat(x, y).contains('#') do count += 1 count diff --git a/2021/src/main/scala/aoc2021/Day11.scala b/2021/src/main/scala/aoc2021/Day11.scala index 1386d73..e3d4a10 100644 --- a/2021/src/main/scala/aoc2021/Day11.scala +++ b/2021/src/main/scala/aoc2021/Day11.scala @@ -5,17 +5,17 @@ import scala.annotation.tailrec object Day11 extends AoC: - type Octo = (Int,Int) + type Octo = (Int, Int) extension (octo: Octo) def x = octo._1 def y = octo._2 - val config: Map[Octo,Int] = + val config: Map[Octo, Int] = lines - .zipWithIndex.flatMap: (row,y) => - row.zipWithIndex.map: (level,x) => - (x,y) -> level.toString.toInt + .zipWithIndex.flatMap: (row, y) => + row.zipWithIndex.map: (level, x) => + (x, y) -> level.toString.toInt .toMap object Octopuses: diff --git a/2021/src/main/scala/aoc2021/Day13.scala b/2021/src/main/scala/aoc2021/Day13.scala index 28c53fb..5c186f0 100644 --- a/2021/src/main/scala/aoc2021/Day13.scala +++ b/2021/src/main/scala/aoc2021/Day13.scala @@ -44,7 +44,7 @@ object Day13 extends AoC: for y <- 0 to dots.map(_.y).max do buffer.append('\n') for x <- 0 to dots.map(_.x).max do - if dots.contains((x,y)) then + if dots.contains((x, y)) then buffer.append('#') else buffer.append('.') diff --git a/2022/src/main/scala/aoc2022/Day17.scala b/2022/src/main/scala/aoc2022/Day17.scala index 12b42e4..05dc200 100644 --- a/2022/src/main/scala/aoc2022/Day17.scala +++ b/2022/src/main/scala/aoc2022/Day17.scala @@ -12,7 +12,7 @@ object Day17 extends AoC: val moves: Vector[Move] = input.toVector - val origin: Pos = (0,0) + val origin: Pos = (0, 0) type Move = Char val L = '<' @@ -25,11 +25,11 @@ object Day17 extends AoC: sealed abstract class Rock(val relative: List[Pos]): def withOrigin(o: Pos): List[Pos] = relative.map(p => (p.x + o.x, p.y + o.y)) - case object Min extends Rock(List((0,0), (1,0), (2,0), (3,0))) - case object Plus extends Rock(List((1,0), (0,1), (1,1), (2,1), (1,2))) - case object El extends Rock(List((0,0), (1,0), (2,0), (2,1), (2,2))) - case object Stack extends Rock(List((0,0), (0,1), (0,2), (0,3))) - case object Box extends Rock(List((0,0), (1,0), (0,1), (1,1))) + case object Min extends Rock(List((0, 0), (1, 0), (2, 0), (3, 0))) + case object Plus extends Rock(List((1, 0), (0, 1), (1, 1), (2, 1), (1, 2))) + case object El extends Rock(List((0, 0), (1, 0), (2, 0), (2, 1), (2, 2))) + case object Stack extends Rock(List((0, 0), (0, 1), (0, 2), (0, 3))) + case object Box extends Rock(List((0, 0), (1, 0), (0, 1), (1, 1))) object Rock: val sequence: LazyList[Rock] = LazyList(Min, Plus, El, Stack, Box) #::: sequence diff --git a/2022/src/main/scala/aoc2022/Day24.scala b/2022/src/main/scala/aoc2022/Day24.scala index c3b1db9..dfcc632 100644 --- a/2022/src/main/scala/aoc2022/Day24.scala +++ b/2022/src/main/scala/aoc2022/Day24.scala @@ -182,7 +182,7 @@ object Day24 extends AoC: val (w1, m1) = loop(world) val w2 = w1.copy( - target = (0,0), + target = (0, 0), currentField = w1.nextField, nextField = w1.streams.futureField, streams = w1.streams.next, @@ -197,7 +197,7 @@ object Day24 extends AoC: nextField = w3.streams.futureField, streams = w3.streams.next, minutes = m3 + 1, - found = Set((0,-1)) + found = Set((0, -1)) ) val (_, m5) = loop(w4) diff --git a/2023/src/main/scala/aoc2023/Day03.scala b/2023/src/main/scala/aoc2023/Day03.scala index 1a90b41..c548194 100644 --- a/2023/src/main/scala/aoc2023/Day03.scala +++ b/2023/src/main/scala/aoc2023/Day03.scala @@ -46,7 +46,7 @@ object Day03 extends AoC: lazy val numbers: Vector[Num] = @tailrec - def compute(pos: Pos = (0,0), cur: String = "", loc: Vector[Pos] = Vector.empty, acc: Vector[Num] = Vector.empty): Vector[Num] = + def compute(pos: Pos = (0, 0), cur: String = "", loc: Vector[Pos] = Vector.empty, acc: Vector[Num] = Vector.empty): Vector[Num] = if pos.y >= chars.sizeY then acc else diff --git a/2023/src/main/scala/aoc2023/Day10.scala b/2023/src/main/scala/aoc2023/Day10.scala index 692f861..c654a7b 100644 --- a/2023/src/main/scala/aoc2023/Day10.scala +++ b/2023/src/main/scala/aoc2023/Day10.scala @@ -43,14 +43,14 @@ object Day10 extends AoC: case W if p.x > 0 => Some((x = p.x - 1, y = p.y)) case _ => None - lazy val tiles: Map[Pos,Tile] = + lazy val tiles: Map[Pos, Tile] = lines .zipWithIndex - .foldLeft(Map.empty[Pos,Tile]): - case (a,(l,y)) => + .foldLeft(Map.empty[Pos, Tile]): + case (a, (l, y)) => l.zipWithIndex.foldLeft(a): - case (a,(c,x)) => - a + ((x,y) -> Tile.fromChar(c)) + case (a, (c, x)) => + a + ((x, y) -> Tile.fromChar(c)) lazy val maxX: Int = tiles.keys.map(_.x).max lazy val maxY: Int = tiles.keys.map(_.y).max @@ -61,9 +61,9 @@ object Day10 extends AoC: case tile => tile.opposite(dir).flatMap(from.move) - def pathsFrom(from: Pos, dir: Dir): Vector[(Pos,Dir)] = + def pathsFrom(from: Pos, dir: Dir): Vector[(Pos, Dir)] = @tailrec - def loop(p: Pos, d: Dir, a: Vector[(Pos,Dir)] = Vector.empty): Vector[(Pos,Dir)] = + def loop(p: Pos, d: Dir, a: Vector[(Pos, Dir)] = Vector.empty): Vector[(Pos, Dir)] = p.move(d) match case None => a case Some(n) => @@ -77,10 +77,10 @@ object Day10 extends AoC: tiles.find((_,t) => t == Start).map((p,_) => p).getOrElse(sys.error("no start tile")) /** trial and error on direction - seems we need to go west */ - lazy val path: Vector[(Pos,Dir)] = + lazy val path: Vector[(Pos, Dir)] = pathsFrom(start, W) - def area(path: Vector[(Pos,Dir)]): Set[Pos] = + def area(path: Vector[(Pos, Dir)]): Set[Pos] = val cacheX: Vector[Pos] = path.sortBy((p,_) => p.x).map((p,_) => p) val cacheY: Vector[Pos] = path.sortBy((p,_) => p.y).map((p,_) => p) @@ -103,7 +103,7 @@ object Day10 extends AoC: case _ => Set.empty @tailrec - def loop(todo: Vector[(Pos,Dir)], prev: Dir, acc: Set[Pos]): Set[Pos] = + def loop(todo: Vector[(Pos, Dir)], prev: Dir, acc: Set[Pos]): Set[Pos] = todo match case (p, n) +: rest => tiles(p) match diff --git a/2023/src/main/scala/aoc2023/Day16.scala b/2023/src/main/scala/aoc2023/Day16.scala index e646dbc..d725eac 100644 --- a/2023/src/main/scala/aoc2023/Day16.scala +++ b/2023/src/main/scala/aoc2023/Day16.scala @@ -70,5 +70,5 @@ object Day16 extends AoC: lazy val grid: Grid = Grid(lines.map(_.toVector)) - override lazy val answer1: Long = grid.energized(start = (0,0), direction = E) + override lazy val answer1: Long = grid.energized(start = (0, 0), direction = E) override lazy val answer2: Long = grid.maxEnergized diff --git a/2025/src/main/scala/aoc2025/Day10.scala b/2025/src/main/scala/aoc2025/Day10.scala index 2e6a830..f0a7463 100644 --- a/2025/src/main/scala/aoc2025/Day10.scala +++ b/2025/src/main/scala/aoc2025/Day10.scala @@ -110,8 +110,8 @@ object Day10 extends AoC: /** add goal minimise for x0 + x1 + ... xn */ val total: ArithExpr[IntSort] = - xs.foldLeft[ArithExpr[IntSort]](ctx.mkInt(0)): (x,y) => - ctx.mkAdd(x,y) + xs.foldLeft[ArithExpr[IntSort]](ctx.mkInt(0)): (x, y) => + ctx.mkAdd(x, y) optimizer.MkMinimize(total) /** joltage(i) - b(i0) - b(i1) - b(in) = 0 */ diff --git a/nmcb/src/main/scala/nmcb/Grid.scala b/nmcb/src/main/scala/nmcb/Grid.scala index 5521c73..b7b5bca 100644 --- a/nmcb/src/main/scala/nmcb/Grid.scala +++ b/nmcb/src/main/scala/nmcb/Grid.scala @@ -85,7 +85,7 @@ case class Grid[+A](matrix: Vector[Vector[A]]): if matrix.isEmpty then matrix else - Vector.tabulate(sizeX, sizeY)((x,y) => matrix(sizeX - 1 - y)(x)) + Vector.tabulate(sizeX, sizeY)((x, y) => matrix(sizeX - 1 - y)(x)) Grid(rotateMatrixCW(matrix)) inline def toMap[B >: A]: Map[Pos, Set[(Pos, B)]] = From 9fbdf1bb36920e06c7283cff90119e72860c3af9 Mon Sep 17 00:00:00 2001 From: nmcb Date: Fri, 27 Feb 2026 00:21:20 +0100 Subject: [PATCH 3/3] fix test --- 2015/src/main/scala/aoc2015/Day18.scala | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/2015/src/main/scala/aoc2015/Day18.scala b/2015/src/main/scala/aoc2015/Day18.scala index 7bde01c..31756b9 100644 --- a/2015/src/main/scala/aoc2015/Day18.scala +++ b/2015/src/main/scala/aoc2015/Day18.scala @@ -1,7 +1,6 @@ package aoc2015 import nmcb.* -import nmcb.pos.{*, given} import scala.annotation.tailrec @@ -38,7 +37,7 @@ object Day18 extends AoC: Vector.empty[Row] /** grid encapsulates the animation of a light configuration */ - case class Grid(conf: Conf, overlay: Set[Pos] = Set.empty): + case class Grid(conf: Conf, overlay: Set[(Int,Int)] = Set.empty): val sizeX: Int = conf.map(_.size).max val sizeY: Int = conf.size val minX: Int = 0 @@ -46,13 +45,13 @@ object Day18 extends AoC: val maxX: Int = sizeX - 1 val maxY: Int = sizeY - 1 - def withOverlay(on: Pos*): Grid = + def withOverlay(on: (Int,Int)*): Grid = copy(overlay = Set.from(on)) - def fold[A](zero: A)(inc: A => A)(f: (Int, Int, A) => A): A = + def fold[A](zero: A)(inc: A => A)(f: (Int,Int,A) => A): A = (minY to maxY).foldLeft(zero): (z, y) => (minX to maxX).foldLeft(inc(z)): (z, x) => - f(x, y, z) + f(x,y,z) def count: Int = fold(0)(identity): (x, y, n) => @@ -62,16 +61,15 @@ object Day18 extends AoC: if overlay(y, x) then on else conf(y)(x) def neighbours(x: Int, y: Int): Vector[Light] = - Pos.offset8 + Vector((-1, -1), (0, -1), (1, -1), (-1, 0),(1, 0), (-1, 1), (0, 1), (1, 1)) .map((dx, dy) => (x + dx, y + dy)) .filter((px, py) => px >= minX && px <= maxX && py >= minY && py <= maxY) .map(light) - .toVector def next: Grid = val step: Conf = - fold(Conf.empty)(_ :+ Row.empty)((x, y, conf) => - conf.init :+ (conf.last :+ light(x, y).next(neighbours(x, y)))) + fold(Conf.empty)(_ :+ Row.empty)((x,y,conf) => + conf.init :+ (conf.last :+ light(x,y).next(neighbours(x,y)))) copy(conf = step) @tailrec