Trying to loop through an array and keep last position remembered - javascript

I have a little assignment I can't manage to complete.
*Goal
You have recently been assigned to a new amusement park’s center of analysis and supervision. Your mission is to estimate each day what the earnings will be for each ride that day. You start by looking at the roller coaster.
Rules
You notice that people like the roller coaster so much that as soon as they have finished a ride, they cannot help but go back for another one.
People queue up in front of the attraction
They can either be alone or in a group. When groups are in the queue, they necessarily want to ride together, without being separated.
People never overtake each other in the queue.
When there isn’t enough space in the attraction for the next group in the queue, the ride starts (so it is not always full).
As soon as the ride is finished, the groups that come out, go back into the queue in the same order.*
var limited_number_of_seats_per_ride = 3, //L
limited_number_of_turns_per_ride = 3, //C
limited_number_of_groups_in_queue = 4, //N
number_of_person_per_group = [3,1,1,2]; //P
function earning_per_day(P,L,C,price){
/**
*
* #P {array} number of person per group.
* #L {int} limited number of seats per ride.
* #C {int} limited number of times the ride goes per day.
* #price {int} price per person per ride.
*
* #daily_earning {int} estimated daily earnings.
*/
var daily_earning = 0;
var total_per_ride = 0;
// calculates sum of the earning for each ride per day
for (var j = 0; j < C; j++) {
total_per_ride = 0;
position_i = 0;
// calculates the number of person on each ride
for (var i = position_i; i < P.length; i++){
while((total_per_ride + P[i+1]) < L){
total_per_ride += P[i];
console.log(i + ' total_per_ride = ' + total_per_ride);
}
position_i = i;
console.log('position_i = ' + position_i);
}
daily_earning += total_per_ride;
console.log('daily_earning ' + daily_earning);
}
}
// calling
earning_per_day(number_of_person_per_group, limited_number_of_seats_per_ride, limited_number_of_turns_per_ride, 1);
This is what I have so far. However, I have an idea I can't manage to put in place. Since the rules state that "that people like the roller coaster so much that as soon as they have finished a ride, they cannot help but go back for another one". I want to save the position of the loop at the moment it ends and restart the loop on that exact same position. Avoiding me to push and shift the element to the last positions of the array.
Can someone please give me a hint on how to proceed ?
Thank you very much !
Ryan

