Merge Sort Visualizer - javascript

My merge sort visualizer draws the array but does not show them being sorted and doesnt seem to be correctly merging them and displaying each step. instead of returning a sorted array, I see a quick flash of the array then a blank screen.
values is the array and states is supposed to change in value from -1 to 1 based on whether an index is currently in progress, waiting, or completed but I'm trying to get the sort and merge working first.
//array of values to be sorted
let values = [];
//width of values
let w = 2;
//hold the state of the array
let states = [];
function setup() {
createCanvas(windowWidth, windowHeight);
values = new Array(floor(random(250, width / w)));
for (i = 0; i < values.length; i++) {
values[i] = random(height);
states[i] = -1;
}
}
async function mergeSort(arr) {
if (arr.length <= 1) {
return arr;
}
//get midpoint
let mid = Math.round(arr.length / 2);
states[mid] = -1;
//split the array
temp1 = arr.slice(0, mid);
temp2 = arr.slice(mid, arr.length);
//merge the array
await Promise.all([
merge(mergeSort(temp1), mergeSort(temp2))
]);
}
async function merge(arr1, arr2) {
await sleep(25);
let sorted = [];
while (arr1.length > 0 && arr2.length > 0) {
(arr1[0] < arr2[0]) ? sorted.push(arr1.shift()):
sorted.push(arr2.shift());
}
while (arr1.length > 0) {
sorted.push(arr1.shift());
}
while (arr2.length > 0) {
sorted.push(arr2.shift());
}
values = sorted.slice();
}
function draw() {
background(0);
mergeSort(values);
for (let i = 0; i < values.length; i++) {
noStroke();
if (states[i] == 0) {
fill('#38e332');
} else if (states[i] == 1) {
fill('#c9c8c7');
} else {
fill(255);
}
//draw the array values at location x=i*w , y=height-array[i] with given width (w) and height(array[i])
rect(i * w, height - values[i], w, values[i]);
}
}
async function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
'

Related

JavaScript find longest Uniform Substring

