How to Test Random Output? - javascript

The code below is used to play a Lottery game.
let Lotto = {
_nMap: [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50
],
_sMap: [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
],
/**
* #param {Array} shuffleArr
*
* #return {Array}
*/
_shuffleArr(shuffleArr) {
let rndNr, tmpValue;
for (let elmNr = shuffleArr.length - 1; elmNr > 0; elmNr--) {
rndNr = Math.floor(
Math.random() * (elmNr + 1)
);
tmpValue = shuffleArr[rndNr];
shuffleArr[rndNr] = shuffleArr[elmNr];
shuffleArr[elmNr] = tmpValue;
}
return shuffleArr;
},
/**
* #return {Object}
*/
getPick() {
return {
n: this._shuffleArr(this._nMap).slice(0, 5),
s: this._shuffleArr(this._sMap).slice(0, 2)
}
}
};
Now I want to verify whether the implementation is correct. For example: it should return a unique set of numbers. How do I test this? Run the .getPick() method once and validate the output or ...?

You can write a test case like, getting the script to run 10 to 15 times, and putting the values inside an array and finding the pattern. Something like this would be nice:
let Lotto = {
_nMap: [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50
],
_sMap: [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
],
/**
* #param {Array} shuffleArr
*
* #return {Array}
*/
_shuffleArr(shuffleArr) {
let rndNr, tmpValue;
for (let elmNr = shuffleArr.length - 1; elmNr > 0; elmNr--) {
rndNr = Math.floor(
Math.random() * (elmNr + 1)
);
tmpValue = shuffleArr[rndNr];
shuffleArr[rndNr] = shuffleArr[elmNr];
shuffleArr[elmNr] = tmpValue;
}
return shuffleArr;
},
/**
* #return {Object}
*/
getPick() {
return {
n: this._shuffleArr(this._nMap).slice(0, 5),
s: this._shuffleArr(this._sMap).slice(0, 2)
}
}
};
var entries = [];
for (var i = 0; i < 100; i++)
entries.push(JSON.stringify(Lotto.getPick()));
var counts = {};
for (var i = 0; i < entries.length; i++) {
counts[entries[i]] = 1 + (counts[entries[i]] || 0);
}
console.log(counts);
if (Object.keys(counts).length == 100)
alert("Excellent, 0 dupes!");
else if (Object.keys(counts).length > 75)
alert("More than 75% unique.");
else
alert("Less than 75% unique.");
Here, I could find every output is a distinct one. That's how you need to automate or write test cases. The above snippet itself is a testing solution. Try it out and let me know if it works out for you.

Related

How to optimalize for loop to work for everyon? [duplicate]

This question already has answers here:
How do I loop through or enumerate a JavaScript object?
(48 answers)
Closed 1 year ago.
i have a problem with the code, idk how to optimalize the code to work for every new "person" in object.
customers_data={
'Ben10': [22, 30, 11, 17, 15, 52, 27, 12],
'Sameer': [5, 17, 30, 33, 40, 22, 26, 10, 11, 45],
'Zeeshan': [22, 30, 11, 5, 17, 30, 6, 57]
}
var count = 0
for (let e of customers_data.Ben10) { if (e >= 20) count ++}
if (count >= 5) {console.log("Ben10 has Premium Membership")}
count = 0
for (let e of customers_data.Sameer) { if (e >= 20) count ++}
if (count >= 5) {console.log("Sameer has Premium Membership")}
count = 0
for (let e of customers_data.Zeeshan) { if (e >= 20) count ++}
if (count >= 5) {console.log("Zeeshan has Premium Membership"); count = 0}
count = 0
customers_data={
'Ben10': [22, 30, 11, 17, 15, 52, 27, 12],
'Sameer': [5, 17, 30, 33, 40, 22, 26, 10, 11, 45],
'Zeeshan': [22, 30, 11, 5, 17, 30, 6, 57]
}
var count = 0
for(let prop in customers_data)
{
for (let e of customers_data[prop]) { if (e >= 20) count ++}
if (count >= 5) {console.log(prop + " has Premium Membership")}
count = 0
}
Use two loops. Outer to loop name => values, inner to loop values
let customers_data = {
'Ben10': [22, 30, 11, 17, 15, 52, 27, 12],
'Sameer': [5, 17, 30, 33, 40, 22, 26, 10, 11, 45],
'Zeeshan': [22, 30, 11, 5, 17, 30, 6, 57]
}
for (let dataKey in customers_data) {
let count = 0;
for (let value of customers_data[dataKey]) {
if (value >= 20) {
count++;
}
}
if (count >= 5) {
console.log(dataKey + " has Premium Membership");
}
}
You can DRY this out a little by using a function into which you pass the data, and the name you want to check, and then return a message based on the result.
const customers_data = {
Ben10: [22, 30, 11, 17, 15, 52, 27, 12],
Sameer: [5, 17, 30, 33, 40, 22, 26, 10, 11, 45],
Zeeshan: [22, 30, 11, 5, 17, 30, 6, 57]
}
// Accept data and a name
function hasMembership(data, name) {
// `filter` out the numbers that are greater
// or equal to 20
const greaterThan20 = data[name].filter(entry => {
return entry >= 20;
});
// If the length of the filtered array is
// greater or equal to five, return a positive message
if (greaterThan20.length >= 5) {
return `${name} has Premium Membership!`;
}
// Otherwise return something else
return `Boo. No membership for ${name}.`;
}
console.log(hasMembership(customers_data, 'Ben10'));
console.log(hasMembership(customers_data, 'Sameer'));
console.log(hasMembership(customers_data, 'Zeeshan'));
Additional documentation
filter
Template/string literals

