Iterate an array into a custom grid - javascript

I have a gird similar with a table with columns and rows but custom created with divs and spans and I want to populate every cell with values from many arrays and is not really working :|
so this is my function that generay those arrays:
function generate(count, values) {
return Array.apply(null, { length: count }).map(function () {
var r = [],
array = values.slice();
while (array.length) {
r.push(array.splice(Math.floor(Math.random() * array.length), 1)[0]);
}
return r;
});
};
var myStringArray = generate(7, [1, 2, 3, 4, 5, 6, 7]);
var arrayLength = myStringArray.length;
for (var i = 0; i < arrayLength; i++) {
console.log(myStringArray[i]);
}
and with this I try to add each array on each row but unfortunatley is not working.
Array.from(document.getElementsByClassName('cell')).forEach(function(e, j) {
e.textContent = myStringArray[i];
});
fiddle:

I'm not sure if i understand you right but i would try this JS code.
First we have to take your 2D Array and calculate the x and y coordinates. Its the index of your cells. If you have 7 Cells in a Row and 4 Rows you have 7*4=28 Output Elements (called Cell). All the Cell's where in a long 1D array. After the 7th Element a new Row start (and after 14th and so on). The Column number is the Index (Number of Cell inside your 1D array) mod 7 (the number of elements of one Row).
Index 0 --> x = Index % 7 = 0 % 7 = 0
Index 6 --> x = Index % 7 = 6 % 7 = 6
Index 7 --> x = Index % 7 = 7 % 7 = 0
Now we need the Row number. This is also the Index but divided by 7 (the number of elements of one Row)
Index 0 --> y = Index / 7 = 0 / 7 = 0
Index 6 --> y = Index / 7 = 6 / 7 = 0.85...
Index 7 --> y = Index / 7 = 7 / 7 = 1
Index 8 --> y = Index / 7 = 8 / 7 = 1.14...
1.14 isn't a nice row number. so we have to cut of the numbers after the point with Math.floor.
And now we have the coordinates x and y. We can use them inside the 2D Array and thats it :)
Array.from(document.getElementsByClassName('cell')).forEach(function(e, j){
//
var y = Math.floor(j/myStringArray.length);
var x = j%myStringArray.length;
e.textContent = myStringArray[y][x] /*+"("+x+","+y+")"*/;
});
Edited fiddle: https://jsfiddle.net/truvh94a/6/
If it's not what you want, please post an example result.

A different approach to your problem with two less specific utility functions, than your generate.
//retuns an Array of nodes that match the css-selector
function $$(selector, ctx){
if(!ctx || !ctx.querySelectorAll) ctx = document;
return Array.from(ctx.querySelectorAll(selector));
}
//shuffles an Array in place and returns it
function shuffle(arr){
for(var i=arr.length, j, tmp; i-->1;){
tmp = arr[ j = 0|(Math.random() * i) ];
arr[j] = arr[i];
arr[i] = tmp;
}
return arr;
}
//forEach `.row` ...
$$('.row').forEach(function(row){
// ... generate a shuffled sequence ...
var values = shuffle([1,2,3,4,5,6,7]);
//... and apply the values to the `.cell`s textContent
$$('.cell', row).forEach(function(cell, i){
cell.textContent = values[i];
});
});

Related

I want to implement a loop script in JS

I want to implement a script to create an array consisting of integers from 1 to 20. Chose those elements that can be divided by 3 and multiply by 3rd power. then chose minimal value from three of its maximum elements.
Here is my code..
var total = 0;
var arrVal = [];
for (var counter = 0; counter <= 20; counter++) {
var i = 3;
var a = 0;
if (counter%i===0 && i!==counter) {
arrVal.push(counter * i);
}
}
console.log(arrVal)
for(var i = arrVal.length; i > 0; i--) {
if(i >= 3){
max = arrVal[i];
total = max;
}
}
console.log(total);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I would like to know if it is ok or not?
Thanks in advance..
You could do it in an easier manner if I understand what you want to do:
Array(21).fill(0).map((v, i) => i).filter(v => v !== 3 && v % 3 === 0).map(v => v * 3).slice(-3)[0]
I'll explain each step:
First you create an array of size 20+1
Then you fill it with zeros (because you can iterate over an array of undefined values)
Fill it with the index number of each element (0,1,2,3...,20).
Filter the array to get the elements that can be divided by 3 but aren't 3 (0,6,9,...) and you multiply them by 3 (0,18,27,...)
Slice the three last elements (36, 45, 54)
Take the first element which is the lowest of the three highest elements.

