Check meter from array of objects - javascript

I have an array of objects like this
var json = [{"price":"30.00","meter":"70"},{"price":"20.00","meter":"130"},{"price":"10.00","meter":"170"}];
How to check qty between this and calculate price. I wrote loop but its not working properly.
var mQty = 2.52;
var jCnt = json.length;
//alert(jCnt);
for (var j = 0; j < jCnt - 1; j++) {
nextj = j + 1;
//alert(nextj;
first = json[j].meter;
if (json[nextj].meter != '') {
second = json[nextj].meter - 1;
} else {
second = '';
}
if (mQty >= first && mQty <= second) {
//bettween meter from json obj
alert('if condition');
alert(json[j].price);
} else {
//under 70 meter
alert('else condition');
alert('40.00');
}
}

I think I understand the problem now. Your prices are per meter prices (I guess) and the more meters of something are ordered, the cheaper the price per meter. You want to find the matching price for a given length.
Since your prices are sorted in ascending order, the logic is pretty simple:
If the quantity/length is less than the required quantity/length of the first entry, use the default price.
Else use the price of the last element that has an equal or smaller quantity/length.
Example:
var price;
if (qty < prices[0].meter) {
price = defaultPrice;
}
else {
for (var i = 1; i <= prices.length; i++) {
price = prices[i - 1].price;
if (prices[i] && prices[i].meter > qty) {
break;
}
}
}
If you add the default price as first element to the array:
var prices = [{price: defaultPrice, meter: 0}, ...];
then you can omit the whole if...else statement:
var price;
for (var i = 1; i <= prices.length; i++) {
price = prices[i - 1].price;
if (prices[i] && prices[i].meter > qty) {
break;
}
}

Related

there are 'X' participants. The participants are to be divided into groups. Each group can have a minimum of 6 and a maximum of 10 participants

there are 'X' participants. The participants are to be divided into groups. Each group can have a minimum of 6 and a maximum of 10 participants. How would you approach this problem, and can you write code for this problem? Optimize for a minimum number of groups. Example: If there are 81 participants, then your program should split them into 9 groups, with each group having 9 participants.
If you have an array with 90 participants and want to create new arrays with a max you could do something like this:
let participants = []
for (let i = 0; i < 90; i++) {
participants.push("Participant" + i)
}
function splitArray(array, newArrayMaxLength) {
var chunks = [], i = 0, n = array.length;
while (i < n) {
chunks.push(array.slice(i, i += newArrayMaxLength));
}
return chunks;
}
console.log(splitArray(participants, 9));
When you call this function, you pass with it an argument stating the max length of the new arrays. If the numbers does not add up, there will only be a difference with one, so ideally you would not have to do anything else, if you span is between 6-10.
Please in the future include your code if you have done any :-)
This is a variation of the classical coin change problem with result as sequence instead of minimum coins required. The base solution is recursive and given below.
function minGroup(groupSize, totalParticipants) {
// Base case
if (totalParticipants == 0) return [];
// Initialize result
let groupArray = -1;
// Try every group that is smaller
// than totalParticipants
for (let i = 0; i < groupSize.length; i++) {
if (groupSize[i] <= totalParticipants) {
let sub_arr = minGroup(groupSize, totalParticipants - groupSize[i]);
// enters if new minGroup less than current or no current solution
if (sub_arr !== -1 && (sub_arr.length + 1 < groupArray.length || groupArray === -1)) {
groupArray = sub_arr.concat([groupSize[i]])
}
}
}
return groupArray
}
The solution can be improved on by Dynamic Programming with tabulation.
function minGroupDp(groupSize, totalParticipants) {
let dpTable = new Array(totalParticipants + 1);
// base case
dpTable[0] = [];
// Initialize all dpTable values as -1
for (let i = 1; i <= totalParticipants; i++) {
dpTable[i] = -1;
}
// Compute minimum groupSize required for all
// totalParticipantss from 1 to V
for (let i = 1; i <= totalParticipants; i++) {
// Go through all groupSize smaller than current total participants
for (let j = 0; j < groupSize.length; j++)
if (groupSize[j] <= i) {
let sub_arr = dpTable[i - groupSize[j]];
// enters if new minGroup less than current or no current solution
if (
sub_arr !== -1 &&
(sub_arr.length + 1 < dpTable[i].length || dpTable[i] === -1)
)
dpTable[i] = sub_arr.concat([groupSize[j]]);
}
}
return dpTable[totalParticipants];
}

