Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
126
Task/Galton-box-animation/JavaScript/galton-box-animation.js
Normal file
126
Task/Galton-box-animation/JavaScript/galton-box-animation.js
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
const readline = require('readline');
|
||||
|
||||
/**
|
||||
* Galton Box animation
|
||||
* @param {number} layers The number of layers in the board
|
||||
* @param {number} balls The number of balls to pass through
|
||||
*/
|
||||
const galtonBox = (layers, balls) => {
|
||||
const speed = 100;
|
||||
const ball = 'o';
|
||||
const peg = '.';
|
||||
const result = [];
|
||||
|
||||
const sleep = ms => new Promise(resolve => {
|
||||
setTimeout(resolve,ms)
|
||||
});
|
||||
|
||||
/**
|
||||
* The board is represented as a 2D array.
|
||||
* @type {Array<Array<string>>}
|
||||
*/
|
||||
const board = [...Array(layers)]
|
||||
.map((e, i) => {
|
||||
const sides = Array(layers - i).fill(' ');
|
||||
const a = Array(i + 1).fill(peg).join(' ').split('');
|
||||
return [...sides, ...a, ...sides];
|
||||
});
|
||||
|
||||
/**
|
||||
* @return {Array<string>}
|
||||
*/
|
||||
const emptyRow = () => Array(board[0].length).fill(' ');
|
||||
|
||||
/**
|
||||
* @param {number} i
|
||||
* @returns {number}
|
||||
*/
|
||||
const bounce = i => Math.round(Math.random()) ? i - 1 : i + 1;
|
||||
|
||||
/**
|
||||
* Prints the current state of the board and the collector
|
||||
*/
|
||||
const show = () => {
|
||||
readline.cursorTo(process.stdout, 0, 0);
|
||||
readline.clearScreenDown(process.stdout);
|
||||
board.forEach(e => console.log(e.join('')));
|
||||
result.reverse();
|
||||
result.forEach(e => console.log(e.join('')));
|
||||
result.reverse();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Collect the result.
|
||||
* @param {number} idx
|
||||
*/
|
||||
const appendToResult = idx => {
|
||||
const row = result.find(e => e[idx] === ' ');
|
||||
if (row) {
|
||||
row[idx] = ball;
|
||||
} else {
|
||||
const newRow = emptyRow();
|
||||
newRow[idx] = ball;
|
||||
result.push(newRow);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Move the balls through the board
|
||||
* @returns {boolean} True if the there are balls in the board.
|
||||
*/
|
||||
const iter = () => {
|
||||
let hasNext = false;
|
||||
[...Array(bordSize)].forEach((e, i) => {
|
||||
const rowIdx = (bordSize - 1) - i;
|
||||
const idx = board[rowIdx].indexOf(ball);
|
||||
if (idx > -1) {
|
||||
board[rowIdx][idx] = ' ';
|
||||
const nextRowIdx = rowIdx + 1;
|
||||
if (nextRowIdx < bordSize) {
|
||||
hasNext = true;
|
||||
const nextRow = board[nextRowIdx];
|
||||
nextRow[bounce(idx)] = ball;
|
||||
} else {
|
||||
appendToResult(idx);
|
||||
}
|
||||
}
|
||||
});
|
||||
return hasNext;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a ball to the board.
|
||||
* @returns {number} The number of balls left to add.
|
||||
*/
|
||||
const addBall = () => {
|
||||
board[0][apex] = ball;
|
||||
balls = balls - 1;
|
||||
return balls;
|
||||
};
|
||||
|
||||
board.unshift(emptyRow());
|
||||
result.unshift(emptyRow());
|
||||
|
||||
const bordSize = board.length;
|
||||
const apex = board[1].indexOf(peg);
|
||||
|
||||
/**
|
||||
* Run the animation
|
||||
*/
|
||||
(async () => {
|
||||
while (addBall()) {
|
||||
await sleep(speed).then(show);
|
||||
iter();
|
||||
}
|
||||
await sleep(speed).then(show);
|
||||
while (iter()) {
|
||||
await sleep(speed).then(show);
|
||||
}
|
||||
await sleep(speed).then(show);
|
||||
})();
|
||||
|
||||
|
||||
};
|
||||
|
||||
galtonBox(12, 50);
|
||||
Loading…
Add table
Add a link
Reference in a new issue