I have updated little of your logic.
For continuously looping over P I have used increment index position_i as position_i = (position_i + 1) % P.length;.
There is no need for inner for (var i = position_i; i < P.length; i++){. Just updated while(){...}.
var limited_number_of_seats_per_ride = 3, //L
limited_number_of_turns_per_ride = 3, //C
limited_number_of_groups_in_queue = 4, //N
number_of_person_per_group = [3, 1, 1, 2]; //P
function earning_per_day(P, L, C, price) {
/**
*
* #P {array} number of person per group.
* #L {int} limited number of seats per ride.
* #C {int} limited number of times the ride goes per day.
* #price {int} price per person per ride.
*
* #daily_earning {int} estimated daily earnings.
*/
var daily_earning = 0;
var position_i = 0;
console.log('---daily_earning : ' + daily_earning + '---');
// calculates sum of the earning for each ride per day
for (var j = 0; j < C; j++) {
console.log('---Ride ' + (j + 1) + '---');
var total_per_ride = 0;
// calculates the number of person on each ride
// for (var i = position_i; i < P.length; i++){
while ((total_per_ride + P[position_i]) <= L) {
total_per_ride += P[position_i];
position_i = (position_i + 1) % P.length;
}
console.log('total_per_ride = ' + total_per_ride);
console.log('New Start position_i = ' + position_i);
// }
daily_earning += total_per_ride;
console.log('daily_earning ' + daily_earning);
}
}
// calling
earning_per_day(number_of_person_per_group, limited_number_of_seats_per_ride, limited_number_of_turns_per_ride, 1);

Related

Array of objects properties become NaN between function calls in Html Javascript

This code is done in HTML javascript.
The following functions (placero() and runro()) are called in that order. placero() seems to initialize the xs and ys of the object list correctly, but by the time the first line of runro() is called, all of the xs and ys have become NaN.
The goal of the code was to make a program that creates rooms and connects them with corridors. Previous steps have inititalized the rooms and corridor layout, but the job of placero() is to place each room somewhere random on the map.
the code is as follows:
runm does all the initial setting code(such as the room member initialization) and does all the other work before placero(). I have been clicking the buttons in the intended order(sequentially), so that shouldnt be the problem.
var roomes = new Array(0);
function randIntBetween(min, max) { // min and max included
return Math.floor(Math.random() * (max - min + 1) + min);
}
//before any function calls, rooms is initialized as follows(well after the input has been entered, in most cases):
roomMax = document.getElementById("inp1").value; //this is the inputted number of rooms being made
for (var k = 0; k < roomMax; k++) {
var obj = {
ind: k,
x: -1,
y: -1,
neighb: Array(0)
}
roomes.push(obj);
}
//then some work is done, placing the indexes of other rooms in the neighbors array in each room.
//none of the in-between code edits x or y.
function placero() {
for (var kis = 0; kis < roomes.length; kis++) {
var x = randIntBetween(5, mapX - 5); //get a random x and y for room position
var y = randIntBetween(5, 5);
roomes[kis].x = x;
roomes[kis].y = y;
}
console.log(roomes); //prints a correct array
}
function runro() {
console.log(roomes); //prints an incorrect array
var iterCount = 2;
//this code aims to place rooms closer to their neighbors, by averaging a rooms position with that of its neighbors and moving it half the way in that direction.
for (var ki = 0; ki < iterCount; ki++) { //for each iteration in which the rooms are moved,
for (var kt = 0; kt < roomes.length; kt++) { //for each room
var coun = NeighbCount(roomes[kt]); //get number of neighbors(will be used for averageing)
console.log(coun);
var sumx = 0;
var sumy = 0;
for (var km = 0; km < coun; km++) { //for each neighbor,
sumx = sumx + roomes[roomes[kt].neighb[km]].x; //add its position to the sum position
sumy = sumy + roomes[roomes[kt].neighb[km]].y;
}
sumx = sumx / coun; //then divide by number of neighbors to get new position
sumy = sumy / coun;
console.log(sumx + " " + roomes[kt].x); //troubleshooting
console.log(sumy + " " + roomes[kt].y);
roomes[kt].x = sumx / 2 + roomes[kt].x / 2; //setting new positions
roomes[kt].y = sumy / 2 + roomes[kt].y / 2;
}
}
}
<div>
<input type="number" id="inp1" name="inp1"><br>
</div>
<button onclick="runm()">Make room map</button>
<button onclick="placero()">place rooms</button>
<button onclick="runro()">Make rooms</button>
You're probably getting the error because roomMax is of string type and not number type. To solve this, make the following modifications to your code:
roomMax = parseInt(document.getElementById("inp1").value);
The value from an input will always be a string. The code above changes the type.
Look through your code to see if you have any similar mistakes.

How Do I Use Loops to Find Sums in Array?

So I need to use a loop to fill an array with the total amount. The total amount will be the amount spent plus a gift card that is a percentage. So
total = amountSpent + amountSpent*(1+giftCard)
I am having trouble getting the total. The spent and gift card amounts are all randomly generated using math.random. The spent and gift card amounts are each found in separate arrays, with the spent amount being anywhere between 0 to 500, and gift card amount being anywhere from 0 to 50.
var spent = new Array(5);
for (var i = 0; i < 5; i++)
{
randS = Math.floor(Math.random() * 500);
spent[i] = randS;
}
var gifts = new Array(5);
for (var i = 0; i < 5; i++)
{
randG= Math.floor(Math.random() * 50);
gifts[i] = randG;
}
These are how I fill the arrays using a for loop. I am now supposed to create a new array and use a loop to calculate the total. I defined 2 variables for spent and gift card amount, but I am unsure if they are calling the correct numbers.
var totals = new Array(5);
var tSpent = spent;
var tGifts = gifts;
for (var i = 0; i < 5; i++)
{
totals[i] = tSpent + (1 + (tGifts / 100)) * tSpent;
totals[i] = totals[i].toFixed(2);
}
I know this array is the problem since the other two arrays are displaying the numbers fine. I also have to convert the gift card amount to a decimal and make sure the total is to 2 decimal places.
you can write the whole code in one loop like this:
var spent=[],gifts=[],totals=[];
for(let i = 0; i < 5; i++){
spent[i] = Math.floor(Math.random() * 500);
gifts[i] = Math.floor(Math.random() * 50);
totals[i] = spent[i] + (1 + gifts[i]/10)*spent[i]
totals[i] = totals[i].toFixed(2);
}
As far as I am able to understand your question, I feel you are doing it correct, just a small correction needs to be done in your code.
var totals = new Array(5);
var tSpent = spent;
var tGifts = gifts;
for (var i = 0; i < 5; i++)
{
totals[i] = tSpent[i] + (1 + (tGifts[i] / 100)) * tSpent[i];
totals[i] = totals[i].toFixed(2);
}
Also, your arrays tSpend and tGifts are calling correct numbers, although they seem redundant, unless you have something planned for them later in code. If not, they are just directly referencing your actual variable spend and gifts.

Split an array into even chunks based on integer in javascript

This might be a duplicate, though I didn't find any questions specific to my problem here.
Say I have an array like this
var hundred = [1,2,3,4,5...100]
This array has 100 elements. From 1 to 100.
Based on an integer, how can I split this array into another array with the same amount of elements, except they've been evenly distributed like this?
var integer = 2;
var hundred = [50,50,50,50,50,50...100,100,100,100,100,100]
In this example, the array has 50 elements with the value 50, and 50 elements with the value 100, because the integer was 2.
I'm bad at math, so this might be incorrect, but I hope you understand what I mean. The array must have the same ammount of indexes after the calculation.
Edit (Due to me being very bad at formulating questions, I'm going to use the code I need this for here):
So I have a frequencybin array (from the AudioContext analyser):
var fbc_array = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(fbc_array);
This array has a set number of elements ( They are the frequencies of audio played ).
Now I have a spectrum analyser, which has a set number of "bars" so if I have only 3 bars, then how can I split the fbc_array so that each bar has the evenly distributed frequency in it? For example, with 3 bars, bar one would have the bass, bar two would have the mids, bar three would have the treble.
I'm using a for loop for iterating over each bar:
for (i = 0; i < bars; i++) {
bar_x = i * canspace;
bar_width = 2;
bar_height = -3 - (fbc_array[i] / 2);
ctx.fillRect(bar_x, canvas.height, bar_width, bar_height);
}
Here's what I gathered from this craziness! Sorry you're having trouble conveying your problem. That's always a headache! Good luck.
//set integer to whatever you want
var integer = 3;
var randomNumber;
var output = new Array()
function getRandomIntInclusive(min, max) {
randomNumber = Math.floor(Math.random() * (max - min + 1)) + min;
}
for(i = 0; i<integer;i++){
getRandomIntInclusive(1,100);
for(j = 1; j< (100/integer); j++){
output.push(randomNumber);
}
}
//note, you will not always get 100 array items
//you can check with console.log(output.length);
console.log(output);
(Written before your update, so guessing here).
You're looking for a way to approximate a graph so that it's divided into bands and each point within a band is replaced with that band's maximum:
Number.prototype.times = function(fn) {
var a = [];
for(var i = 0; i < this; i++)
a.push(fn(i));
return a;
}
function approximate(src, n) {
var res = [],
size = Math.ceil(src.length / n),
i = 0;
while(i < src.length) {
var chunk = src.slice(i, i += size)
var p = Math.max.apply(null, chunk);
// this gives you an average instead of maximum
// p = chunk.reduce((x, y) => x + y) / chunk.length;
res = res.concat(size.times(i => p));
}
return res;
}
src = 20..times(i => 10 + Math.floor(Math.random() * 80));
res = approximate(src, 4);
document.write('<pre>'+JSON.stringify(src));
document.write('<pre>'+JSON.stringify(res));

Cycling through RGB colors in hex

I am creating a color picker type tool using a table. I want to apply a color to each cell in 16 by 16 table. I am having trouble with cycling through colors probably because I'm not sure how to go about it. How should I do this?
Hexagonal
You can use this BaseConverter. Make a loops that writes decimal numbers in 0-255 range with given interval, converts them to hexagonal and create a string containing hex number of three colors with a "#" before them (rgb).
It will work the same way as snippet below but you need to convert numbers additionaly: "rgb(" + (i * interval) + ", " + (j * interval) + ", " + (k * interval) + ")" will be changed to "#" + bin2hex(i * interval) + bin2hex(j * interval) + bin2hex(k * interval).
Decimal with an example
Otherwise just use the other format of CSS Colors which is rgb(red, green, blue) which takes decimal numbers as arguments.
/* Please keep in mind that this function is just an example.
You can modify it to create different palette schemes. */
var tot = 800; /* total amount of blocks */
var num = Math.pow(tot, 1/3); /* amount of blocks in one axis */
var interval = parseInt(255 / num); /* color diff step */
var cont = document.getElementById("container");
var tmp = 0;
for (i = 0; i < num; i++) {
for (j = 0; j < num; j++) {
for (k = 0; k < num; k++) {
/* creates block, add styled class and set color */
var block = document.createElement("div");
block.className = "foo";
block.style.backgroundColor = "rgb(" + (i * interval) + ", " + (j * interval) + ", " + (k * interval) + ")";
cont.appendChild(block);
/* i - red, j - green, k - blue */
tmp++;
}
}
}
.foo {
width: 20px;
height: 20px;
float: left;
}
<!-- It will be populated with JS -->
<div id="container"></div>
If I get the idea of your question wrong then sorry. That's how I would understand "cycle".
The problem you might encounter is that rgb() takes three arguments and you want to create two dimensional array with it. Try looking for rgb palette in google graphics to get the idea how RGB palette may look like and then change the code from above.

How to get a unique random integer in a certain range for every number in that range in javascript?

I have:
function getRandomInt(min, max){
return Math.floor(Math.random() * (max - min + 1)) + min;
}
But the problem is I want randomise the population of something with elements in an array (so they do not appear in the same order every time in the thing I am populating) so I need to ensure the number returned is unique compared to the other numbers so far.
So instead of:
for(var i = 0; i < myArray.length; i++) {
}
I have:
var i;
var count = 0;
while(count < myArray.length){
count++;
i = getRandomInt(0, myArray.length); // TODO ensure value is unique
// do stuff with myArray[i];
}
It looks like rather than independent uniform random numbers you rather want a random permutation of the set {1, 2, 3, ..., N}. I think there's a shuffle method for arrays that will do that for you.
As requested, here's the code example:
function shuffle(array) {
var top = array.length;
while (top--) {
var current = Math.floor(Math.random() * top);
var tmp = array[current];
array[current] = array[top - 1];
array[top - 1] = tmp;
}
return array;
}
Sometimes the best way to randomize something (say a card deck) is to not shuffle it before pulling it out, but to shuffle it as you pull it out.
Say you have:
var i,
endNum = 51,
array = new Array(52);
for(i = 0; i <= endNum; i++) {
array[i] = i;
}
Then you can write a function like this:
function drawNumber() {
// set index to draw from
var swap,
drawIndex = Math.floor(Math.random() * (endNum+ 1));
// swap the values at the drawn index and at the "end" of the deck
swap = array[drawIndex];
array[drawIndex] = array[endNum];
array[endNum] = swap;
endNum--;
}
Since I decrement the end counter the drawn items will be "discarded" at the end of the stack and the randomize function will only treat the items from 0 to end as viable.
This is a common pattern I've used, I may have adopted it into js incorrectly since the last time I used it was for writing a simple card game in c#. In fact I just looked at it and I had int ____ instead of var ____ lol
If i understand well, you want an array of integers but sorted randomly.
A way to do it is described here
First create a rand function :
function randOrd(){
return (Math.round(Math.random())-0.5); }
Then, randomize your array. The following example shows how:
anyArray = new Array('1','2','3','4','5');
anyArray.sort( randOrd );
document.write('Random : ' + anyArray + '<br />';);
Hope that will help,
Regards,
Max
You can pass in a function to the Array.Sort method. If this function returns a value that is randomly above or below zero then your array will be randomly sorted.
myarray.sort(function() {return 0.5 - Math.random()})
should do the trick for you without you having to worry about whether or not every random number is unique.
No loops and very simple.

Categories