Trying to find longest Uniform Substring.
Suppose I have abbbccda then it should return [1, 3]. Because it starts from index 1 and is 3 characters long.
Other Example:
"10000111" => [ 1, 4 ]
"aabbbbbCdAA" => [ 2, 5 ]
I tried:
function longestUniformSubstring(input){
if(input){
let arr = input.split("");
let obj = {};
arr.map((ele, index) => {
return obj[ele] ? obj[ele][1]++ : obj[ele] = [index,1];
});
console.log(obj);
return obj;
}
else {
return [ -1, 0 ];
}
}
longestUniformSubstring("abbbccda");
It gives me object of all character But, no idea how can i get with highest length.
You could iterate the string and check the previous character and continue if the caracters are equal.
If not, check the length and assign a new logest array, if necessary and check if a longer string is not possible, then break the loop.
Assign the new found character and set a new start value to the actual index.
function longestUniformSubstring(input) {
var longest = [-1, 0],
start = 0,
character = input[0];
for (let i = 1; i <= input.length; i++) {
if (input[i] === character) continue;
if (longest[1] < i - start) {
longest = [start, i - start];
if (i + i - start >= input.length) break;
}
character = input[i];
start = i;
}
return longest;
}
console.log(...longestUniformSubstring("aabbbbbCdAA"));
console.log(...longestUniformSubstring("ab"));
console.log(...longestUniformSubstring("aa"));
console.log(...longestUniformSubstring(""));
You can keep track of the character being evaluated. When it changes, check to see if its repetition is larger than previous repetitions. If so, store the new version and move on.
function longestUniformSubstring(input){
const result = [-1, 0];
let currentCharacter = '';
let currentIndex = -1;
let currentCount = 0;
(input || '').split('').forEach((character, index) => {
if (character == currentCharacter) {
currentCount++;
} else {
if (currentCount > result[1]) {
result[0] = currentIndex;
result[1] = currentCount;
}
currentCharacter = character;
currentIndex = index;
currentCount = 1;
}
});
if (currentCount > result[1]) {
result[0] = currentIndex;
result[1] = currentCount;
}
return result;
}
console.log(longestUniformSubstring("abbbccdddda"));
You can write the logic like this, this works at my end.
function longestUniformSubstring(input) {
let length = input.length;
let firstLetter = input[0];
let sIndex = 0;
let eIndex = 0;
let resultIndex = 0;
let resultLength = 0;
while(sIndex < length && eIndex < length) {
if (input[eIndex] === firstLetter) {
eIndex++;
if (eIndex - sIndex > resultLength) {
resultLength = eIndex - sIndex;
resultIndex = sIndex;
}
}
else {
sIndex++;
if (input[sIndex] !== firstLetter)
{
firstLetter = input[sIndex];
}
}
}
return [resultIndex, resultLength];
}
console.log(longestUniformSubstring('AABBBBBCC'));
You can create a queue, to keep track of elements. and pop once all the iteration has been done.
function longestUniformSubstring(input) {
if (!input) return [-1, 0];
let queue = [];
const map = {};
for (let index = 0; index < input.length; index++) {
const char = input[index];
if (!map[char]) map[char] = [index, 1];
else {
map[char][1] += 1;
}
const max = queue[0];
if (max && max[1] < map[char][1]) {
queue.unshift(map[char]);
} else {
queue.push(map[char]);
}
}
return queue.shift();
}
console.log(longestUniformSubstring("abbbccda"));
console.log(longestUniformSubstring("10000111"));
console.log(longestUniformSubstring("aabbbbbCdAA"));
The dirty one, keep track of longest
function longestUniformSubstring(input) {
if (!input) return [-1, 0];
let max = ["", -1, 0];
let map = {}
for (let index = 0; index < input.length; index++) {
const char = input[index];
if (!map[char]) map[char] = [index, 1];
else {
map[char][1] += 1;
}
if (max[2] < map[char][1]) {
max = [char, map[char][0], map[char][1]];
}
}
return [max[1], max[2]];
}
console.log(longestUniformSubstring("abbbccda"));
console.log(longestUniformSubstring("10000111"));
console.log(longestUniformSubstring("aabbbbbCdAA"));
You can use .reduce to count. .sort method to get the min or max.
function longestUniformSubstring(input) {
if (!input) return [-1, 0];
const map = input.split("").reduce((m, item, index) => {
if (!m[item]) m[item] = [index, 1];
else {
m[item][1] += 1;
}
return m;
}, {});
return Object.values(map).sort(([_, i], [__, j]) => j - i)[0];
}
console.log(longestUniformSubstring("abbbccda"));
console.log(longestUniformSubstring("10000111"));
console.log(longestUniformSubstring("aabbbbbCdAA"));
You can just iterate over
function longestUniformSubstring(input){
if(!input) {
return [-1, 0];
}
let lastIndex=0;
let lastLength=1;
let currIndex=0;
let currLength=0;
for (let i = 1; i < input.length; i++) {
if(input.charAt(i)===input.charAt(i-1)) {
currLength++;
} else {
if (currLength > lastLength) {
lastIndex = currIndex;
lastLength = currLength;
}
currIndex = i;
currLength = 1;
}
}
return [lastIndex, lastLength];
}

Problems Implementing Multithreaded mergeSort in Javascript

I am new to coding for parallel processing and am attempting to implement a multithreaded Merge Sort algorithm. I am unclear on the proper usage of threads and how exactly it works, but I attempted to implement it anyway and this is where I landed. (tells me that slice is not a function)
function pMergeSort(input, done) {
const spawn = require('threads').spawn;
if (input.length< 2)
return input;
function partition(arr) {
let middle = Math.floor(arr.length / 2);
let left = arr.sclice(0, middle);
let right = arr.slice(middle + 1, arr.length);
}
let left,right=partition(input);
let task = spawn(pMergeSort).send(left).on('done', function (arr) {
if (result === undefined) {
for (let i = 0; i< n.length; i++) {
result[i] = n[i];
}
}else {
merge(result, n);
left.kill();
}
});
pMergeSort(right, function (n) {
if (result === undefined) {
for (let i = 0; i< n.length; i++) {
result[i] = n[i];
}
}else {
merge(result, n);
right.kill();
}
});
}
/*
function mergeSort (arr) {
if (arr.length === 1) {
// return once we hit an array with a single item
return arr
}
const middle = Math.floor(arr.length / 2) // get the middle item of the array rounded down
const left = arr.slice(0, middle) // items on the left side
const right = arr.slice(middle) // items on the right side
return merge(mergeSort(left), mergeSort(right))
}*/
// compare the arrays item by item and return the concatenated result
function merge(left, right) {
let result = []
let indexLeft = 0
let indexRight = 0
while (indexLeft < left.length && indexRight < right.length) {
if (left[indexLeft] < right[indexRight]) {
result.push(left[indexLeft])
indexLeft++
} else {
result.push(right[indexRight])
indexRight++
}
}
return result.concat(left.slice(indexLeft)).concat(right.slice(indexRight))
}
function genArray(size) {
// randomly fills arr
var arr = Array(size);
for (var i = 0; i < size; i++) {
arr[i] = Math.floor(Math.random() * 98);
}
return arr
}
function testParallel(){
var array=genArray(Math.floor(Math.random()*100));
pMergeSort(array, function(i){
console.log(JSON.stringify(i));
})
}
var testArr = genArray(2);
pMergeSort(testArr, function (i) {
console.log(JSON.stringify(i));
});
help implementing this would be amazing, but some simple questions that could push me in the right direction is, is the merge of pMergeSort supposed to be a callback function? how do you define your call back function? Would it be better to use a pool of threads rather than trying to spawn threads? And the function wrapped in pMergeSort should be merge sort + splitting into threads right?

