From 38927a7889957b600fdadd3b3ee79b6413a6e74d Mon Sep 17 00:00:00 2001 From: Christian Date: Sat, 14 Dec 2024 21:18:16 +0100 Subject: [PATCH] Day 14 Mathy solution --- aoc/src/dev/ctsk/aoc/Utils.scala | 5 ++++ aoc/src/dev/ctsk/aoc/days/Day14.scala | 34 ++++++++++----------------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/aoc/src/dev/ctsk/aoc/Utils.scala b/aoc/src/dev/ctsk/aoc/Utils.scala index a56503f..bf0ff68 100644 --- a/aoc/src/dev/ctsk/aoc/Utils.scala +++ b/aoc/src/dev/ctsk/aoc/Utils.scala @@ -6,3 +6,8 @@ def gcd(a: Int, b: Int): Int = extension [A](xs: Seq[A]) def pairs: Iterator[(A, A)] = xs.combinations(2).map(xs => (xs(0), xs(1))) + +def eea(a: Int, b: Int): (Int, Int, Int) = + if b == 0 then return (a, 1, 0) + val (d, x, y) = eea(b, a % b) + (d, y, x - y * (a / b)) diff --git a/aoc/src/dev/ctsk/aoc/days/Day14.scala b/aoc/src/dev/ctsk/aoc/days/Day14.scala index 2ed03fd..445624d 100644 --- a/aoc/src/dev/ctsk/aoc/days/Day14.scala +++ b/aoc/src/dev/ctsk/aoc/days/Day14.scala @@ -1,9 +1,10 @@ package dev.ctsk.aoc.days -import dev.ctsk.aoc.* +import dev.ctsk.aoc._ import os.ReadablePath -import scala.util.boundary -import scala.util.boundary.break + +def mu(arr: Seq[Int]) = arr.sum * 1.0 / arr.length +def va(arr: Seq[Int]) = { val m = mu(arr); arr.map(v => (v - m) * (v - m)).sum } object Day14 extends Solver(14): private val Y = 101 @@ -22,27 +23,18 @@ object Day14 extends Solver(14): ul * ur * dl * dr def part2(robots: Array[(Point, Point)]): Int = - val hist = Array.fill(X, Y)(0) - def isTree(t: Int): Boolean = - boundary: - for i <- robots.indices - do - val dst = go(robots(i), t) - if hist(dst.x)(dst.y) == t then break(false) - hist(dst.x)(dst.y) = t - break(true) - - (1 to X * Y).find(isTree).get + val xo = (0 to 103).minBy(t => va(robots.map(go(_, t).x).take(50))) + val yo = (0 to 103).minBy(t => va(robots.map(go(_, t).y).take(50))) + val (_, iX, iY) = eea(X, Y) + (xo * iY * Y + yo * iX * X) % (X * Y) override def run(input: ReadablePath): (Timings, Solution) = - val (pre_time, robots) = timed { - os.read - .lines(input) - .map(longs) - .map { case Vector(y, x, dy, dx) => (Point.of(x, y), Point.of(dx, dy)) } - .toArray - } + def parse(line: String): (Point, Point) = + longs(line) match { + case Vector(y, x, dy, dx) => (Point.of(x, y), Point.of(dx, dy)) + } + val (pre_time, robots) = timed { os.read.lines(input).map(parse).toArray } val (p1_time, p1) = timed { part1(robots) } val (p2_time, p2) = timed { part2(robots) }