Construct 2/3: Continuous Loop Function? - javascript

Using Construct 3 to build a game.
I want to change this function in the code below (which just randomly assigns a frame count in an array) to something that isn't random, but instead loops in order from indexes 0 to 10 and then back to 0 and then to 10 in order again and loop like that continuously.
random(1,Self.AnimationFrameCount)
Is there a random() equivalent for non-random?

// generator function - yields multiple times, maybe forever
function* oneToTenAndBack(N: number): Generator<number> {
while(true) {
for (let i = 0; i < N; i++) yield i;
for (let j = N; j > 0; j--) yield j;
}
}
let k = 0;
for (let num of oneToTenAndBack(4)) {
console.log(num) // 0 1 2 3 4 3 2 1 0 1 2
if (++k>10) break;
}
let gen = oneToTenAndBack(3);
for (let k = 0; k < 10; k++)
console.log(gen.next()) // {value: number, done: false}
Playground Link

Related

Problems in understanding javascript nested for loops [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I try to understand nested for loops in javascript but it's very confusing.
I have this code and I can't understand how it works:
let n = 5;
for (let i = 0; i < n; i++) {
for (let j = 0; j < i; j++) {
console.log(j);
}}
In console I have : 0
1
0
1
2
0
1
2
3
And I'm trying to figure out which loop represent each number.
Run this code:
let n = 5;
let str = '';
for (let i = 0; i < n; i++) {
for (let j = 0; j < i; j++)
str += j;
console.log("Outer: "+i+" Inner: "+str);
str = '';
}
Output is:
Outer: 0 Inner:
Outer: 1 Inner: 0
Outer: 2 Inner: 01
Outer: 3 Inner: 012
Outer: 4 Inner: 0123
As you can see, in the output above, inner loop (the one with variable j) doesn't run, because if you replace the variables with numbers it would be
0 < 0 (i < 0), which isn't true.
The best way for you to understand how nested loops work is to write each step and variable values on the paper, like so:
n = 5
STEP 1:
i = 0
i < n (0 < 5) TRUE
j = 0
j < i (0 < 0) FALSE inner loop doesn't execute
OUTPUT: "Outer: 0 Inner:"
str = ''
STEP 2:
i = 1
i < n (1 < 5) TRUE
j = 0
j < i (0 < 1) TRUE
str = 0
j = 1 (j++)
j < i (1 < 1) FALSE
OUTPUT: "Outer: 1 Inner: 0"
str = ''
And so on... Keep repeating this until the argument in the outer loop is false (i < n).
You must remember, in for loop the sequence of orders executed:
for(let i = 0; i < 5; i++) {
console.log('It works');
}
let i = 0; (this executes only once)
i < 5 (if true run 3 and 4)
run the code in loop
i ++
i < 5 (if true run 6 and 7)
run the code in loop
i++
etc.

Print sequence of numbers in javascript

I'm sure this is quite a simple programming question however, I cant seem to understand it...
I'm trying to make the console.log print out numbers like this - 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 - one for each line. I thought modulo could be used to make this happen, however, I cant seem to figure out how to use it.
Here is the code:
iteration = 16;
for (var i = 0; i < iteration; i++) {
if(i == iteration%4 )
console.log(i);
}
Yes, you need a single loop.
No, you do not need the remainder operator %. This would give you
0 1 2 3 0 1 2 3 ...
But instead you could divide the actual value by 4 and take the integer value for console.log.
const iteration = 16;
for (let i = 0; i < iteration; i++) {
console.log(Math.floor(i / 4) + 1); // offset for starting with 1
}
I suggest that you use two nested for loops, one for the rows and another one for the columns.
Here's an example of how i would do it:
const columns = 4;
const rows = 4;
//if you want to just console.log each number on a different line
for (let i = 1; i <= rows; i++) {
for (let j = 1; j <= columns; j++) {
console.log(i);
}
console.log("\n");
}
//if you want to add each number to an array, and then log the array
for (let i = 1; i <= rows; i++) {
let columnsArray = [];
columnsArray.length = columns;
columnsArray.fill(i);
console.log(columnsArray);
}
//if you want to just log the numbers, you can spread the array
for (let i = 1; i <= rows; i++) {
let columnsArray = [];
columnsArray.length = columns;
columnsArray.fill(i);
console.log(...columnsArray);
}
//or you could push the arrays in another one, and get a matrix!
const matrix = [];
for (let i = 1; i <= rows; i++) {
let columnsArray = [];
columnsArray.length = columns;
columnsArray.fill(i);
matrix.push(columnsArray);
}
console.log(matrix);
It was not clear the output that you wanted, so i got a little sidetracked and made an example for the different cases that came to my mind.

How to perform j operations on array?

Given an array of integers, what's the most efficient way to perform j operations on the array where the value of j could be => or <= array.length?
I tried something like this...
function performJ(arr, j) {
arr.sort((a, b) => b - a);
let i = 0;
while (j !== 0) {
if (i < arr.length) {
arr[i] = Math.ceil(arr[i] / 2)
} else {
// when i reaches arr.length, reset it to continue operations j
i = 0;
arr[i] = Math.ceil(arr[i] / 2)
}
// increment i, step through arr
++i;
// decrement j as we perform operations on arr
--j;
}
return arr.reduce((a, b) => a + b);
}
That works for a lot of cases, but for some reason it seems like large inputs of arr and j cause arithmetic operations in the while loop to get way off.
Thanks!
EDIT: Edited question for clarity. I previously had a solution that worked, but it took way too long. This solution's arithmetic is off, but works much faster.
Use modulo to iterate on indicies [i % arr.length] from 0 to j:
function performJ(arr, j) {
arr.someMethod(); // ?
for (let i = 0; i < j; i++) {
arr[i % arr.length] = /* operation */
}
return arr.someMethod(); // ?
}
Why not just a for loop like this?
for(let i = 0; i <= j; i++) {
const index = i % array.length;
array[index] = doSomething();
}
if array.length is 5 but j is 3 then doSomething() will only be called on the first three elements. if array.length is 3 but j is 5 then i will reach 3 and 3 % 3 === 0 so index will loop back to the beginning. That means doSomething() will be called on all three elements once and during the second run on only the first two elements.
Is this what you want?

misprinted number in prime function

function primeSieve() {
for(i = 0; i <= 100; i++){
let flag = true
for(let j = 2; j < i/2; j++){
if(i % j === 0){
flag = false
}
}
if(flag){
console.log(i)
}
}
}
primeSieve();
Hi,
I'm studying some algos and ran into a prime sieve problem. I'm trying to print all prime numbers between 0 and 100 and it's working for the most part. However, i realized that 4 slipped in somehow and i can't figure out why for the life of me. Wondering if i can get a few pairs of eyes and see how 4 ended up being logged to the console and why that's the case.
thank you!
Your condition in the inner loop:
for (let j = 2; j < i / 2; j++) {
is
j < i / 2
This means that when i is 4, once j gets to 2 (or, since j is always initialized to 2, before the first iteration), the loop breaks. So, without any iterations, there's never any chance for an i of 4 to get to flag = false.
Change to
for (let j = 2; j <= i / 2; j++) {
Also, per wikipedia:
A prime number (or a prime) is a natural number greater than 1 that cannot be formed by multiplying two smaller natural numbers.
So you should probably start i at 2, not 0.
Also, just like your let j, it would be good to declare i with let as well so as not to implicitly pollute the global scope:
function primeSieve() {
for (let i = 2; i <= 100; i++) {
let flag = true
for (let j = 2; j <= i / 2; j++) {
if (i % j === 0) {
flag = false
}
}
if (flag) {
console.log(i)
}
}
}
primeSieve();
Beside the including the value for j to check with j <= i / 2, you could omit the use of a flag and use continue with a label for the outer loop.
function primeSieve() {
outer: for (var i = 2; i <= 100; i++) {
for (var j = 2; j <= i / 2; j++) {
if (i % j === 0) {
continue outer;
}
}
console.log(i);
}
}
primeSieve();

Find the multiple of n numbers within given range

How can I find the number of multiple for N numbers(as an array input) for a range 1 to K, where 1 < K < 10⁸ and 3 ≤ N < 25.
function findNumberOfMultiples(inputArray, maxSize) {
var count = 0;
var tempArray = [];
for (var i=0; i<maxSize; i++){
tempArray[i] = 0;
}
for (var j=0; j<inputArray.length; j++) {
for (var i=1; i<=maxSize; i++) {
if (i % inputArray[j]) {
tempArray[i-1] = 1;
}
}
}
for (var i=0; i<maxSize; i++) {
if (tempArray[i]==1) {
count++;
}
}
return count;
}
The above program fails for large number K. For example, if inputArray = [2,3,4] and maxSize(k) is 5,
Multiple of 2 is 2,4
Multiple of 3 is 3
multiple of 4 is 4
so total number of mutiple of 2 or 3 or 4 is 3 in range 1 to 5
You can solve this in O(N^2) where N is the number of elements in your array.
let us say you have two element in your array [a1,a2] and the range is K
your answer will be = >
K/a1 + K/a2 - K/lcm(a1,a2) // because you added them in both a1 and a2
So If you have a1,.....ax elements, your answer would be
K/a1+.....K/ax - K/lcm(ai,aj) (you have to replace i,j by (n*n-1)/2 combinations.
You will have to do K/lcm(ai,aj) O(N^2) times ((n*n-1)/2 time to be precise). So the algorithm complexity will be O(N^2) (There will be a Log(min(ai,aj)) factor but that would not make much difference to the overall complexity).
This will work any K as it only depends on your innput array size.
public int combinations(int K, int[] input){
int total = 0;
for(int i=0;i<input.length;i++){
total = total + Math.floor(K/input[i]);
}
for(int i=0;i<input.length;i++){
for(int j=i+1;j<input.length;j++){
if(i!=j){
int lcm =lcmFind(input[i], input[j]);
total = total - Math.floor(K/lcm);
}
}
}
return total;
}
The test case you have provided:
This function seems to do the trick :
var findMultiplesLength = function(arrayInput, max) {
var globalMultiples = [];
for (var j = 0; j < arrayInput.length; j++) {
var x = arrayInput[j];
var n = max / x;
for (var i=1; i < n; i++) {
mult = i * x;
if (globalMultiples.indexOf(mult) === -1) {
globalMultiples.push(mult);
}
}
}
return globalMultiples.length;
};
EDIT : You won't have any stack error but choosing big values for the range may hang your browser.

Categories