Problem with Javascript function not returning total sum in a for loop with if conditions

I am writing pure javascript without any HTML and I am having trouble with one of my functions that would need to return the total "course points."
The program consists of prompting the user the # of course taken followed by the grade received which is pushed in the "grades" array. The function calculateCP will allow it to reiterate every element of the array and is suppose to give me the total course points given the following if conditions.
Please help why my function isn't working! The output is returning only the first element of the array, not the total sum of all elements.
calculateCP = () => {
let coursePoints;
let total = 0;
for (let i = 0; i < grades.length; i++) {
if (grades[i] >= 90) {
coursePoints = 4;
} else if (grades[i] >= 80 && grades[i] < 90) {
coursePoints = 3;
} else if (grades[i] >= 70 && grades[i] < 80) {
coursePoints = 2;
} else if (grades[i] >= 60 && grades[i] < 70) {
coursePoints = 1;
} else if (grades[i] < 60) {
coursePoints = 0;
}
return total = total + coursePoints;
}
}
const grades = [];
let noOfCourses = parseInt(prompt("Please enter # of courses taken: "));
console.log("\n")
for (let i = 0; i < noOfCourses; i++) {
grades.push(prompt('Enter grade recieved '));
}
console.log(calculateCP());
}
In the for loop you just want to sum the values.. only once you're done, return the total :) something like this..
calculateCP = () => {
let coursePoints;
let total = 0;
for (let i = 0; i < grades.length; i++) {
if (grades[i] >= 90) {
coursePoints = 4;
} else if (grades[i] >= 80 && grades[i] < 90) {
coursePoints = 3;
} else if (grades[i] >= 70 && grades[i] < 80) {
coursePoints = 2;
} else if (grades[i] >= 60 && grades[i] < 70) {
coursePoints = 1;
} else if (grades[i] < 60) {
coursePoints = 0;
}
total = total + coursePoints;
}
return total;
}
const grades = [];
let noOfCourses = parseInt(prompt("Please enter # of courses taken: "));
console.log("\n")
for (let i = 0; i < noOfCourses; i++) {
grades.push(prompt('Enter grade recieved '));
}
console.log(calculateCP());
}
try to remove the return statement from the for loop and put it right after it..
change this:
return total = total + coursePoints;
to this:
... for loop
total = total + coursePoints;
}
return total;

Fill an array with distanced random integers