Strange behavior of the neutral network written in plain JS

Impressed by the possibilities of neural networks, I've decided that before using any library I want to understand how they work. So I wrote a simple training app, which used 3 layer network with 2 neurons each. There was a canvas 400x400. Given the coordinates of x,y of the mouse over the canvas <0;399> it was supposed to give as the result coordinate/400 <0;1> (So for 100,300 it is supposed to give 0.25,0.75).
The training looked reasonable.
But when I switch to the prediction mode the network gives the same result all the time for each training batch. It gives the same results no matter what the input is.
Then after more training the output changes, but it’s still the same for each input.
It's written in TypeScript.
Instead of pasting the whole web training page I just made the training script so you can see more clearly what's going on.
index.ts
let sigmoid: ActivationFunction = {
func: (x: number) => (1 / (1 + Math.exp(-x))),
derivative: (z: number) => {
return sigmoid.func(z) * (1 - sigmoid.func(z));
}
};
import Matrix from './matrix';
class NeutralNetwork {
layers: Array<number>;
weights: Matrix[];
biases: Matrix[];
activation_function: ActivationFunction;
learning_rate: number;
constructor(...layers: Array<number>) {
this.layers = layers;
this.activation_function = sigmoid;
//Initialize neural network with random weigths and biases [-1;1]
this.weights = [];
for(let i=0; i<this.layers.length - 1; i++){
this.weights.push(new Matrix(this.layers[i+1], this.layers[i]));
this.weights[i].randomize();
}
this.biases = [];
for(let i=1; i<this.layers.length; i++){
this.biases.push(new Matrix(this.layers[i], 1));
this.biases[i-1].randomize();
}
this.setActivationFunction();
this.setLearningRate();
}
feedForward(originalInput: Array<number>): Array<number> {
if(originalInput.length != this.layers[0]) throw new Error("corrupt input data");
let input : Matrix = Matrix.createFromArray(originalInput);
for(let i = 0; i < this.layers.length - 1; i++){
let output = Matrix.multiply(this.weights[i], input);
output.add(this.biases[i]);
output.map(this.activation_function.func);
input = output;
}
return input.toArray();
}
train(originalInput: Array<number>, originalTarget: Array<number>) {
if(originalInput.length != this.layers[0]) throw new Error("corrupt training data");
if(originalTarget.length != this.layers[this.layers.length - 1]) throw new Error("corrupt training data");
let outputs : Matrix[] = [];
let input : Matrix = Matrix.createFromArray(originalInput);
for(let i = 0; i < this.layers.length - 1; i++){
let output = Matrix.multiply(this.weights[i], input);
output.add(this.biases[i]);
output.map(this.activation_function.func);
input = output;
outputs.push(output);
}
let target = Matrix.createFromArray(originalTarget);
let errors = Matrix.subtract(target, outputs[this.layers.length - 2]);
for(let i = this.layers.length - 2; i>=0; i--){
let gradients = Matrix.map(outputs[i], this.activation_function.derivative);
gradients.multiply(errors);
gradients.multiply(this.learning_rate);
let outputsOfLayerBeforeTransposed = Matrix.transpose(i > 0 ? outputs[i-1] : Matrix.createFromArray(originalInput));
let deltas = Matrix.multiply(gradients, outputsOfLayerBeforeTransposed);
this.weights[i].add(deltas);
this.biases[i].add(gradients);
let weightsTransposed = Matrix.transpose(this.weights[i]);
errors = Matrix.multiply(weightsTransposed, errors);
}
return outputs[outputs.length - 1].toArray();
}
setActivationFunction(activationFunction = sigmoid) {
this.activation_function = activationFunction;
}
setLearningRate(learning_rate = 0.1) {
this.learning_rate = learning_rate;
}
}
interface ActivationFunction {
func(x: number): number;
derivative(x: number): number;
}
export = NeutralNetwork;
training.ts
let NN = require('./index');
let n = new NN(2,2,2);
let data = generateTrainingData();
data.forEach(d => n.train(d.i, d.o));
//check how well is it trained
let index = 0
let t = setInterval(()=>{
let pred = n.feedForward(data[index].i);
console.log(`PREDICTED - ${pred} EXPECTED = ${data[index].o} COST - ${Math.pow(pred[0]-data[index].o[0],2)+Math.pow(pred[1]-data[index].o[1],2)}`)
if(index++ == 1000) clearInterval(t);
}, 500);
function generateTrainingData(){
let data = [];
for(let i=0;i<1000;i++){
let x = Math.floor(Math.random() * 400);
let y = Math.floor(Math.random() * 400);
data.push({
i : [x,y],
o : [x/400, y/400]
})
}
return data;
}
matrix.ts
export default class Matrix {
rows;
columns;
data: Array<Array<number>>;
constructor(rows, columns) {
this.rows = rows;
this.columns = columns;
this.data = new Array(this.rows).fill().map(() => Array(this.columns).fill(0));
}
static map(matrix, f) : Matrix{
let m = new Matrix(matrix.rows, matrix.columns);
m.map((v,i,j) => f(matrix.data[i][j], i, j));
return m;
}
map(f) {
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.columns; j++) {
this.data[i][j] = f(this.data[i][j], i, j);
}
}
}
randomize() {
this.map(() => Math.random() * 2 - 1);
}
add(n) {
if (n instanceof Matrix) {
if (this.rows !== n.rows || this.columns !== n.columns) {
throw new Error('Size of both matrices must match!');
}
return this.map((v, i, j) => v + n.data[i][j]);
} else {
return this.map(v => v + n);
}
}
static subtract(a, b) : Matrix{
if (a.rows !== b.rows || a.columns !== b.columns) {
throw new Error('Size of both matrices must match!');
}
let m = new Matrix(a.rows, a.columns);
m.map((_, i, j) => a.data[i][j] - b.data[i][j]);
return m;
}
static multiply(a, b) {
if (a.columns !== b.rows) {
throw new Error('a.columns !== b.rows');
}
let m = new Matrix(a.rows, b.columns)
m.map((_, i, j) => {
let sum = 0;
for (let k = 0; k < a.cols; k++) {
sum += a.data[i][k] * b.data[k][j];
}
return sum;
});
return m;
}
multiply(n) {
if (n instanceof Matrix) {
if (this.rows !== n.rows || this.columns !== n.columns) {
throw new Error('Size of both matrices must match!');
}
return this.map((v, i, j) => v * n.data[i][j]);
} else {
return this.map(v => v * n);
}
}
toArray() {
let arr = [];
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.columns; j++) {
arr.push(this.data[i][j]);
}
}
return arr;
}
static transpose(matrix) : Matrix {
let m = new Matrix(matrix.columns, matrix.rows)
m.map((_, i, j) => matrix.data[j][i]);
return m;
}
static createFromArray(arr): Matrix {
let m = new Matrix(arr.length, 1);
m.map((v, i) => arr[i]);
return m;
}
}
I'm not really sure what the cause of that. I've been trying to debug this for days now, but I think my lack of experience doesn't let me see the issue here. Thank you so much for all of your help.
There is a mistake in Matrix.multiply class method. It should be a.columns rather than a.cols. Because of this, gradients and deltas are not updating properly.