How do I replace unique values from another array, by replacing the original array

So I have two sets of Array, one of them is an object (arrA). And another one is just a set of primitive values arrB.
let a = "100229265852737908723455202093346882084130103685642861644052656467061936958706";
let arrA = [];
let arrB = [];
for (let i = 1; i <= 28; i++) {
arrA.push({index: i, pos: i, unique: false});
arrB.push(i);
}
let b = a.split(/(?=(?:..)*$)/).slice(0, 28);
b.forEach((val, index) => {
let c = Math.floor((+val / 100) * 28 ) + 1;
if (arrB.indexOf(c) !== -1) {
arrB.splice(arrB.indexOf(c), 1);
arrA[index].unique = true;
}
arrA[index].pos = c;
});
arrB.forEach((val, index) => {
arrA.forEach((valA, indexA) => {
if (!valA.unique) {
if (arrB[index] > valA.pos) {
arrA[indexA].pos = arrB[index];
arrA[indexA].unique = true;
arrB.splice(arrB.indexOf(arrB[index]));
}
}
})
});
My expected result is, arrA.pos is:
3, 1, 9, 8, 17, 15, 21, 4, 22, 10, 16, 6, 7, 27, 13, 20, 25, 5, 12, 14, 19, 11, 24, 18, 26, 28, 2
 
However I got:
3, 1, 9, 8, 17, 15, 21, 4, 21, 10, 16, 6, 6, 27, 10, 20, 23, 3, 12, 9, 3, 11, 24, 18, 8, 18, 18
If your goal is to take the string, split it into an array of elements of an arbitrary length, each being a 2-digit number, then output an Array that contains only the original Array's unique values, then you can do this:
const MAGIC_NUMBER = 28;
const a = "100229265852737908723455202093346882084130103685642861644052656467061936958706";
const b = a.split(/(?=(?:..)*$)/).slice(0, MAGIC_NUMBER );
const unique = Array.from( new Set( b ));
Set at MDN

How does this for in Loop Work to Sort Numbers using Quick Sort in JavaScript

How does the for in loop work below to correctly sort the numbers in the left array and right array for the quick sort implementation below?
I'd like an example of a first example iteration of the sortArr(left) recursive call, then another iteration, and so on (maybe up to three or four iterations).
Then I'll be able to understand the sortArr(left), including the sortArr(right) recursive call.
const unsortedArr = [31, 27, 28, 42, 13, 8, 11, 30, 17, 41, 15, 43, 1, 36, 9, 16, 20, 35, 48, 37, 7, 26, 34, 21, 22, 6, 29, 32, 49, 10, 12, 19, 24, 38, 5, 14, 44, 40, 3, 50, 46, 25, 18, 33, 47, 4, 45, 39, 23, 2];
let sortArr = (arr) => {
if (arr.length < 2) return arr;
const pivot = arr[Math.floor(arr.length / 2)];
let left = [];
let equal = [];
let right = [];
equal.push(pivot);
for (let element of arr) {
if (element < pivot) {
left.push(element);
} else if (element > pivot) {
right.push(element);
}
}
let sortedArr = sortArr(left)
.concat(equal)
.concat(sortArr(right));
return sortedArr;
};
console.log(sortArr(unsortedArr));

Spiral Matrix: Inner Functions Work But Throw Error When Used In While Loop

