2 # The Computer Language Benchmark Shootout
3 # http://shootout.alioth.debian.org
5 # original code by Martin DeMello
6 # modified by Jabari Zakiya 3/20/05
7 # modified by Glenn Parker 3/28/05 (format results)
12 DAYS_PER_YEAR
= 365.24
14 Vector3D
= Struct
.new("Vector3D", :x, :y, :z)
19 Vector3D
.new(*self.map
{|i
| i
* val
})
23 Vector3D
.new(*self.map
{|i
| i
/ val
})
26 #in-place add with scale
27 # a.adds(b, s) -> a += b*s
29 def adds(other
, scale
)
30 self[0] += other
[0]*scale
; self[1] += other
[1]*scale
31 self[2] += other
[2]*scale
34 def subs(other
, scale
)
35 self[0] -= other
[0]*scale
; self[1] -= other
[1]*scale
36 self[2] -= other
[2]*scale
40 x
=self[0]; y
=self[1]; z
=self[2]
46 x
=self[0]-other
[0]; y
=self[1]-other
[1]; z
=self[2]-other
[2]
52 attr_accessor
:pos, :v, :mass
54 def initialize(x
, y
, z
, vx
, vy
, vz
, mass
)
55 @pos = Vector3D
.new(x
, y
, z
)
56 @v = Vector3D
.new(vx
, vy
, vz
) * DAYS_PER_YEAR
57 @mass = mass
* SOLAR_MASS
61 self.pos
.dmag(other
.pos
)
66 4.84143144246472090e+00,
67 -1.16032004402742839e+00,
68 -1.03622044471123109e-01,
69 1.66007664274403694e-03,
70 7.69901118419740425e-03,
71 -6.90460016972063023e-05,
72 9.54791938424326609e-04)
75 8.34336671824457987e+00,
76 4.12479856412430479e+00,
77 -4.03523417114321381e-01,
78 -2.76742510726862411e-03,
79 4.99852801234917238e-03,
80 2.30417297573763929e-05,
81 2.85885980666130812e-04)
84 1.28943695621391310e+01,
85 -1.51111514016986312e+01,
86 -2.23307578892655734e-01,
87 2.96460137564761618e-03,
88 2.37847173959480950e-03,
89 -2.96589568540237556e-05,
90 4.36624404335156298e-05)
93 1.53796971148509165e+01,
94 -2.59193146099879641e+01,
95 1.79258772950371181e-01,
96 2.68067772490389322e-03,
97 1.62824170038242295e-03,
98 -9.51592254519715870e-05,
99 5.15138902046611451e-05)
101 sun
= Planet
.new(0, 0, 0, 0, 0, 0, 1)
107 ((i
+1)...length
).each
{|j
|
114 bodies
= [sun
, jupiter
, saturn
, uranus
, neptune
]
126 b1
.v
.adds(b2
.pos
, m2
)
127 b1
.v
.subs(b1
.pos
, m2
)
128 b2
.v
.adds(b1
.pos
, m1
)
129 b2
.v
.subs(b2
.pos
, m1
)
132 each
{|b
| b
.pos
.adds(b
.v
, dt
)}
137 each
{|b
| e
+= 0.5 * b
.mass
* (b
.v
.magnitude
** 2) }
138 each_pair
{|b1
, b2
| e
-= (b1
.mass
* b2
.mass
) / b1
.distance(b2
) }
143 p
= Vector3D
.new(0,0,0)
145 each
{|b
| p
.adds(b
.v
, b
.mass
) }
146 sun
.v
.subs(p
, 1.0/sun
.mass
)
150 bodies
.offset_momentum
151 puts
"%.9f" % bodies
.energy
152 Integer(ARGV[0]).times
{ bodies
.advance(0.01) }
153 puts
"%.9f" % bodies
.energy