diff options
author | Nat Lasseter <Nat Lasseter nathan@bytemark.co.uk> | 2017-12-21 00:04:01 +0000 |
---|---|---|
committer | Nat Lasseter <Nat Lasseter nathan@bytemark.co.uk> | 2017-12-21 00:04:01 +0000 |
commit | f2797d77b2abdc48bb90c716563a69d3790891f0 (patch) | |
tree | 5c2af0788436340cb5f1d5f92abb74fd6b3137f2 /day20/part2 | |
parent | b8e0dc361e2ddf8c272629a8b4bb6d52a82baad7 (diff) |
Day 20
Diffstat (limited to 'day20/part2')
-rwxr-xr-x | day20/part2 | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/day20/part2 b/day20/part2 new file mode 100755 index 0000000..1d474e1 --- /dev/null +++ b/day20/part2 @@ -0,0 +1,102 @@ +#!/usr/bin/env ruby + +require 'scanf' + +class Array + def find_all_indices(elt) + return self.each_index.select { |i| self[i] == elt } + end +end + +class Vector + attr_accessor :x, :y, :z + + def initialize(array) + @x = array[0] || 0 + @y = array[1] || 0 + @z = array[2] || 0 + end + + def add!(vector) + @x += vector.x + @y += vector.y + @z += vector.z + end + + def to_s + return "<#{@x},#{@y},#{@z}>" + end +end + +class Particle + attr_accessor :pos, :vel, :acc + + def initialize(p, v, a) + @pos = Vector.new(p) + @vel = Vector.new(v) + @acc = Vector.new(a) + @destroyed = false + end + + def destroy! + @destroyed = true + end + + def destroyed? + return @destroyed + end + + def collides?(other) + return @pos.x == other.pos.x && + @pos.y == other.pos.y && + @pos.z == other.pos.z + end + + def update! + @vel.add!(@acc) + @pos.add!(@vel) + end + + def to_s + return "p=#{@pos}, v=#{@vel}, a=#{@acc}" + end +end + +input = $stdin.readlines.map(&:chomp) + +particles = input.map do |line| + px, py, pz, vx, vy, vz, ax, ay, az = + line.scanf("p=<%d,%d,%d>, v=<%d,%d,%d>, a=<%d,%d,%d>") + Particle.new([px, py, pz], [vx, vy, vz], [ax, ay, az]) +end + +times = 0 + +THE_LONG_RUN = 1000 + +loop do + collision = false + + (0...particles.length).each do |i| + (i+1...particles.length).each do |j| + if particles[i].collides?(particles[j]) then + collision = true + particles[i].destroy! + particles[j].destroy! + end + end + end + + if !collision then + times += 1 + else + times = 0 + end + + break if times == THE_LONG_RUN + + particles.each(&:update!) + particles = particles.reject(&:destroyed?) +end + +p particles.length |