A Spiral Matrix coding challenge in JavaScript; of particular importance are the four inner functions leftToRight, topToBottom, rightToLeft, and bottomToTop. Commenting out the while loop and invoking the four functions within the scope of spiralCopy like so:
leftToRight(iLeftRightStart, iLeftRightEnd, leftRightPosition);
topToBottom(iTopBottomStart, iTopBottomEnd, topBottomPosition);
rightToLeft(iRightLeftStart, iRightLeftEnd, rightLeftPosition);
bottomToTop(iBottomTopStart, iBottomTopEnd, bottomTopPosition);
Returns [ 1, 2, 3, 4, 5, 6, 12, 18, 24, 30, 36, 35, 34, 33, 32, 31, 25, 19, 13, 7 ], as expected.
However, when used in the while loop in the code below the program crashes with the following error:
spiral.push(matrix[position][i]);
^
TypeError: Cannot read property '1' of undefined
Here is the entire program:
inputMatrix = [
[1, 2, 3, 4, 5, 6],
[7, 8, 9, 10, 11, 12],
[13, 14, 15, 16, 17, 18],
[19, 20, 21, 22, 23, 24],
[25, 26, 27, 28, 29, 30],
[31, 32, 33, 34, 35, 36]
]
const spiralCopy = (matrix) => {
const spiralLength = matrix.length * matrix[0].length;
const spiral = [];
let iLeftRightStart = 0; // +1
let iLeftRightEnd = matrix[0].length; // -1
let leftRightPosition = 0; // +1
let iTopBottomStart = 1; // +1
let iTopBottomEnd = matrix.length; // -1
let topBottomPosition = matrix[0].length - 1; // -1
let iRightLeftStart = matrix[0].length - 2; // -1
let iRightLeftEnd = 0; // +1
let rightLeftPosition = matrix.length - 1; // -1
let iBottomTopStart = matrix.length - 2; // -1
let iBottomTopEnd = 1; // +1
let bottomTopPosition = 0; // +1
const leftToRight = (iStart, iEnd, position) => {
console.log(iStart, iEnd, position);
for (let i = iStart; i < iEnd; i++) {
spiral.push(matrix[position][i]);
}
}
const topToBottom = (iStart, iEnd, position) => {
for (let i = iStart; i < iEnd; i++) {
spiral.push(matrix[i][position]);
}
}
const rightToLeft = (iStart, iEnd, position) => {
for (let i = iStart; i >= iEnd; i--) {
spiral.push(matrix[position][i]);
}
}
const bottomToTop = (iStart, iEnd, position) => {
for (let i = iStart; i >= iEnd; i--) {
spiral.push(matrix[i][position]);
}
}
while (spiral.length < spiralLength) {
leftToRight(iLeftRightStart, iLeftRightEnd, leftRightPosition);
topToBottom(iTopBottomStart, iTopBottomEnd, topBottomPosition);
rightToLeft(iRightLeftStart, iRightLeftEnd, rightLeftPosition);
bottomToTop(iBottomTopStart, iBottomTopEnd, bottomTopPosition);
iLeftRightStart++;
iLeftRightEnd--;
leftRightPosition--;
iTopBottomStart++;
iTopBottomEnd--;
topBottomPosition--;
iRightLeftStart--;
iRightLeftEnd++;
rightLeftPosition--;
iBottomTopStart--;
iBottomTopEnd++;
bottomTopPosition++;
}
return spiral;
}
console.log(spiralCopy(inputMatrix));
// should print [1, 2, 3, 4, 5, 6, 12, 18, 24, 30, 36, 35, 34, 33, 32, 31, 25, 19, 13, 7, 8, 9, 10, 11, 17, 23, 29, 28, 27, 26, 20, 14, 15, 16, 22, 21]
Why are the functions not working in the while loop?
The problem was decrementing leftRightPosition instead of incrementing it.
I changed the
leftRightPosition--;
To
leftRightPosition++;
And it works.

Issue with custom array ordering sequence Javascript

I am facing an issue with array ordering sequence. Need your help for desired result.
var a = [0, 1, 2, 3, 4, 5, 6, 77, 7, 8, 9, 10, 11, 12, 35, 36, 43, 51, 72, 89, 95, 100];
var b = [6,5,7,8,0,800,46,1,2,3,12,47,100,95];
var c = [];
for (var i = 0; i <= (a.length) - 1; i++) {
var res = b.indexOf(a[i]);
if (res > -1) {
c.push(a[i]);
}
}
document.write(c);
// I need same sequence of array B in reponse
// Desired Result
// 6,5,7,8,0,1,2,3,12,100,95
Iterate array b instead of a:
var a = [0, 1, 2, 3, 4, 5, 6, 77, 7, 8, 9, 10, 11, 12, 35, 36, 43, 51, 72, 89, 95, 100];
var b = [6,5,7,8,0,800,46,1,2,3,12,47,100,95];
var c = [];
for (var i = 0; i < b.length; i++) {
var res = a.indexOf(b[i]);
if (res > -1) {
c.push(b[i]);
}
}
console.log(c.join(','));
A more functional solution is to use Array#filter on b:
var a = [0, 1, 2, 3, 4, 5, 6, 77, 7, 8, 9, 10, 11, 12, 35, 36, 43, 51, 72, 89, 95, 100];
var b = [6,5,7,8,0,800,46,1,2,3,12,47,100,95];
var c = b.filter(function(n) {
return a.indexOf(n) !== -1;
});
console.log(c.join(','));

Categories

Resources