Why does my factorial function always return one?

I am trying to write a piece of code to solve a Coderbyte challenge, to calculate a number's factorial. Every time I run it, the factorial generated is one. What am I doing wrong?
var num
var array1 = new Array();
function FirstFactorial(num) {
for (var i = num; i>0; i--){ // 8 , 7, 6 , 5
for (var y = 0; y<num ; y++){ // 0, 1, 2, 3, 4
array1[y]=i; // we have an array that looks like [8,7,6,5,4,3,2,1]
};
};
var sum = 1
for (var x = 0; x<array1.length; x++){ // now I want to run up that array, reading the #s
sum = sum * array1[x];
return sum;
};
return sum
};
A few issues.
1/ This is minor but, when you multiply two numbers, you get a product, not a sum.
2/ You returned the value from within the loop which would mean, even if you fixed the other problems, it would return prematurely without having multiplied all the numbers.
3/ Your nested loop does not fill your array the way you describe, you should check it after population. Think about your loops expressed as pseudo-code:
for i = num downto 1 inclusive:
for y = 0 to num-1 inclusive:
array1[y] = i
You can see that the inner loop is populating the entire array with the value of the current i. So the last iteration of the outer loop, where i is one, sets the entire array to ones.
4/ In any case, you don't need an array to store all the numbers from 1 to n, just use the numbers 1 to n directly. Something like (again, pseudo-code):
def fact(n):
prod = 1
for i = 2 to n inclusive:
prod = prod * i
return prod
This is a much easier way to calculate the factorial of a number.
function factorial(num)
{
if(num === 1)
{
return num;
}
return num * factorial(num - 1);
}
However to fix your code you need to fix the initial loop that loads the numbers into the array. as well as remove the return statement in the bottom loop. Like so.
function FirstFactorial(num) {
for (var i = num; i>0; i--) {
array1[num - i] = i;
};
var sum = 1
for (var x = 0; x < array1.length; x++){ // now I want to run up that array, reading the #s
sum = sum * array1[x];
};
return sum
};

Generate all combinations for pair of bits set to 1?

