In the array randomly take three numbers, but the number of up and down the left and right non-adjacent (array cross random number)
This is my code, how can I optimize (get the number more evenly)?
Thanks~
array
var a = [
[0, 1],
[2, 3],
[4, 5],
[6, 7]
];
function select() {
var a = [
[0, 1],
[2, 3],
[4, 5],
[6, 7]
];
var lastSelect = -1;
for (var i = 0; i < a.length; i++) {
var index = getRandomNumber(lastSelect, a[i].length);
console.log(a[i][index]);
lastSelect = index;
}
}
function getRandomNumber(lastSelect, max) {
var random = Math.floor(Math.random() * max);
if (random == lastSelect) return getRandomNumber(lastSelect, max);
else return random;
}
select();
Javascript has a modulus operator %, that finds the remainder of division.
var a = [
[0, 1],
[2, 3],
[4, 5],
[6, 7]
];
function select() {
//generating random 0 or 1
var random = Math.round(Math.random());
for (var i = 0; i < a.length; i++) {
console.log(a[i][(i+random)%2]);// 0 or 1
}
console.log("-----------");
}
//test
for(var j=0;j<5;j+=1){
select();
}
Related
I'm creating a tictactoe game and I'm trying to compare each set array within the winPattern 2d array to the placePieces array.
I've created loops to iterate through the winPattern 2d array for each placePieces array but because it doesn't recognize each array as a set and simply iterates through individual values, it doesn't work as intended.
const winPattern = [
//horizontal
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
//vertical
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
//diagonal
[0, 4, 8],
[2, 4, 6]
];
//positions that o or x would be in tictactoe
const placePieces = [0, 1, 2, 4, 8];
let count = 0;
nextPiece:
for (let i = 0; i < placePieces.length; i++) {
for (let j = 0; j < winPattern.length; j++) {
for (let n = 0; n < winPattern[0].length; n++) {
if (placePieces[i] === winPattern[j][n]) {
//Prints out the matches and mismatches
console.log(`It matches: Piece: ${placePieces[i]} //\\ Pattern: ${winPattern[j][n]}`);
continue nextPiece;
} else {
console.log(`It doesn't match: Piece: ${placePieces[i]} //\\Pattern: ${winPattern[j][n]}`);
}
}
}
}
I'm expecting the placePieces array to compare values with each SET of arrays in the winPattern 2d array.
This code should work to see if the users current array matches anything in the answers array -
var winPattern = [
//horizontal
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
//vertical
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
//diagonal
[0, 4, 8],
[2, 4, 6]
];
//positions that o or x would be in tictactoe
var placePieces = [0, 1, 2, 4, 8, ];
var count = 0;
function arraysEqual(a, b) {
if (a === b) return true;
if (a == null || b == null) return false;
if (a.length != b.length) return false;
for (var i = 0; i < a.length; ++i) {
if (a[i] !== b[i]) return false;
}
return true;
}
function checkMatch(arr){
for(var i = 0; i < winPattern.length; i++){
for(var j = 0; j < arr.length - 2; j++){
for(var k = j + 1; k < arr.length - 1; k++){
for(var l = k + 1; l < arr.length; l++){
var possibleAnswer = [arr[j], arr[k], arr[l]];
if(arraysEqual(possibleAnswer, winPattern[i])) return true;
}
}
}
}
return false;
}
This is assuming placePieces is sorted because it seemed like it was in your example. Hope this helps!
I'm looking for an array method implementation named Array.window(n) that invoked on an array with parameter n, would give a contiguous overlapping array slice.
Example:
let a = [1, 2, 3, 4, 5, 6]
a.window(2) // [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6]]
a.window(3) // [[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6]]
a.window(4) // [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6]]
a.window(10)// []
How can I accomplish this?
Here you go with a slightly shorter example using array functions:
let a = [1, 2, 3, 4, 5, 6];
function windowedSlice(arr, size) {
let result = [];
arr.some((el, i) => {
if (i + size > arr.length) return true;
result.push(arr.slice(i, i + size));
});
return result;
}
console.log(windowedSlice(a, 2));
console.log(windowedSlice(a, 3));
console.log(windowedSlice(a, 4));
console.log(windowedSlice(a, 5));
I think this would suffice:
function arrayWindow(array, n) {
if (array.length < n || n <= 0) {
return []
}
let arrayLength = array.length
let result = []
for (let i = 0; i < arrayLength; i++) {
let slicedArray = array.slice(i, n+i)
if (slicedArray && slicedArray.length === n) {
result.push(slicedArray)
continue
}
break
}
return result
}
let arr = [1, 2, 3, 4, 5, 6]
console.log(arrayWindow(arr, 2))
console.log(arrayWindow(arr, 3))
console.log(arrayWindow(arr, 4))
console.log(arrayWindow(arr, 5))
console.log(arrayWindow(arr, 10))
console.log(arrayWindow(arr, 0))
Here is a simple rolling window function. Notice that we can determine the number of iterations based on array length minus the desired window size.
/**
* Produces a rolling window of desired length {w} on a 1d array.
*
* #param {Array} a The 1d array to window.
* #param {Number} w The desired window size.
* #return {Array} A multi-dimensional array of windowed values.
*/
function rolling(a, w) {
let n = a.length;
let result = [];
if (n < w || w <= 0) {
return result;
}
for (let i = 0; i < n - w + 1; i++) {
result.push(a.slice(i, w + i));
}
return result;
}
let a = [1, 2, 3, 4, 5];
console.log(JSON.stringify(rolling(a, 3)));
I have written this code
var items = [
[1, 2],
[3, 4],
[5, 6]
];
function listiteration(list, fromrows, torows, col) {
var newl = list; //making a copy of list
var iterla = [];
for (i = fromrows; i <= torows; i++) {
iterla[i] = [];
for (j = col; j <= col; j++) {
iterla[i][j] = newl[i][j];
}
}
return iterla;
}
console.log(listiteration(items, 1, 2, 1));
result should be
[[4],[6]]
but getting
[ <1 empty item>, [ <1 empty item>, 4 ], [ <1 empty item>, 6 ] ]
how to solve this
You don't need the second for loop. Just create a new list, iterate over the rows and use push function to add the current rows col-th element into the array.
const items = [[1, 2], [3, 4], [5, 6]];
function listiteration(list, fromRows, toRows, col) {
const newList = [];
for (let i = fromRows; i <= toRows; i++) {
newList.push([list[i][col]]);
}
return newList;
}
const newItems = listiteration(items, 1, 2, 1);
console.log(newItems);
You can do this with slice() and map() methods.
var items = [[1, 2], [3, 4], [5, 6]];
function f(list, start, end, col) {
return list.slice(start, end + 1).map(e => [e[col]])
}
const result = f(items, 1, 2, 1)
console.log(result)
You can also add check for arrays.
var items = [[1, 2], 'a', [5, 6], [1, 2]];
function f(list, start, end, col) {
return list
.slice(start, end + 1)
.map(e => Array.isArray(e) ? [e[col]] : e)
}
const result = f(items, 1, 3, 1)
console.log(result)
A simpler approach
var items = [[1, 2], [3, 4], [5, 6]];
function listiteration(list, fromrows, torows, col) {
var ret = [];
for (var i = fromrows; i <= torows; i++) {
ret.push(list[i][col]);
}
return ret;
}
console.log(listiteration(items, 1, 2, 1));
This would be the solution
var items = [ [1, 2], [3, 4], [5, 6] ];
function listiteration(list, start, end, col) {
var result = [];
for ( i = start; i <= end; i++ ) {
result.push( [ list[ i ][ col ] ] )
}
return result;
}
console.log(listiteration(items, 1, 2, 1));
Other answers have given you different ways of doing this, and that's great.
But for learning purposes I've fixed the bug in the one you have done.
All you forgot to do was offset the arrays back to zero..
iterla[i - fromrows][j - col] = newl[i][j];
Example below..
var items = [
[1, 2],
[3, 4],
[5, 6]
];
function listiteration(list, fromrows, torows, col) {
var newl = list; //making a copy of list
var iterla = [];
for (i = fromrows; i <= torows; i++) {
iterla[i - fromrows] = [];
for (j = col; j <= col; j++) {
iterla[i - fromrows][j - col] = newl[i][j];
}
}
return iterla;
}
console.log(listiteration(items, 1, 2, 1));
var items = [
[1, 2],
[3, 4],
[5, 6]
];
function listiteration(list, fromrows, torows, col) {
var newArr = list.splice(fromrows, torows);
var newResult =[];
newArr.map(value=>{
newResult.push([value[col]]);
});
return newResult;
}
console.log(listiteration(items, 1, 2, 1));
I want to see the output like
[0, 1, 2]
[3, 4, 5, 6]
[7, 8, 9]
[10, 11, 12, 13]
[14, 15, 16]
...
recognize every three(a cycle) and four(b cycle) to do something.
I have only figure out some bad way I think like following:
var arr = [];
function a(n) {
var eachCycle = 7;
var aCycle = 3;
var bCycle = 0;
arr.push(0);
for (var i = 1; i < n; i += 1) {
if (i % eachCycle === aCycle || i % eachCycle === bCycle) {
if(i % eachCycle === aCycle) {
// print three column
} else if(i % eachCycle === bCycle) {
// print four column
}
console.log(arr);
arr.length = 0;
}
arr.push(i)
}
}
is there any good idea to improve this function for the output !?
Thanks
How about this:
function a(n)
{
// keep track of all the cycles
var total = [];
// hold values for the current cycle
var temp = [];
// cycle sizes
var cycleSizes = [3, 4];
// index of the current cycle
var currentCycleIndex = 0;
// iterate through numbers
for(var i = 0; i < n; ++i)
{
// push the value into the temp
temp.push(i);
// if the length of the temp array is the length we want for the current cycle then
if(temp.length == cycleSizes[currentCycleIndex])
{
// save the cycle data
total.push(temp);
// reset the cycle
temp = [];
// change the cycle
currentCycleIndex = currentCycleIndex ^ 1;
}
}
return total;
}
a(9);
[
[0, 1, 2],
[3, 4, 5, 6],
[7, 8]
];
a(17);
[
[0, 1, 2],
[3, 4, 5, 6],
[7, 8, 9],
[10, 11, 12, 13],
[14, 15, 16],
];
I have an array like this:
var winArray = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[1, 4, 7],
[2, 5, 8],
[3, 6, 9],
[1, 5, 9],
[7, 5, 3]
];
And another array like this:
var Xarray = [1,2,3]
How can I check that the first array's index 0 contains my second array? Another issue is that the value order should not be regarded during the compression
Copy the arrays to new arrays, so that you can sort them, then compare each item in the arrays:
var a1 = winArray[0].slice(0);
var a2 = Xarray.slice(0);
var equal = a1.length == a2.length;
if (equal) {
a1.sort();
a2.sort();
for (var i = 0; i < a1.length; i++) {
if (a1[i] != a2[i]) {
equal = false;
break;
}
}
}
Demo: http://jsfiddle.net/Guffa/oa11qc4r/
If you mean that you want to search the array for a match, and not only compare the array at index 0, you would loop through the array and compare each array:
var a1 = Xarray.slice(0);
a1.sort();
var equal = false;
for (var j = 0; !equal && j < winArray.length; j++) {
var a2 = winArray[j].slice(0);
equal = a1.length == a2.length;
var index = j;
if (equal) {
a2.sort();
for (var i = 0; i < a1.length; i++) {
if (a1[i] != a2[i]) {
equal = false;
break;
}
}
}
}
Demo: http://jsfiddle.net/Guffa/oa11qc4r/1/
Might give this a shot. The function will return the index of the 'child array' if its found in the main data array. If its not found -1 will be returned.
var winArray = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[1, 4, 7],
[2, 5, 8],
[3, 6, 9],
[1, 5, 9],
[7, 5, 3]
];
var Xarray = [1,2,3];
function indexOfPredicate(data, value, predicate) {
if (typeof(predicate) !== 'function') {
throw "Predicate must be a function"
}
for(var x = 0; x < data.length; x++) {
if (predicate(data[x], value)) {
return x
}
}
return -1;
}
function indexOfMulti(data, value) {
return indexOfPredicate(data, value, function(a, b) {
if (a.length !== b.length) {
return false;
}
for(var i = 0; i < a.length; i++) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
})
}
var index = indexOfMulti(winArray, Xarray);
var contains = index > -1;
console.log(index);
console.log(contains);