javascript getting rid array reference

This is a react minesweeper and it involves setState when the user wants to choose a new grid size. When the user clicks the grid should be recreated, but there are some reference problems thanks to the prev state.
When I first console.log(array); it is not empty thanks to the prev state. When I console.log(array[m][n]['value']) it says all the values are 0, but when I console.log(array); right after it the array contains 'b' values which are set from the addBombsmethod which is invoked after the createMap.
What should I do?
createMap (sizeX, sizeY, bombNumber) {
let array = [];
while (array.length > 0) {
array.pop();
}
array.length = 0;
console.log(array); // not totally empty, but it says length 0.
for (var m = 0; m < sizeY; m++) {
array[m] = new Array();
for (var n = 0; n < sizeX; n++) {
array[m][n] = { value: 0, state: 'closed' };
console.log(array[m][n]['value']); // Prints 0 for all of them.
}
}
console.log(array); // There are 'b' values in the array.
return array.slice();
}
createTable(props) {
const sizeX = props.sizeX;
const sizeY = props.sizeY;
const bombNumber = props.bombNumber;
const map = this.createMap(sizeX, sizeY, bombNumber);
const newMap = map.slice();
const newestMap = this.addBombs(newMap, sizeX, sizeY, bombNumber);
const newestestMap = newestMap.slice();
const mMap = this.calculateFieldValues(newestestMap);
const nMap = mMap.slice();
return nMap;
}
addBombs (map, sizeX, sizeY, bombNumber) {
let bombFields = [];
while (bombFields.length < bombNumber) {
const randomNumber = Math.floor(Math.random() * (sizeY * sizeX - 1))
if (!bombFields.includes(randomNumber)) {
bombFields.push(randomNumber);
}
}
bombFields.forEach((number) => {
const i = Math.floor(number / sizeX);
let j = (number % sizeX);
if (j === -1) {
j = sizeX - 1;
}
map[i][j]['value'] = 'b';
});
return map;
}

