diff options
author | Brian Chu <brianmchu42@gmail.com> | 2022-02-21 00:11:06 -0800 |
---|---|---|
committer | Brian Chu <brianmchu42@gmail.com> | 2022-02-21 00:11:06 -0800 |
commit | 0a4fe70d367f0bf1a78602af600052f58a377c34 (patch) | |
tree | 69c2bcd2b54b48968fd52728aaf0e21ca154784c /day20.fsx | |
parent | 1e2642d8793e6a4fb6cba16cd651d5fdca3e4581 (diff) | |
download | AdventOfCode2017-0a4fe70d367f0bf1a78602af600052f58a377c34.tar.gz |
solutions to day 25 main
Diffstat (limited to 'day20.fsx')
-rw-r--r-- | day20.fsx | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/day20.fsx b/day20.fsx new file mode 100644 index 0000000..e357986 --- /dev/null +++ b/day20.fsx @@ -0,0 +1,71 @@ +open System.IO +open System.Text.RegularExpressions + +type Vector = + struct + val mutable x: int + val mutable y: int + val mutable z: int + new(X, Y, Z) = {x=X; y=Y; z=Z} + + member this.add(other: Vector) = + this.x <- this.x + other.x + this.y <- this.y + other.y + this.z <- this.z + other.z + + member this.manhattan() = + abs this.x + abs this.y + abs this.z + + override this.ToString() = + sprintf "(%d, %d, %d)" this.x this.y this.z + end + +type Projectile = + struct + val id: int + val mutable position: Vector + val mutable velocity: Vector + val acceleration: Vector + new(ID, pos, vel, acc) = {id=ID; position=pos; velocity=vel; acceleration=acc} + + member this.update() = + this.velocity.add(this.acceleration) + this.position.add(this.velocity) + this + + member this.distance() = + this.velocity.manhattan() + + override this.ToString() = + sprintf "p=%A v=%A a=%A" this.position this.velocity this.acceleration + end + +let parseInput i str = + let m = Regex("(-?\d+)").Matches(str) + let values = [for g in m -> int g.Value] + if List.length values <> 9 then printfn "%A" values; failwith "invalid input" + Projectile(i, Vector(values[0], values[1], values[2]), + Vector(values[3], values[4], values[5]), + Vector(values[6], values[7], values[8])) + +let part1() = + let mutable projectiles = File.ReadAllLines "day20.txt" |> Array.mapi parseInput + // assume that 1000 simulations is good enough + for i = 1 to 1000 do + projectiles <- Array.map (fun (x: Projectile) -> x.update()) projectiles + Array.minBy (fun (x: Projectile) -> x.distance()) projectiles |> (fun x -> x.id) |> printfn "%d" + +let part2() = + let mutable projectiles = File.ReadAllLines "day20.txt" |> Array.mapi parseInput + for i = 1 to 1000 do + projectiles <- Array.map (fun (x: Projectile) -> x.update()) projectiles + let uncollided = Array.groupBy (fun (x: Projectile) -> x.position) projectiles + |> Array.filter (fun (pos, xs) -> Array.length xs = 1) + |> Array.map snd + |> Array.fold Array.append Array.empty + projectiles <- uncollided + Array.length projectiles |> printfn "%d" + +let () = + part1() + part2() \ No newline at end of file |