I'm trying to generate all possible combinations for pair of 1's within given bit width.
Let's say the bit width is 6, i.e. number 32. This is what I would like to generate:
000000
000011
000110
001100
001111
011000
011011
011110
110000
110011
110110
111100
111111
If I have variables:
var a = 1,
b = 2;
num = a | b;
and create a loop that I'll loop over width - 1 times, and where I shift both a << 1 and b << 1, I'll get all combinations for one pair. After that, I'm pretty much stuck.
Could someone , please, provide some help.
Update: working example
Based on Barmar's mathematical approach, this is what I managed to implement
var arr = [],
arrBits = [];
function getCombs(pairs, startIdx) {
var i, j, val = 0, tmpVal, idx;
if (startIdx + 2 < pairs) {
startIdx = arr.length - 1;
pairs -= 1;
}
if (pairs < 2) {
return;
}
for (i = 0; i < pairs-1; i++) {
idx = startIdx - (i * 2);
val += arr[idx];
}
for (j = 0; j < idx - 1; j++) {
arrBits.push((val + arr[j]).toString(2));
}
getCombs(pairs, startIdx-1);
}
(function initArr(bits) {
var i, val, pairs, startIdx;
for (i = 1; i < bits; i++) {
val = i == 1 ? 3 : val * 2;
arr.push(val);
arrBits.push(val.toString(2));
}
pairs = Math.floor(bits / 2);
startIdx = arr.length - 1;
getCombs(pairs, startIdx);
console.log(arrBits);
}(9));
Working example on JSFiddle
http://jsfiddle.net/zywc5/
The numbers with exactly one pair of 1's are the sequence 3, 6, 12, 24, 48, ...; they start with 3 and just double each time.
The numbers with two pairs of 1's are 12+3, 24+3, 24+6, 48+3, 48+6, 48+12, ...; these are the above sequence starting at 12 + the original sequence up to n/4.
The numbers with three pairs of 1's are 48+12+3, 96+12+3, 96+24+3, 96+24+6, ...
The relationship between each of these suggests a recursive algorithm making use of the original doubling sequence. I don't have time right now to write it, but I think this should get you going.
if the bit width isn't that big then you'll be way better off creating bit representations for all numbers from 0 to 31 in a loop and simply ignore the ones that have an odd number of "ones" in the bit representation.
Maybe start counting normally in binary and replace all 1's with 11's like this:
n = 5
n = n.toString(2) //= "101"
n = n.replace(/1/g, "11") //= "11011"
n = parseInt(n, 2) //= 27
So you'll get:
0 -> 0
1 -> 11
10 -> 110
11 -> 1111
100 -> 1100
101 -> 11011
110 -> 11110
111 -> 111111
And so on. You'll have to count up to 31 or so on the left side, and reject ones longer than 6 bits on the right side.
See http://jsfiddle.net/SBH6R/
var len=6,
arr=[''];
for(var i=0;i<len;i++){
for(var j=0;j<arr.length;j++){
var k=j;
if(getNum1(arr[j])%2===1){
arr[j]+=1;
}else{
if(i<len-1){
arr.splice(j+1,0,arr[j]+1);
j++;
}
arr[k]+=0;
}
}
}
function getNum1(str){
var n=0;
for(var i=str.length-1;i>=0;i--){
if(str.substr(i,1)==='1'){n++;}
else{break;}
}
return n;
}
document.write(arr.join('<br />'));
Or maybe you will prefer http://jsfiddle.net/SBH6R/1/. It's simpler, but then you will have to sort() the array:
var len=6,
arr=[''];
for(var i=0;i<len;i++){
for(var k=0,l=arr.length;k<l;k++){
if(getNum1(arr[k])%2===1){
arr[k]+=1;
}else{
if(i<len-1){
arr.push(arr[k]+1);
}
arr[k]+=0;
}
}
}
function getNum1(str){
var n=0;
for(var i=str.length-1;i>=0;i--){
if(str.substr(i,1)==='1'){n++;}
else{break;}
}
return n;
}
document.write(arr.sort().join('<br />'));
See http://jsperf.com/generate-all-combinations-for-pair-of-bits-set-to-1 if you want to compare the performance. It seems that the fastest code is the first one on Chrome but the second one on Firefox.
You can also do this with bit twiddling. If the lowest two bits are zero, we need to set them, which is equivalent to adding 3. Otherwise, we need to replace the lowest block of ones by its top bit and a 1-bit to the left of it. This can be done as follows, where x is the current combination:
x3 = x + 3;
return (((x ^ x3) - 2) >> 2) + x3;

Producing a random number that is different each time

I need to produce a random number ranging between 2 and 5 which is different each time. For example, I don't want two 3's in a row, or two 5's in a row. I then have to feed this into a for() loop, like this:
for(var i = 0; i < noBoxes.length; i+=randNumber) {
//....
}
How do I go about doing this?
Generate a random number up to n-1 and add it on, modulo the original range (shifting because the min is not 0):
i = some random int from 2 to 5
delta = randInt(3) // range of possible values from 2 to 5 is 4, minus 1 to
// prevent getting all the way round to i again
nextval = (i-2+delta)%4+2 // shift i down by the minimum, add the
// delta and modulo the range
This works because it adds up to 1 below the range, so it can never get back to the original number. For example, i=3, random int 0 to 2, so the max is (i-2+2)%3+2=3%3+2=0+2=2.
function differentRandInt(min,max,current) {
var shiftedcurrent = current-min;
var range = max-min+1;
var delta = Math.floor((Math.random()*(range-1))+1);
return (shiftedcurrent + delta)%range + min;
}
So if i=3, then i-min is 1, the range after adding the delta is 2,3,4, modulo 4 yielding 2,3,0, so adding the min gives us 4,5,2.
Edit: more complete solution, and fixed off-by-one error:
var prev, randNumber;
for(var i = 0; i < noBoxes.length; i+=randNumber) {
do {
randNumber = 2 + Math.floor(Math.random() * 4);
} while(randNumber === prev);
prev = randNumber;
}
Like so: http://jsbin.com/eyitav/
var loopingValues = [2, 3, 4, 5],
len,
value,
rand;
while ( (len=loopingValues.length) ) {
rand = ~~( ( Math.random() % 1 ) * len);
value = loopingValues.splice(rand, 1)[0];
//alert( value )
}
Now you have your loop with value as the value 2, 3, 4 and 5 in random order.
Or easier to read: http://jsbin.com/ejizuw/
var loopingValues = [2, 3, 4, 5],
value,
rand;
while ( loopingValues.length ) {
rand = Math.random();
if ( rand === 1 ) {
rand = 0;
}
rand = rand * loopingValues.length;
rand = Math.floor(rand);
value = loopingValues[rand];
loopingValues.splice(rand, 1);
alert(value);
}
You can get your series in an array before you start looping-
var noBoxes={length:100};
var R= [2], r= 2, n= 2;
while(R.length<noBoxes.length){
n= R[R.length-1];
while(r== n) r= 2+Math.floor(Math.random()*4)
R.push(r);
}
And then loop through the array-
for(var i = 0; i < noBoxes.length; i+=R[i]) {
....
}

