# The Computer LanguageBenchmarks Game

## n-body TypeScript program

### source code

```/* The Computer Language Benchmarks Game
http://benchmarksgame.alioth.debian.org/
contributed by Isaac Gouy

Transliterated from Smalltalk program
*/

/// <reference path="./Include/node/index.d.ts" />

class PlanetarySystem {
private bodies: Body[]

constructor(){
this.bodies = [
Body.Sun(),
Body.Jupiter(),
Body.Saturn(),
Body.Uranus(),
Body.Neptune()
]

// How to use reduce?
let total : [number,number,number] = [0.0,0.0,0.0]
this.bodies.forEach(each => {
})
this.bodies[0].offsetMomentum(total)
}

after(dt: number) {
const size = this.bodies.length
for (let i=0; i<size; i++) {
for (let j=i+1; j < size; j++) {
this.bodies[i].setVelocitiesAfter(dt,this.bodies[j])
}
}
for (let i=0; i<size; i++) {
this.bodies[i].setPositionAfter(dt)
}
}

energy(): number {
let e = 0.0
const size = this.bodies.length
for (let i=0; i<size; i++) {
e += this.bodies[i].kineticEnergy()
for (let j=i+1; j < size; j++) {
e -= this.bodies[i].potentialEnergyWith(this.bodies[j])
}
}
return e
}
}

class Body {
private static PI = 3.141592653589793
private static SOLAR_MASS = 4 * Body.PI * Body.PI
private static DAYS_PER_YEAR = 365.24

constructor(
private x: number,
private y: number,
private z: number,
private vx: number,
private vy: number,
private vz: number,
private m: number
) { }

mass(): number {
return this.m
}

static Jupiter(){
return new Body(
4.84143144246472090e+00,
-1.16032004402742839e+00,
-1.03622044471123109e-01,
1.66007664274403694e-03 * Body.DAYS_PER_YEAR,
7.69901118419740425e-03 * Body.DAYS_PER_YEAR,
-6.90460016972063023e-05 * Body.DAYS_PER_YEAR,
9.54791938424326609e-04 * Body.SOLAR_MASS
)
}

static Saturn(){
return new Body(
8.34336671824457987e+00,
4.12479856412430479e+00,
-4.03523417114321381e-01,
-2.76742510726862411e-03 * Body.DAYS_PER_YEAR,
4.99852801234917238e-03 * Body.DAYS_PER_YEAR,
2.30417297573763929e-05 * Body.DAYS_PER_YEAR,
2.85885980666130812e-04 * Body.SOLAR_MASS
)
}

static Uranus(){
return new Body(
1.28943695621391310e+01,
-1.51111514016986312e+01,
-2.23307578892655734e-01,
2.96460137564761618e-03 * Body.DAYS_PER_YEAR,
2.37847173959480950e-03 * Body.DAYS_PER_YEAR,
-2.96589568540237556e-05 * Body.DAYS_PER_YEAR,
4.36624404335156298e-05 * Body.SOLAR_MASS
)
}

static Neptune(){
return new Body(
1.53796971148509165e+01,
-2.59193146099879641e+01,
1.79258772950371181e-01,
2.68067772490389322e-03 * Body.DAYS_PER_YEAR,
1.62824170038242295e-03 * Body.DAYS_PER_YEAR,
-9.51592254519715870e-05 * Body.DAYS_PER_YEAR,
5.15138902046611451e-05 * Body.SOLAR_MASS
)
}

static Sun(){
return new Body(
0,
0,
0,
0,
0,
0,
Body.SOLAR_MASS
)
}

return [
x + this.vx * this.m,
y + this.vy * this.m,
z + this.vz * this.m
]
}

private decreaseVelocity(dx, dy, dz, m: number) {
this.vx -= dx * m
this.vy -= dy * m
this.vz -= dz * m
}

private increaseVelocity(dx, dy, dz, m : number) {
this.vx += dx * m
this.vy += dy * m
this.vz += dz * m
}

kineticEnergy(): number {
return 0.5 * this.m * (this.vx**2 + this.vy**2 + this.vz**2)
}

offsetMomentum([px,py,pz]: [number,number,number]) {
this.vx = -px / Body.SOLAR_MASS
this.vy = -py / Body.SOLAR_MASS
this.vz = -pz / Body.SOLAR_MASS
}

potentialEnergyWith(b: Body) {
const [dx,dy,dz] = b.vectorTo(this.x,this.y,this.z)
const distance = Math.sqrt(dx**2 + dy**2 + dz**2)
return this.m * b.mass() / distance
}

setPositionAfter(dt: number) {
this.x += dt * this.vx
this.y += dt * this.vy
this.z += dt * this.vz
}

setVelocitiesAfter(dt: number, b: Body) {
const [dx,dy,dz] = b.vectorTo(this.x,this.y,this.z)
const distance = Math.sqrt(dx**2 + dy**2 + dz**2)
const mag = dt / distance**3
this.decreaseVelocity(dx,dy,dz,b.mass()*mag)
b.increaseVelocity(dx,dy,dz,this.m*mag)
}

private vectorTo(x,y,z : number) {
return [x-this.x, y-this.y, z-this.z]
}
}

const n = +process.argv[2]
const system = new PlanetarySystem()
console.log(system.energy().toFixed(9))
for (let i=0; i<n; i++){ system.after(0.01) }
console.log(system.energy().toFixed(9))

```

### notes, command-line, and program output

```NOTES:
Version 2.6.2
node.js v9.4.0

Wed, 10 Jan 2018 21:42:29 GMT

MAKE:
mv nbody.typescript nbody.ts
/opt/src/node-v9.4.0-linux-x64/bin/tsc --alwaysStrict -t ESNEXT  nbody.ts

2.89s to complete and log all make actions

COMMAND LINE:
/opt/src/node-v9.4.0-linux-x64/bin/node --use_strict nbody.js 50000000

PROGRAM OUTPUT:
-0.169075164
-0.169059907
```