Day 24: Odds

Megathread guidelines

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

FAQ

  • Treeniks@lemmy.ml
    link
    fedilink
    English
    arrow-up
    2
    ·
    10 months ago

    Rust

    github: https://github.com/Treeniks/advent-of-code/blob/master/2023/day24/rust/src/main.rs

    codeberg: https://codeberg.org/Treeniks/advent-of-code/src/branch/master/2023/day24/rust/src/main.rs

    gitlab: https://gitlab.com/Treeniks/advent-of-code/-/blob/master/2023/day24/rust/src/main.rs

    Had to look on reddit for how to solve part 2. Wasn’t happy with the idea of using something like Z3, so I ended up brute force guessing the velocity, solving for the position and time and seeing if those are correct.

    Lots of unintelligible calculations for solving the equation systems in the code that I just prepared on paper and transferred over.

  • cvttsd2si@programming.dev
    link
    fedilink
    arrow-up
    2
    ·
    edit-2
    10 months ago

    Scala3, Sympy

    case class Particle(x: Long, y: Long, z: Long, dx: Long, dy: Long, dz: Long)
    
    def parseParticle(a: String): Option[Particle] = a match
        case s"$x, $y, $z @ $dx, $dy, $dz" => Some(Particle(x.toLong, y.toLong, z.toLong, dx.trim.toLong, dy.trim.toLong, dz.trim.toLong))
        case _ => None
    
    def intersect(min: Double, max: Double)(p: Particle, q: Particle): Boolean =
        val n = p.dx * q.y - p.y * p.dx - q.x * p.dy + p.x * p.dy
        val d = p.dy * q.dx - p.dx * q.dy
    
        if(d == 0) then false else 
            val k = n.toDouble/d
            val k2 = (q.y + k * q.dy - p.y)/p.dy
            val ix = q.x + k * q.dx
            val iy = q.y + k * q.dy
            k2 >= 0 && k >= 0 && min <= ix && ix <= max && min <= iy && iy <= max
    
    def task1(a: List[String]): Long = 
        val particles = a.flatMap(parseParticle)
        particles.combinations(2).count(l => intersect(2e14, 4e14)(l(0), l(1)))
    
    import re as re2
    from sympy import *
    
    p, v, times, eqs = symbols('x y z'), symbols('dx dy dz'), [], []
    
    def parse_eq(i: int, s: str):
        parts = [int(p) for p in re2.split(r'[,\s@]+', s) if p.strip() != '']
        time = Symbol(f't{i}')
        times.append(time)
        for rp, rv, hp, hv in zip(p, v, parts[:3], parts[3:]):
            eqs.append(Eq(rp + time * rv, hp + time * hv))
    
    # need 3 equations for result, everything after that just slows things down
    neq = 3
    with open('task1.txt', 'r') as fobj:
        for i, s in zip(range(neq), fobj.readlines()):
            parse_eq(i, s)
    
    for sol in solve(eqs, list(p) + list(v) + times):
        x, y, z, *_ = sol
        print(x + y + z)