Skip to content

Instantly share code, notes, and snippets.

@rkaw92
Last active March 14, 2018 19:57
Show Gist options
  • Save rkaw92/00ee2cfc070dcfee199cd99821247e4f to your computer and use it in GitHub Desktop.
Save rkaw92/00ee2cfc070dcfee199cd99821247e4f to your computer and use it in GitHub Desktop.
'use strict';
const Big = require('big.js');
const EventEmitter = require('events');
/**
* An EventEmitter that emits subsequent approximations of number Pi.
* @extends external:EventEmitter
*/
class PiEmitter extends EventEmitter {
constructor() {
super();
this._iteration = new Big(0);
this._inside = new Big(0);
this._samplesPerEvent = new Big(1000000);
this._piInterval = null;
}
start() {
const self = this;
// Execute the computation task periodically to avoid starving the CPU:
self._piInterval = setInterval(function() {
const start = self._iteration;
const limit = start.plus(self._samplesPerEvent);
// Create a local counter to speed up computation (big.js is pretty slow):
let inside = 0;
// Check how many random points are inside the 1x1 circle:
for (let i = start; i.lt(limit); i = i.plus(1)) {
let x = Math.random() * 2 - 1;
let y = Math.random() * 2 - 1;
if ((x*x + y*y) < 1) {
inside = inside + 1;
}
}
self._iteration = limit;
self._inside = self._inside.plus(inside);
const bestPiValue = self._inside.times(4).div(self._iteration);
// Emit the result:
self.emit('pi', bestPiValue);
}, 1);
}
}
const myPi = new PiEmitter();
myPi.on('pi', function(piValue) {
console.log('best Pi value: %s', piValue);
});
myPi.start();
'use strict';
const Big = require('big.js');
const Observable = require('rxjs/Rx').Observable;
/**
* An Observable stream of Pi approximations.
* @extends external:EventEmitter
*/
class PiRx {
constructor() {
this._iteration = new Big(0);
this._inside = new Big(0);
this._samplesPerEvent = new Big(1000000);
this._piInterval = null;
}
getPiStream() {
const self = this;
// Execute the computation task periodically to avoid starving the CPU:
return Observable.create(function(observable) {
self._piInterval = setInterval(function() {
const start = self._iteration;
const limit = start.plus(self._samplesPerEvent);
// Create a local counter to speed up computation (big.js is pretty slow):
let inside = 0;
// Check how many random points are inside the 1x1 circle:
for (let i = start; i.lt(limit); i = i.plus(1)) {
let x = Math.random() * 2 - 1;
let y = Math.random() * 2 - 1;
if ((x*x + y*y) < 1) {
inside = inside + 1;
}
}
self._iteration = limit;
self._inside = self._inside.plus(inside);
const bestPiValue = self._inside.times(4).div(self._iteration);
// Emit the result:
observable.next(bestPiValue);
}, 1);
});
}
}
const myPi = new PiRx();
const myPiStream = myPi.getPiStream();
myPiStream.subscribe(function(piValue) {
console.log('best Pi value: %s', piValue);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment