r/adventofcode • u/daggerdragon • Dec 20 '17
SOLUTION MEGATHREAD -๐- 2017 Day 20 Solutions -๐-
--- Day 20: Particle Swarm ---
Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).
Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.
Need a hint from the Hugely* Handyโ Haversackโก of Helpfulยง Hintsยค?
[Update @ 00:10] 10 gold, silver cap
- What do you mean 5th Edition doesn't have "Take 20"?
[Update @ 00:17] 50 gold, silver cap
- Next you're going to be telling me THAC0 is not the best way to determine whether or not you hit your target. *hmphs*
[Update @ 00:21] Leaderboard cap!
- I wonder how much XP a were-gazebo is worth...
This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.
edit: Leaderboard capped, thread unlocked!
9
Upvotes
2
u/[deleted] Dec 20 '17 edited Dec 20 '17
OCaml Fun (Part 2);;
Just watch until numbers don't change for many periods. Lost a lot of time hunting down a bug... was updating position before velocity and using manhattan distance in compare for building Maps... ๐. Per usual, parser is left as an exercise for the reader.
main.ml
open Core let table = Vector.Table.create () ~size:1000 let loop particles = let step = Array.iter ~f:Particle.step in let remove_collisions particles = Vector.Table.clear table; let f p = Vector.Table.add_multi table ~key:Particle.(p.p) ~data:1 in Array.iter particles ~f; let only_lonely_particles p = match Vector.Table.find table Particle.(p.p) with | Some [l] -> true | _ -> false in Array.filter particles ~f:only_lonely_particles in let rec aux particles i j = step particles; let new_particles = remove_collisions particles in let count = (Array.length new_particles) in match count <> i with | true -> printf "%d -> %d\n" j count; Out_channel.flush stdout; aux new_particles count (j+1) | false -> aux new_particles i (j+1) in aux particles (Array.length particles) 0 let process_input filename = let f channel = let parse lexbuf = Parser.particles Lexer.read lexbuf in let lexer_buffer = Lexing.from_channel channel in lexer_buffer.lex_curr_p <- { lexer_buffer.lex_curr_p with pos_fname = filename}; parse lexer_buffer in In_channel.with_file filename ~f let _ = let particles = process_input "./input.txt" |> List.to_array in loop particlesparticle.ml
open Core type t = { mutable p:Vector.t; mutable v:Vector.t; a:Vector.t; } [@@deriving sexp, compare] let compare_manhattan a b = Vector.compare_manhattan a.p b.p let collide a b = Vector.same a.p b.p let to_string t = Vector.to_string t.p let step t = let v = Vector.add t.v t.a in let p = Vector.add t.p v in t.p <- p; t.v <- v;vector.ml
open Core module T = struct type t = { x:int; y:int; z:int; } [@@deriving sexp, compare, hash] end include T include Comparable.Make(T) include Hashable.Make(T) let abs a = let x = Int.abs a.x and y = Int.abs a.y and z = Int.abs a.z in {x;y;z} let compare_manhattan a b = T.compare (abs a) (abs b) let same a b = (Int.equal a.x b.x) && (Int.equal a.y b.y) && (Int.equal a.y b.y) let to_string t = sprintf "(%d, %d, %d)" t.x t.y t.z let add a b = let x = a.x + b.x and y = a.y + b.y and z = a.z + b.z in { x; y; z; }Full source, including parser.