comparison 2017/day20/app.d @ 33:bc652fa0a645

Move all solutions to per-day subdirs
author Jordi Gutiérrez Hermoso <jordigh@octave.org>
date Tue, 09 Jan 2018 21:50:37 -0500
parents 2017/day20.d@8db386034a68
children
comparison
equal deleted inserted replaced
32:763c88851b91 33:bc652fa0a645
1 import std.stdio;
2 import std.string: split;
3 import std.conv: to;
4 import std.algorithm: map, filter, minElement, sum, any;
5 import std.array: array;
6 import std.math: sqrt;
7 import std.range: enumerate;
8
9 struct particle {
10 double[3] pos;
11 double[3] vel;
12 double[3] acc;
13 }
14
15 auto parseLine(string line) {
16 auto p = line.split(", ").map!(
17 x => x[3..$-1].split(",").map!(to!double).array.to!(double[3])
18 );
19 particle res = {p[0], p[1], p[2]};
20 return res;
21 }
22
23 auto norm(double[3] v) {
24 return v[].map!(x => x*x).sum.sqrt;
25 }
26
27 auto unit(particle p) {
28 auto
29 pos = p.pos,
30 vel = p.vel,
31 acc = p.acc;
32 pos[] /= pos.norm;
33 vel[] /= vel.norm;
34 acc[] /= acc.norm;
35 particle u = {pos, vel, acc};
36 return u;
37 }
38
39 auto slowestParticle(particle[] particles) {
40 // This should use minIndex, from later Phobos
41 auto norms = particles.map!(p => p.acc.norm);
42 auto min = norms.minElement;
43 return norms.enumerate.filter!(x => x[1] == min).front[0];
44 }
45
46 void evolve(ref particle p) {
47 p.vel[] += p.acc[];
48 p.pos[] += p.vel[];
49 }
50
51 void collide(ref particle[] particles) {
52 int[double[3]] counter;
53 foreach(p; particles) {
54 counter[p.pos] = counter.get(p.pos, 0) + 1;
55 }
56 particles = particles.filter!(p => counter[p.pos] == 1).array;
57 }
58
59 bool canCollide(particle[] particles) {
60 return particles.map!(unit).any!(
61 function(particle p) {
62 // Check if the position, velocity, and acceleration fail to be
63 // mostly collinear
64 double[3] diff1 = p.pos, diff2 = p.vel;
65 diff1[] -= p.vel[];
66 diff2[] -= p.acc[];
67 return norm(diff1) > 0.001 || norm(diff2) > 0.001;
68 }
69 );
70 }
71
72 auto evolve(particle[] particles) {
73 while(particles.canCollide) {
74 collide(particles);
75 foreach(ref particle; particles) {
76 evolve(particle);
77 }
78 }
79 return particles.length;
80 }
81
82 void main(string[] args) {
83 auto particles = File(args[1]).byLineCopy.map!(parseLine).array;
84 writeln(particles.slowestParticle);
85 writeln(particles.evolve);
86 }