1 # The Computer Language Shootout
\r
2 # http://shootout.alioth.debian.org
\r
4 # Optimized for Ruby by Jesse Millikan
\r
5 # From version ported by Michael Neumann from the C gcc version,
\r
6 # which was written by Christoph Bauer.
\r
8 SOLAR_MASS = 4 * Math::PI**2
\r
9 DAYS_PER_YEAR = 365.24
\r
15 attr_accessor :x, :y, :z, :vx, :vy, :vz, :mass
\r
17 def initialize(x, y, z, vx, vy, vz, mass)
\r
18 @x, @y, @z = x, y, z
\r
19 @vx, @vy, @vz = vx * DAYS_PER_YEAR, vy * DAYS_PER_YEAR, vz * DAYS_PER_YEAR
\r
20 @mass = mass * SOLAR_MASS
\r
23 def move_from_i(bodies, nbodies, dt, i)
\r
30 distance = Math.sqrt(dx * dx + dy * dy + dz * dz)
\r
31 mag = dt / (distance * distance * distance)
\r
32 b_mass_mag, b2_mass_mag = @mass * mag, b2.mass * mag
\r
34 @vx -= dx * b2_mass_mag
\r
35 @vy -= dy * b2_mass_mag
\r
36 @vz -= dz * b2_mass_mag
\r
37 b2.vx += dx * b_mass_mag
\r
38 b2.vy += dy * b_mass_mag
\r
39 b2.vz += dz * b_mass_mag
\r
51 nbodies = bodies.size
\r
53 for i in 0 ... nbodies
\r
55 e += 0.5 * b.mass * (b.vx * b.vx + b.vy * b.vy + b.vz * b.vz)
\r
56 for j in (i + 1) ... nbodies
\r
61 distance = Math.sqrt(dx * dx + dy * dy + dz * dz)
\r
62 e -= (b.mass * b2.mass) / distance
\r
68 def offset_momentum(bodies)
\r
69 px, py, pz = 0.0, 0.0, 0.0
\r
79 b.vx = - px / SOLAR_MASS
\r
80 b.vy = - py / SOLAR_MASS
\r
81 b.vz = - pz / SOLAR_MASS
\r
86 Planet.new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0),
\r
90 4.84143144246472090e+00,
\r
91 -1.16032004402742839e+00,
\r
92 -1.03622044471123109e-01,
\r
93 1.66007664274403694e-03,
\r
94 7.69901118419740425e-03,
\r
95 -6.90460016972063023e-05,
\r
96 9.54791938424326609e-04),
\r
100 8.34336671824457987e+00,
\r
101 4.12479856412430479e+00,
\r
102 -4.03523417114321381e-01,
\r
103 -2.76742510726862411e-03,
\r
104 4.99852801234917238e-03,
\r
105 2.30417297573763929e-05,
\r
106 2.85885980666130812e-04),
\r
110 1.28943695621391310e+01,
\r
111 -1.51111514016986312e+01,
\r
112 -2.23307578892655734e-01,
\r
113 2.96460137564761618e-03,
\r
114 2.37847173959480950e-03,
\r
115 -2.96589568540237556e-05,
\r
116 4.36624404335156298e-05),
\r
120 1.53796971148509165e+01,
\r
121 -2.59193146099879641e+01,
\r
122 1.79258772950371181e-01,
\r
123 2.68067772490389322e-03,
\r
124 1.62824170038242295e-03,
\r
125 -9.51592254519715870e-05,
\r
126 5.15138902046611451e-05)
\r
129 init = 200_000 # ARGV[0]
\r
132 offset_momentum(BODIES)
\r
134 puts "%.9f" % energy(BODIES)
\r
136 nbodies = BODIES.size
\r
143 b.move_from_i(BODIES, nbodies, dt, i + 1)
\r
148 puts "%.9f" % energy(BODIES)
\r