Calculating Minimum Lectures required for a target attendance % - javascript

The concept is simple,
Suppose I have attended 3 out of 4 lectures. My current % would be 75%
I want the % above 95. This means I need to attend 16 more classes to make it 19 out of 20 lectures.
This is what I have implemented in JS. I needed to multiply 10 at the end - not sure why the answer was coming 1/10th of the correct answer.
var present=3, absent=1;
var total = present+absent;
var CurrentPercentage = (100*present)/total;
var classReq = (95 * total)/100 - present;
classReq += (95 * classReq)/100;
console.log(classReq>0?(Math.ceil(classReq*10)):0);
It works but I think there must be a better algorithm (I am sure there must be)

Basically you have a count of lecture (20) and a percent value (95%) and visited lecture (3), you could calculate the missing count and subtract the already visited lectures.
var target = 95,
lectures = 20,
visited = 3,
needed = lectures * target / 100 - visited;
console.log(needed);
You could have a look to the missed lectures, then you could calculate the needed lectures.
var target = 95, // percent
visited = 3,
missed = 1, // this is 5%
needed = missed * 100 / (100 - target) - visited;
console.log(needed);

What about:
current=3;
max=4;
if(current/max>0.95){
alert("reached");
}else{
Alert((0.95-current/max)*100+"% needed");
}

Related

Calculate/replicate RSI from Tradingview's pine script

Im trying to recreate Tradingviews pine script RSI code into Javascript code. But having a hard time figuring out how it works. I made the basic RSI using a normal moving average calculation. But the pine script uses exponential weighted moving average. And there documentation is really hard to follow to me. This is the pine script.
//#version=4
study(title="Relative Strength Index", shorttitle="RSI", format=format.price, precision=2, resolution="")
len = input(14, minval=1, title="Length")
src = input(close, "Source", type = input.source)
up = rma(max(change(src), 0), len)
down = rma(-min(change(src), 0), len)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))
plot(rsi, "RSI", color=#7E57C2)
band1 = hline(70, "Upper Band", color=#787B86)
bandm = hline(50, "Middle Band", color=color.new(#787B86, 50))
band0 = hline(30, "Lower Band", color=#787B86)
fill(band1, band0, color=color.rgb(126, 87, 194, 90), title="Background")
This is what I oould make of it in Javascript:
// Period = 200
// Close variable is 200 closed values. Where [0] in array = oldest, [199] in array = newest value.
/**
* Relative strength index. Based on closed periods.
*
* #param {Array} close
* #param {Integer} period
* #returns
*/
function calculateRSI(close, period) {
// Only calculate if it is worth it. First {period - 1} amount of calculations aren't correct anyway.
if (close.length < period) {
return 50;
}
let averageGain = 0;
let averageLoss = 0;
const alpha = 1 / period;
// Exponential weighted moving average.
for (let i = 1; i < period; i++)
{
let change = close[i] - close[i - 1];
if (change >= 0) {
averageGain = alpha * change + (1 - alpha) * averageGain;
} else {
averageLoss = alpha * -change + (1 - alpha) * averageLoss;
}
}
// Tried this too, but seems to not really matter.
// To get an actual average.
// averageGain /= period;
// averageLoss /= period;
// Calculate relative strength index. Where it can only be between 0 and 100.
var rsi = 100 - (100 / (1 + (averageGain / averageLoss)));
return rsi;
}
The results this function gives on my chart is not too bad, but it just isn't the same as I have it in Tradingview. I belive im missing something that the pine script does and I don't.
Things I dont understand of the pine script:
When does it do a for loop? I don't see it in there functions. If they don't, how do they calculate the average for a period of longer than 2? You have to loop for that right?
How does the rma function work? This is their docs.
I might have too many questions on this, but I think if you show a somewhat working example in Javascript of the RSI calculation like they do. Then I can probably make sense of it.
Is my calculation in Javascript correct to the one in the pine script?

How do I write a function to add 7 and substract 2 if it is not already 0

This is what I need to do:
The snail climbs up 7 feet each day and slips back 2 feet each night.
How many days will it take the snail to get out of a well with the given depth?
Sample Input:
31
Sample Output:
6
Explanation: Let's break down the distance the snail covers each day:
Day 1: 7-2=5
Day 2: 5+7-2=10
Day 3: 10+7-2=15
Day 4: 15+7-2=20
Day 5: 20+7-2=25
Day 6: 25+7=32
So, on Day 6 the snail will reach 32 feet and get out of the well at day, without slipping back that night.
This is the code I have written so far:
function main() {
var depth = parseInt(readLine(), 10);
//your code goes here
}
Please help me, I'm like really stuck.
This is a pretty simple question,
function main() {
var depth = parseInt(readLine(), 10);
//your code goes here
i = 0;
for (; depth > 0;) {
i++;
depth -= 7
if (depth > 0) {
depth += 2
}
}
console.log(i);
}
What this code basically does is:
It sets a i variable which is 0, than when the depth is bigger than 0, 1 is post incremented by 1 -which means 1 is added to it- this will count the days it will take. But we must consider the nights as well, as it says, it will not fall down the night if it climbs it all in the day. Thus, we put another + 2 if the -7 doesn't make it 0.
You can read about for loops here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for
I have noticed you're new to stack overflow, so please for the next time you ask, do some coding and research on your own. You mentioned you coded some bits but you just stated a function which is just same as writing nothing and asking for an answer -stack overflow is not your homework solving site!-
In a day and a night, a snail gains a total of 5 feet. The catch here is that this gain is made up of gaining 7 feet, and then slipping back 2. Another way to think about it is that the goal is 2 less than the actual goal, but advances 7-2=5 feet per day.
To formulate this to Javascript, you need to subtract 2 from the distance, divide it by 5, and ceil the result to get the number of days as an integer:
function numDays(distance) {
return Math.ceil((distance - 2) / 5);
}
function main(distance) {
var depth = parseInt(distance);
//your code goes here
var day = 0;
var total = 0;
while(total<depth){
day = day + 1;
total = total + 7;
if(total >= depth){
console.log(day);
break;
}
total = total - 2;
}
}
main(32)
main(51)
This question pretty simple but tricky ;
The depth is already defined which is " var depth = parseInt(readLine(), 10);"
So you don't have to worry declaring depth again depth.
So we need to declare variable for day and total distance at start which is
var day = 0 ; and var total = 0 ; .So here the solution :
function main() {
var depth = parseInt(readLine(), 10); //defining depth
//your code goes here
var day = 0; //defining day
var total = 0; // distance which is at zero
while(total<depth){
day += 1;
total += 7; // if the total distance is less than depth of the well the day is added by one and distance is added by 7
if(total >= depth){
break; // but if the total is equal to or greater than depth the loop will break
}
total -= 2; // 2 is deducted from every step in loop except when the loop is about to ends(where the loop breaks when total=depth).
}
}
function main() {
var depth = parseInt(readLine(), 10);
//your code goes here
var result = depth / 5;
console.log(Math.round(result));
}

How to implement fair division(?) with buffer in javascript?

For the sake of explaining, imagine I have 101 entities. The entities are all people.
In the first entity, it has x amount of "potatoes", I want it to have y potatoes, for now I shall use 950 as an example, intentionally choosing a more awkward number than 1000 for testing.
var personOne = {
...
potatoes: 100
}
I have 100 more of these entities which may have any number of potatoes, but I set a constant buffer that at least 100 for the sake of example again - have to remain with each person.
This means for all of the entities that have over 100, I will be taking some from them - I want this to be shared proportionally across all of them, so that 850 aren't taken from the first two or three, but 10 or 5 taken from all those that are capable of providing such an amount.
Any ideas for an approach?
Optionally: I am using more properties than one "potatoes" property, but I plan on looping through each type and re-using the method that I find to each. I am unsure as to whether this could affect the answer.
Important / Simplified
The one entitiy is pulling "potatoes" from all of the other entities, they are not being distributed evenly across all of them - they are being taken to one entity. I just do not want to do it in a way that is not proportional across all other 100 entities.
This is more taxation than cake-cutting. I am struggling to google for or think of the correct name for the mathematical problem.
Case 1. enough potatoes for everyone to have over 100 of them: put all potatoes together and divide evenly.
Case 2. Not enough potatoes for everyone to have 100. Sum the excess over 100 for those who have + sum all potatoes of those with less than 100, divide the collected potatoes between those with under 100.
(yes, case 2 will imply that some of those under 100 will end with less potatoes than they started. Not fair? Well, maybe you shouldn't protect the 1-percenters that much if there aren't enough potatoes for everybody :) But I digress)
I hope this time i understood the problem. I would calculate the percentage of excess potatoes needed to get the desired amount of potatoes and take that percentage of each participant's excess potatoes, or all if there are not enough total.
Here is some demonstration code to clarify. It is probably overly verbose but should only serve to show the intention anyways. I assumed a very precise potato-cutter is available, as there was no rule specified about what to do about rounding. The outputs are the potatoes of the participants before and after the redistribution. I set NUMBER_OF_PARTICIPANTS to 4 so the output is somewhat readable.
const MAXIMUM_START_POTATOES = 1234;
const MINIMUM_KEPT_POTATOES = 100;
const ENTITY_TAKING_POTATOES = 0;
const DESIRED_POTATOES = 950;
const NUMBER_OF_PARTICIPANTS = 4;
//generate NUMBER_OF_PARTICIPANTS entities with random amount of potatoes
let entities = [];
for (let i = 0; i < NUMBER_OF_PARTICIPANTS; i++) {
entities.push(Math.floor(Math.random() * (MAXIMUM_START_POTATOES + 1)));
}
console.log(entities);
let required_potatoes = DESIRED_POTATOES - entities[ENTITY_TAKING_POTATOES];
if (required_potatoes <= 0) console.log("nothing to do.");
else {
let excess_potatoes = 0;
//Sum excess available potatoes
for (let i = 0; i < NUMBER_OF_PARTICIPANTS; i++) {
if (i === ENTITY_TAKING_POTATOES) continue;
excess_potatoes += Math.max(0, entities[i] - MINIMUM_KEPT_POTATOES);
}
if (excess_potatoes < required_potatoes) {
//just take all excess potatoes
for (let i = 0; i < NUMBER_OF_PARTICIPANTS; i++) {
if (i === ENTITY_TAKING_POTATOES) continue;
entities[i] = Math.min(entities[i], MINIMUM_KEPT_POTATOES);
}
entities[ENTITY_TAKING_POTATOES] += excess_potatoes;
} else {
//calculate percentage of the excess potatoes that is needed
let percentage_required = required_potatoes / excess_potatoes;
//Take that percentage off every participant's excess potatoes
for (let i = 0; i < NUMBER_OF_PARTICIPANTS; i++) {
if (i === ENTITY_TAKING_POTATOES) continue;
entities[i] -= Math.max(0, entities[i] - MINIMUM_KEPT_POTATOES) * percentage_required;
}
//Assume double precision is enough for this to never be an issue
entities[ENTITY_TAKING_POTATOES] = DESIRED_POTATOES;
}
console.log(entities);
}

How to distribute values linearly

I have a total of 10,000 that I want distributed among 99 points, not divided equally but on an increasing linear curve. So while the first point may be worth only [e.g.] 10, each following point would be worth more until the final one is worth [e.g.] 250 or so. But all points need total the 10,000. How could I do that?
// Edit: The first and last values of 10 and 250 are just examples, they could be anything really. The total though (10,000) needs to be variable, so I could change it to 20,000 later if needed.
Take the 99 cells with values [1,2,3,4,..,99] and multiply each number by S/4950 where S is the desired sum (e.g. S=10,000).
Starting at 3, and going up to 199, across 99 points, totaling 10,000. Is this a HW question?
var total = 0;
for (var i = 1; i < 100; i += 1) {
total += i * 2 + 1;
}
alert(total);
This is pretty vague but if the first point has value X and the gap between successive points is Y then the total of 99 such points is
(99 * X) + (0.5 * 99 * 98 * Y)
You can use this formula to play around with a suitable value of X and Y such that your total of 10,000 is satisfied. For example you could fix X first then solve the total for Y but this may not yield an integer result which may make it unsuitable. Unfortunately for certain totals there may not be integer solutions X and Y but your requirements seem rather arbitrary so I am sure you can use the above to arrive at a suitable value of X,Y and the total for your needs. It may serve you until you get a better answer.
I had a similar thing I wanted to do. Even though it is a bit late, perhaps this can help others.
Came up with the following:
var total = 10000;
var len_array = 99;
var points_array = [];
var next_no
var sum_check =0;
for (var i = 0; i < (len_array); i += 1) {
next_no = ((1- i/len_array)/(0.5 * len_array + 0.5)) * total
points_array.push(next_no);
sum_check = sum_check + next_no;
}

Javascript Brainteaser - Reverse Number Determining

Lets say I have a list of numbers in the following form(Ignore the | they are there for formating help).
00|00|xx
00|xx|00
xx|00|00
etc.
Rules: XX can be any number between 1 and 50. No XX values can be identical.
Now I select a random set of numbers(no duplicates) from a list qualifying the above format, and randomly add and subtract them. For example
000011 - 002400 - 230000 = -232389
How can I determine the original numbers and if they were added or subtracted solely from -232389? I'm stumped.
Thanks!
EDIT:
I was looking for a function so I ended up having to make one. Its just a proof of concept function so variables names are ugly http://jsfiddle.net/jPW8A/.
There are bugs in the following implementation, and it fails to work in a dozen of scenarios. Check the selected answer below.
function reverse_add_subtract(num){
var nums = [];
while(num != 0){
var str = num.toString(),
L = Math.abs(num).toString().length,
MA = str.match(/^(-?[0-9]?[0-9])([0-9][0-9])([0-9][0-9])*$/);
if(MA){
var num1 = MA[1],
num2 = MA[2];
}else{
var num1 = num,
num2 = 0;
}
if(L%2)L++;
if( num2 > 50){
if(num < 0) num1--;
else num1++;
}
nums.push(num1);
var add = parseInt(num1 + Array(--L).join(0),10);
num = (num-add);
}
return nums;
}
reverse_add_subtract(-122436);
First note that each xx group is constrained from [1, 50). This implies that each associated pair in the number that is in the range [50, 99) is really 100 - xx and this means that it "borrowed from" the group to the left. (It also means that there is only one set of normalized numbers and one solution, if any.)
So given the input 23|23|89 (the initial xx spots from -232389), normalize it -- that is, starting from the right, if the value is >= 50, get 100 - value and carry the 100 rightward (must balance). Example: (23 * 100) + 89 = 2300 * 89 = 2400 - 11 = 2389. And example that shows that it doesn't matter if it's negative as the only things that change is the signs: (-23 * 100) - 89 = -2300 - 89 = -2400 + 11 = -2389
(Notes: Remember, 1 is added to the 23 group to make it 24: the sign of the groups is not actually considered in this step, the math is just to show an example that it's okay to do! It may be possible to use this step to determine the sign and avoid extra math below, but this solution just tries to find the candidate numbers at this step. If there are any repeats of the number groups after this step then there is no solution; otherwise a solution exists.)
The candidate numbers after the normalization are then 23|24|11 (let's say this is aa|bb|cc, for below). All the xx values are now known and it is just a matter of finding the combination such that e * (aa * 10000) + f * (bb * 100) + g * (cc * 1) = -232389. The values aa, bb, cc are known from above and e, f, and g will be either 1 or -1, respectively.
Solution Warning: A method of finding the addition or subtraction given the determined numbers (determined above) is provided below the horizontal separator. Take a break and reflect on the above sections before deciding if the extra "hints" are required.
This can then be solved by utilizing the fact that all the xx groups are not dependent after the normalization. (At each step, try to make the input number for the next step approach zero.)
Example:
-232389 + (23 * 10000) = -2389 (e is -1 because that undoes the + we just did)
-2389 + (24 * 100) = 11 (likewise, f is -1)
11 - (11 * 1) = 0 (0 = win! g is 1 and solution is (-1 * 23 * 10000) + (-1 * 24 * 100) + (1 * 11 * 1) = -232389)
Happy homeworking.
First, your math is wrong. Your leading zeros are converting the first two numbers to octal. If that is the intent, the rest of this post doesn't exactly apply but may be able to be adapted.
11-2400-230000 = -232389
Now the last number is easy, it's always the first two digits, 23 in this case. Remove that:
-232389 + 230000 = -2389
Your 2nd number is the next 100 below this, -2400 in this case. And your final number is simply:
-2389 + 2400 = 11
Aww! Someone posted an answer saying "brute force it" that I was about to respond to with:
function find(num){for(var i=1;i<50;i++){for(var o1=0;o1<2;o1++){for(var j=1;j<50;j++){for(var o2=0;o2<2;o2++){for(var k=1;k<50;k++){var eq;if(eval(eq=(i+(o1?'+':'-')+j+'00'+(o2?'+':'-')+k+'0000'))==num){ return eq; }}}}}}}
they deleted it... :(
It was going to go in the comment, but here's a cleaner format:
function find(num){
for(var i=1;i<50;i++){
for(var o1=0;o1<2;o1++){
for(var j=1;j<50;j++){
for(var o2=0;o2<2;o2++){
for(var k=1;k<50;k++){
var eq;
if(eval(eq=(i+(o1?'+':'-')+j+'00'+(o2?'+':'-')+k+'0000'))==num){ return eq; }
}
}
}
}
}
}

Categories

Resources