How to generate 4 random non-repeating numbers from 0-9?

I want to get a random digit from 0-9 and have it popped so it doesn't get repeated but I find that after the the second number is pushed it doesn't have it's number popped. Instead, some other number not yet selected is popped giving room for a repeat.
var yourNum = [],
oppNum = [],
choose = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
function chooseRandomNumber() {
return choose[Math.floor(Math.random() * choose.length)];
}
for (var i = 0; i < 4; i++) {
if (i === 0) {
yourNum.push(chooseRandomNumber());
if (yourNum[yourNum.length - 1] === 9) {
choose.pop();
} else {
choose.splice(yourNum[0], 1);
}
} else if (i === 1) {
yourNum.push(chooseRandomNumber());
if (yourNum[yourNum.length - 1] === 9) {
choose.pop();
} else {
choose.splice(yourNum[1], 1);
}
} else if (i === 2) {
yourNum.push(chooseRandomNumber());
if (yourNum[yourNum.length - 1] === 9) {
choose.pop();
} else {
choose.splice(yourNum[2], 1);
}
} else if (i === 3) {
yourNum.push(chooseRandomNumber());
if (yourNum[yourNum.length - 1] === 9) {
choose.pop();
} else {
choose.splice(yourNum[3], 1);
}
}
}
console.log(choose);
console.log(yourNum);
function getRand(min, max, result) {
result = result || [];
if(result.length == 4) {
return result;
}
var rand = Math.floor(Math.random()*max) + min;
if(result.indexOf(rand) === -1) {
result.push(rand);
}
return getRand(min, max, result);
}
var result = getRand(1,9);
console.log(result);
Your whole approach is way to complicated and unperformant.
A better approach:
//first we need a shuffle function
function shuffle(array){
for(var i = array.length, j, tmp; i--; ){
j = 0|(Math.random() * i);
tmp = array[j];
array[j] = array[i];
array[i] = tmp;
}
return array;
}
//now let's define a sequence of possible values
var numset = [0,1,2,3,4,5,6,7,8,9];
//shuffle the sequence and take the first 4 values
var fourRandomValues = shuffle(numset).slice(0,4);
console.log("four random values: " + fourRandomValues);
//doing this multiple times:
for(var values = []; values.length < 10;){
//shuffle again, and take the values that are now at the beginning of this sequence
values.push( shuffle(numset).slice(0,4) );
}
console.log("more random values: \n" + values.join("\n"));
Edit:
to address holi-java's approach by implementing sort of an Iterator, I'll add a way to do this with ES6 Iterators/Generators
Since Generators can be unlimited sequences we need to account for that. We do that by buffering a limited amount of values and returning them randomly; basically a shifiting frame of shuffled values.
function *shuffled(iterable, bufferSize = 256){
var buffer, numValues = 0, randomIndex;
if(Array.isArray(iterable) && iterable.length <= bufferSize){
//an optimization for (small) Arrays:
buffer = iterable.slice();
numValues = iterable.length;
}else{
buffer = Array( bufferSize )
for(var value of iterable){
//push value from the iterable to the buffer
buffer[numValues++] = value;
//buffer is full, yield a random value
if(numValues === bufferSize){
//choose a random value from the buffer
randomIndex = 0|(Math.random() * (numValues-1));
//yield it
yield buffer[randomIndex];
//overwrite the value with the last index
//that's cheaper than pop() and splice()
buffer[randomIndex] = buffer[--numValues];
}
}
}
//iterable doesn't provide any more values
//flush the buffer in a random order
while(numValues){
randomIndex = 0|(Math.random() * (numValues-1));
yield buffer[randomIndex];
buffer[randomIndex] = buffer[--numValues];
}
}
//every Array is a valid iterator
for(var v of shuffled([0,1,2,3,4,5,6,7,8,9]))
console.log(v);
That way we can shuffle a stream of values without first caching all the values in an array.
pro: memory efficient
possible problem: if the buffer's to small the result doesn't feel random anymore since values that are generated late in the sequence simply can not be shifted entirely to the start. You see some noise but it doesn't feel random anymore.
now let's take a jump into potentially infinite sequences:
// *shuffled again, for this snippet
function *shuffled(iterable, bufferSize = 256){
var buffer, numValues = 0, randomIndex;
if(Array.isArray(iterable) && iterable.length <= bufferSize){
buffer = iterable.slice();
numValues = iterable.length;
}else{
buffer = Array( bufferSize )
for(var value of iterable){
buffer[numValues++] = value;
if(numValues === bufferSize){
randomIndex = 0|(Math.random() * (numValues-1));
yield buffer[randomIndex];
buffer[randomIndex] = buffer[--numValues];
}
}
}
while(numValues){
randomIndex = 0|(Math.random() * (numValues-1));
yield buffer[randomIndex];
buffer[randomIndex] = buffer[--numValues];
}
}
//creates an infinite sequence of numbers
function *count(){
for(var index = 0; true;)
yield index++;
}
//like limits a iterator but for iterators
function *take(n, iterator){
for(var value of iterator){
if(n-- > 0) yield value;
else break;
}
}
//create an (infinite) counter and convert it into a generator of shuffled values
//with a bufferSize of 256 entries (play a bit with that value)
var shuffledSequence = shuffled(count(), 256);
//to convert that into an Array we take the first 1000 values generated from that generator
var array = [...take(1000, shuffledSequence)];
//and log it
console.log(array.toString());
what do you mean like this below:
function next() {
function all() {
return [].concat(Array(10).fill(null).map(function (_, index) {
return index;
}));
}
function random(start, end) {
return parseInt(Math.random() * (end + 1 - start)) + start;
}
var self = this;
self.all = self.all && self.all.length && self.all || all().sort(function(){
return random(-1, 1);
});
return self.all.shift();}
var results=Array(4).fill(null).map(next);
console.log(results);
my be this is better for browser to run.
var it = {
next: function () {
var self = this;
self._all = self._all && self._all.length && self._all || self.shuffle(self.all());
return self._all.shift();
},
all: function () {
return [0,1,2,3,4,5,6,7,8,9];
},
random: function (start, end) {
if (!end && end != 0) {
end = start;
start = 0;
}
return parseInt(Math.random() * (end + 1 - start)) + start;
},
shuffle: function (array) {
var self = this;
for (var i = array.length - 1; i > 0; --i) {
self.swap(array, i, self.random(i));
}
return array;
},
swap: function (array, i, j) {
var tmp = array[i];
array[i] = array[j];
array[j] = tmp;
},
reset: function () {
this._all = null;
}
};
for (var i = 0; i < 10; i++) {
var results=[];
for(var n=0;n<4;n++) results.push(it.next());
console.log("retain:"+it._all + '>>generated:' + results);
it.reset();
}
Edit
Takes four unique numbers out of the choose array. Is that what you're after?
var yourNum = [],
oppNum = [],
choose = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
function chooseRandomNumber() {
return choose[Math.floor(Math.random() * choose.length)];
}
var rand;
for (var i = 0; i < 4; i++) {
rand = chooseRandomNumber();
yourNum.push(rand);
choose.splice(choose.indexOf(rand), 1);
}
console.log(choose);
console.log(yourNum);
Old approach:
var start = 0, end = 9;
function generate(count) {
var nums = [],
random;
for (var i = 0; i < count; i++) {
while (!random || nums.indexOf(random) !== -1) {
random = Math.floor(Math.random() * (end + 1)) + start;
}
nums.push(random);
}
return nums;
}
console.log(
generate(4)
);
Demo:
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
var yourNums = [];
var choose = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (var i = 0; i < 4; i++) {
yourNums = yourNums.concat(choose.splice(getRandomInt(0, choose.length), 1))
}
console.log("yourNums is:")
console.log(yourNums);
console.log("===")
console.log("choose is:")
console.log(choose);

Categories