javascript autoupdate array

I'd like to do the following;
create a 2 -column array of arbitrary finite length (say, 10 rows)
populate it sequentially from a constant-rate datastream
once its populated, update it from the same datastream ( ie replace element 0, move 1-9 down, discard old 9)
(optimally) output an average for each column
I can probably do 4 myself, but have no idea how to do 1-3.
If it helps, I'm trying to translate this;
http://kindohm.com/2011/03/01/KinectCursorControl.html (see under the dreaded shaking cursor).
This should work ok (nice question, by the way - fun little challenge, since there are tons of ways to do it)
var pointSmoother = (function(){
var pointCount = 10, // number of points to keep
componentCount = 2, // number of components per point (i.e. 2 for x and y)
points = [];
function clear() {
var i, l;
for( i = 0, l = componentCount ; i < l ; i++ ) {
if( typeof points[i] === 'undefined' ) {
points.push([]);
} else {
points[i].splice(0, pointCount);
}
}
}
clear();
function pushPoint( /* point components */ ) {
var i, l;
for( i = 0 ; i < componentCount ; i++ ) {
points[i].unshift(arguments[i]);
points[i] = points[i].slice(0, pointCount);
}
}
function average() {
var i, j, l, sum, averages = [];
l = points[0].length;
for( i = 0 ; i < componentCount ; i++ ) {
sum = 0;
for( j = 0 ; j < l ; j++ ) {
sum += points[i][j];
}
averages.push(sum/l);
}
return averages;
}
function getPoints() {
return points;
}
return {
getPoints: getPoints,
pushPoint: pushPoint,
clear: clear,
average: average
};
}());
What it basically does is it creates an object and assigns it to pointSmoother. The object has 4 methods: pushPoint(), clear(), getPoints() and average(). At the top of the thing you can set how many coordinates a point has, and how many points (maximum) to keep. I used your example of 2 coordinates per point, and 10 points at a time.
Now, I've made the assumption that you get your values in sets of 2 at a time. Let's call those 2 values x and y. When you receive them, add them to the thing by using pointSmoother.pushPoint(x, y);. You can then get the "average point", by calling pointSmoother.average() which will return an array with (in this case) 2 values: average x and average y.
If you want to look at the array yourself, you can call pointSmoother.getPoints() which will return the points array. And lastly, pointSmoother.clear() will empty the array of previous values.
Here's a demo, of sorts: http://jsfiddle.net/tapqs/1/
var nums = [[1,2],[1,3],[2,1]];
alert(nums[0][0]); //1
alert(nums[0][1]); //2
That's a two dimensional array. Loading data works just like with any other array.
To update it sequentially you are looking at queue behavior in javascript. Use unshift() and pop().
Javascript Arrays: http://www.w3schools.com/jsref/jsref_obj_array.asp
Finally for averaging the columns assuming there are 10 positions:
var num1 = 0;
var num2 = 0;
for(int i = 0;i<10;i++)
{
num1 +=array[i][0];
num2 +=array[i][1];
}
num1 = num1/10;
num2 = num2/10;
//num1 is now the average of the first column
//num2 is now the average of the second column

Categories

Resources