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

  • @cvttsd2si
    link
    2
    edit-2
    6 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)