I need an array to be filled with random integers
Those integers should be very distinct from each other i.e. must at least be 20 units of separation between each items
This is what i have tried so far :
var all = [];
var i = 0;
randomDiff();
function randomDiff() {
var num1 = randomNumber(10, 290); //chose a first random num in the range...
all[0] = num1; //...put it in first index of array
do // until you have 12 items...
{
var temp = randomNumber(10, 290); //...you pick a temporary num
var j;
for (j = 0; j < all.length; j++) // for each item already in the array
{
if ((temp < all[i] - 10) || (temp > all[i] + 10)) // if the temporary num is different enough from others members...
{
all.push(temp); //then you can store it
i++; //increment until....
console.log(all[i]);
}
}
}
while (i < 11) // ...it is filled with 12 items in array
}
////////////Radom in int range function///////////////////////////////////////
function randomNumber(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
but always unsuccessful, including infinite loops...
Have a look on something like this:
function randomNumber(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
const LIST_SIZE = 20;
const DISTANCE = 10;
const STOP_AFTER_ATTEMPT = 2000;
const randomList = [];
let attempt = 0;
while(randomList.length < LIST_SIZE && attempt < STOP_AFTER_ATTEMPT) {
const num = randomNumber(10, 290);
const numberExistsWithSmallerDistance = randomList.some(r => Math.abs(r - num) < DISTANCE)
if (!numberExistsWithSmallerDistance) {
randomList.push(num);
}
attempt++;
}
if (randomList.length === LIST_SIZE) {
console.log(randomList);
} else {
console.log("Failed to create array with distnct values after ", attempt, " tries");
}
Here's a solution that will always work, as long as you allow enough room in the range/separation/count you choose. And it's way more efficient than a while loop. It doesn't just keep trying until it gets it right, it actually does the math to make sure it's right the first time.
This comes at the cost of tending to lean towards certain numbers more than others (like from + (i * separation)), so take note of that.
function getSeparatedRadomInts(from, through, separation, count) {
if(through < from) return getSeparatedRadomInts(through, from, separation, count);
if(count == 0) return [];
if(separation == 0) return !!console.log("Please allow enough room in the range/separation/count you choose.");
//pick values from pool of numbers evenly stepped apart by units of separation... adding 1 to from and through if from is 0 so we can divide properly
var smallFrom = Math.ceil((from || 1) / separation);
var smallThrough = Math.floor((through + (from == 0)) / separation);
var picks = randoSequence(smallFrom, smallThrough).slice(-count).sort((a, b) => a - b);
if(picks.length < count) return !!console.log("Please allow enough room in the range/separation/count you choose.");
for (var i = 0; i < picks.length; i++) picks[i] *= separation;
//go through each pick and randomize with any wiggle room between the numbers above/below it... adding 1 to from and through if from is 0
for (var i = 0; i < picks.length; i++) {
var lowerBound = picks[i - 1] + separation || from || 1;
var upperBound = picks[i + 1] - separation || (through + (from == 0));
picks[i] = rando(lowerBound, upperBound);
}
//subtract 1 from all picks in cases where from is 0 to compensate for adding 1 earlier
for (var i = 0; i < picks.length; i++) if(from == 0) picks[i] = picks[i] - 1;
return picks;
}
console.log(getSeparatedRadomInts(10, 290, 20, 12));
<script src="https://randojs.com/1.0.0.js"></script>
To be clear, from is the minimum range value, through is the maximum range value, separation is the minimum each number must be apart from each other (a separation of 20 could result in [10, 30, 50, 70], for example), and count is how many values you want to pick.
I used randojs in this code to simplify the randomness and make it easier to read, so if you want to use this code, just remember to paste this in the head of your HTML document:
<script src="https://randojs.com/1.0.0.js"></script>

JavaScript Function Arrays

How would I use a function that returns the sum of a given array while getting the sum of the even numbers and sum the odd numbers? I'm not understanding how that is done. Can someone please explain a little more in depth?
Here is my entire code:
function main()
{
var evenNum = 0;
//need a total Even count
var oddNum = 0;
//need a total Odd count
var counter = 1;
var num = 0;
function isOdd(x) {
if ((num % 2) == 0)
{
return false;
}
else
{
return true;
}
}
function isEven(x) {
if ((num % 2) == 0)
{
return false;
}
else
{
return true;
}
}
for (counter = 1; counter <= 100; counter++)
{
num = Math.floor(1 + Math.random() * (100-1));
var total = 0;
for(var j = 0; j < length; j++)
total += a[j];//Array?
console.log(num);
console.log("The count of even number is " + evenNum);
console.log("The count of odd number is " + oddNum);
return 0;
}
main()
If I understand your question correctly, you need a function that returns two values, one for the sum of even numbers and one for the sum of odd numbers. It's not clear if you use even/odd referring to the index of the array or the values in array.
In both cases you can return an object that contains both values:
function sum(array) {
var evenSum = 0;
var oddSum = 0;
...calculate...
var res = {};
res.evenSum = evenSum;
res.oddSum = oddSum;
return res;
}
Hope this will help

Find the largest prime factor with Javascript

Thanks for reading. Pretty new to Javascript and programming in general.
I'm looking for a way to return the largest prime factor of a given number. My first instinct was to work with a while loop that counts up and finds prime factors of the number, storing the factors in an array and resetting each time it finds one. This way the last item in the array should be the largest prime factor.
var primerizer = function(input){
var factors = [];
var numStorage = input
for (x=2; numStorage != 1; x++){ // counter stops when the divisor is equal to the last number in the
// array, meaning the input has been fully factorized
if (result === 0) { // check if the number is prime; if it is not prime
factors.push(x); // add the divisor to the array of prime numbers
numStorage = numStorage/x // divide the number being calculated by the divisor
x=2 // reset the divisor to 2 and continue
};
};
primeFactor = factors.pop();
return primeFactor;
}
document.write(primerizer(50))
This only returned 2, undefined, or nothing. My concern was that the stop condition for the for loop must be defined in terms of the same variable as the start condition, so I tried it with a while loop instead.
var primerizer = function(input){
var factors = [];
var numStorage = input
x=2
while (numStorage != 1){
var result = numStorage%x;
if (result === 0) {
factors.push(x);
numStorage = numStorage/x
x=2
}
else {
x = x+1
}
}
return factors.pop();
}
document.write(primerizer(50)
Same problem. Maybe there's a problem with my syntax that I'm overlooking? Any input is much appreciated.
Thank you.
The shortest answer I've found is this:
function largestPrimeFactor(n){
var i=2;
while (i<=n){
if (n%i == 0){
n/=i;
}else{
i++;
}
}
console.log(i);
}
var a = **TYPE YOUR NUMBER HERE**;
largestPrimeFactor(a)
You can try with this
var x = 1, div = 0, primes = [];
while(primes.length != 10001) {
x++;
for(var i = 2; i < x && !div; i++) if(!(x % i)) div++;
if(!div) primes.push(x); else div = 0;
}
console.log(primes[primes.length-1]);
or this: (This solution uses more of your memory)
var dont = [], max = 2000000, primes = [];
for (var i = 2; i <= max; i++) {
if (!dont[i]) {
primes.push(i);
for (var j = i; j <= max; j += i) dont[j] = true;
}
}
console.log(primes);
here is my own solution.
//function
function largestPrimeFactor (num) {
//initialize the variable that will represent the divider
let i = 2;
//initialize the variable that will represent the quotient
let numQuot = num;
//array that will keep all the dividers
let primeFactors = [];
//execute until the quotient is equal to 1
while(numQuot != 1) {
/*check if the division between the number and the divider has no reminder, if yes then do the division keeping the quotient in numQuot, the divider in primeFactors and proceed to restart the divider to 2, if not then increment i by one an check again the condition.*/
if(numQuot % i == 0){
numQuot /= i;
primeFactors.push(i);
i = 2;
} else {
i++;
}
}
/*initialize the variable that will represent the biggest prime factor. biggest is equal to the last position of the array, that is the biggest prime factor (we have to subtract 1 of .length in order to obtain the index of the last item)*/
let biggest = primeFactors[primeFactors.length - 1];
//write the resutl
console.log(biggest);
}
//calling the function
largestPrimeFactor(100);
<script>
function LPrimeFactor() {
var x = function (input) {
var factors = [];
var numStorage = input;
x = 2;
while (numStorage != 1) {
var result = numStorage % x;
if (result === 0) {
factors.push(x);
numStorage = numStorage / x;
x = 2;
}
else {
x = x + 1;
}
}
return factors.pop();
}
document.write(x(50));
}
</script>
<input type="button" onclick="LPrimeFactor();" />
Here is an example i tried with your code
Here is the solution I used that should work in theory... except for one small problem. At a certain size number (which you can change in the code) it crashes the browser due to making it too busy.
https://github.com/gordondavidescu/project-euler/blob/master/problem%203%20(Javascript)
Adding the code inline:
<p id="demo">
</p>
<script>
function isPrime(value) {
for(var i = 2; i < value; i++) {
if(value % i === 0) {
return false;
}
}
return value > 1;
}
function biggestPrime(){
var biggest = 1;
for(var i = 600851470000; i < 600851475143; i++){
if (isPrime(i) != false)
{
biggest = i;
}
document.getElementById("demo").innerHTML = biggest;
}
}
biggestPrime();
</script>
</p>
<script>
//Finds largest prime factor
find = 2165415 ; // Number to test!
var prime = 0;
loop1:
for (i = 2; i < find; i++){
prime = 0;
if (find%i == 0){
document.write(find/i);
for (j = 2; j < (find / i); j++){
if ((find / i )%j == 0){
document.write(" divides by "+j+"<br>");
prime = prime + 1;
break;
}
}
if (prime == 0){
document.write("<br>",find/i, "- Largest Prime Factor")
prime = 1;
break;
}
}
}
if (prime==0)
document.write("No prime factors ",find," is prime!")

Categories

Resources