Mathematical problem help - php

I have some code where, if a user has referred X number of people, he will get X number of credits.
For example, referring 2 people = 1 credit. 4 people = 2 credits, and so on.
However where this gets tricky is, the numbers can be changed so he gets 1 credit per person, or 1 credit per 3 people, 1 credit for 5 people, etc.
If he gets 1 credits for 3 people, and he has referred 5 people, then I would like him to receive 1 credit, and have it stored that he still has 2 people for whom he didn't get any credits. So the next time he refers someone, it is 2 + 1 = 3, and he gets a credit.
My question is,
Given X = Number of people he needs to refer for 1 credit,
and Y = Number of people a user has refered,
(So X might be 3, as in 3 people per credit, and Y might be 6, in which case he should get 2 credits)
1) What's a straightforward formula or function which will X and Y, and return the number of credits which should be given to that person, and
2) Which will also give a remainder for the credits which can't be awarded yet. E.g if X is 3 and Y is 5, the credits would be 1, and remainder would be 2, so with the next referer Y will become 3 again and the user would get 1 credit?

1.)
creditsToPayout = Y/X; //use integer division to truncate, or floor result
remainderReferrals = Y % X; //remainder of Y / X, leftover referrals

You need integer division and modulus. For PHP see here for :
- intval($a / $b)
- $a % $b

If the number can change over time, what happens if, say, intially it is 3 people per credit. He refers 7 people and gets 2 credits with 1 person left over. Then the rule is changed to 4 people per credit. Under that rule he would only get 1 credit with 3 people left over. Do you take a credit back? I'm guessing not, that the new rule only applies to new credits. So I think you need to keep on your database or whatever, the number of credits received, and the number of referrals left that was not sufficient to make a credit. The number of un-credited referrals would then go up and down over time, as he makes new referrals and as they are "exchanged" for credits.
Frankly I think it would be simpler if you could make the rule be X credits per referral rather than X referrals per credit, and then just increase the cost of whatever it is you buy with the credits. Like, if the rule is 1 credit for 5 referrals, and when you get 10 credits you get a free iPod or whatever, then you need 50 referrals to get an iPod. So change it to 1 credit per referral and it takes 50 credits to get an iPod. Then you'd never have to deal with the fractions. But maybe you're not making up the rules and this is all irrelevant.

Number of credits = FLOOR(Y/X)
Remainder = Y-(X*FLOOR(Y/X))

Related

Revert a number to its original value in PHP

I have a problem in reverting the original amount of a customer.
A customer can amortize its balance in 3 months.
So, if the balance is 1,100.00
1,100.00 / 3 = 366.666666667 rounded up to 366.67
But then, he decided to cancel the amortization.
What I do is amortized amount * 3, which is:
366.67 * 3 = 1,100.01
Expected output should be 1,100.00
Thanks!
Your problem here is the original calculation, if you have 1,100.00 to pay and simply divide by 3 with rounding, your customer will actually pay 1,100.01!
The usual solution is to compensate this difference in the last (or first) amount to pay:
n-1 first payments: total / n -> for your example: 2 times 366.67
last payment: total - sum of precedent payments -> for your example: 1,100.00 - (2 * 366.67) so 366.66 to pay
Like this the total paid will always be right, whatever you apply flooring or rounding, and you can reverse any time by adding each value.
Save the original value 1,100.00 somewhere (database, variable, etc.) and when they cancel their amortization, set the display from the saved value instead of calculating it.

Calculate commision based on level completeness of a binary tree

I have 2 tables.
Business Plans
Users Binary
Right now, if you see users_binary, The following hierarchy is being developed.
1
/ \
3 4
/ \ / \
19 33 18 32
I want to calculate commission based of completeness of level. I has 2 childs. Its first level is complete. Now User 1 is on PLAN 1. Plan 1's right and left points are 20 and commission percentage is 4.5. It's first level is complete. It will get ((20+20)*4.5%) commission. When 3 and 4 also completes their 1st levels, user 1 will get ((20+20+20+20)*4.5%) commission. Just 1 thing to note. In query, we will note that the commission being calculated is from this Monday to Saturday and point_status should be equal to N.
This is my getBasicTree function.
function getBasicTree($user_id)
{
$query="select user_id,first_name,last_name,leg from users
where introducer_id = '".$user_id."'
and leg != ''";
if(($data=$this->CustomQuery($query))!=null)
{
return $data;
}
return 0;
}
Anyone willing to help me out understanding the logic how it will be done. I am unable to understand recursion and make a logic for it.

Generate a single elimination tournament

first , sorry for my english I'll do my best to explain my problem !
So , i'm trying to generate a single elimination tournament with an unlimited number of players.
for now i'm just thinking about it , i have nothing on paper , i think i will not have problem for tournament with power of two ( 2 4 8 16 32 players..) , my brain hangs on players going directly to round 2 , i don't know how to determine this number and where to place them.
eg (with 59 players)
I think there is a formula but I can't find it, I have some ideas but i think too specifically on a case, without knowing if it would work for another .
Thank you if you can help me !
For a given number N, find the difference between it and the smallest power of 2 at least as large as N. For 59, that'll be 5 (64 - 59). Those 5 players will be added to the tournament schedule at the second round.
This algorithm allows for all the players to be part of the game when the second round begins - i.e., as early as possible. Its explanation is very simple: imagine that originally there were 2**N players - but some just didn't come to their games, so their opponents went further without a fight. )
As a sidenote, your formula should take into account that it's strongest players that should enter the game from the second round, not the weakest ones. )
The first step apparently is calculating the number of players that will participate in the first round. Now, let's continue that 'missing players' metaphor - let's say there were 64 players originally, so the first round should have 32 games played. But 5 players (64 - 59) didn't come for those games - so the number of real games is 27 ( 64/2 - 5 ), and the number of real participants of the first round is 54 (27 * 2).
After the first round, there'll be 27 people left in the tournament - those people will be joined by those other 5 guys, so the total number of the 2nd round players is 32. The rest is trivial, I suppose. )
Actually, this is easy to commonize. Let's say we have N players, and the smallest power of 2 at least as large as N is P. Now...
The first round should have (N - (P - N)) (or just (2*N - P)) players.
The total number of the games in the first round is (N - P/2).
Apparently, the same is the number of players going into the 2nd round.
These will be joined by (P - N) players left without a play in the 1st round,
so the total number of players in the 2nd round will be...
N - P/2 + P - N => P - P/2 => P/2
... and from now you just go with the direct schedule of 2^N players (as P/2, as well as P, is the power of 2).
ooh thank you #raina77ow , you blew my mind , So here are my calculations:
64/2 = 32
59/2 = 29 ( rounded to the lower ) => nb of total player at left ( round 1 & 2)
32-29 = 3 => nb players at left going to round 2
29-3 = 26 => nb players at left going to round 1
59-29 = 30 => nb total players at right ( round 1 & 2 )
5-3 = 2 => nb players going to round 2 at right
30-2 = 28 = nb players round 1
`
I think I can make an algorithm now if that's right for each case.

Scoring algorithm user/actions

I'm looking for a scoring algorithm but I really don't find what I'm looking for.
Let's imagine an application in which an user can post reviews, can vote on articles or create reviews, like or dislike reviews/articles. The goal is to rank user depending on their activity.
The system himself might grow like a neperian logarithm or something, so the more points you have the more difficulty you have to get more points. Also a newbie must have a voice against a very experienced user, but his voice is less important.
I'm thinking about:
Each action has a base value.
An user has an amount of points, which determines his weight.
His amount of points determine his level and so the set of actions he can perform.
When a user performs an action his weight affect the base value of the action, and his amount of points increase so his weight also.
Does this sound correct ? And Do you know some algorithms/examples of code implementing this kind of thing ? Thanks
PS : I also mean which function should I take has weight ?
How about something like this:
Each action has base value at least 100 points (but not more than 1000).
User starts with 100 points
And if user that has X points in total performs action with value base Y you give him 10 * Y / log2(log2(X)) extra points.
So after performing consecutively actions with 100 base value, user recives:
360 points (460 total points)
317 points (777 total points)
306 points (1083 total points)
and so on

Adding an extra factor (number of clicks) to a Bayesian ranking system

I run a music website for amateur musicians where we have a rating system based on a score out of 10, which is then calculated into an overall score out of 100. We have a "credibility" points system for users which directly influences the average score at the point of rating, but the next step is to implement a chart system which uses this data effectively.
I'll try and explain exactly how it all works so you can see which data I have at my disposal.
A site member rates a track between 1 and 10.
That site member has a "credibility" score, which is just a total of points accumulated for various activities around the site. A user gains, for example, 100 points for giving a rating so the more ratings they give, the higher their "credibility" score. Only the total credibility score is saved in the database, updated each time a user performs an activity with a points reward attached. These individual activities are not stored.
Based on the credibility of this user compared to other users who have rated the track, a weighted average is calculated for the track, which is then stored as a number between 1 and 100 in the tracks table.
In the tracks table, the number of times a track is listened to (i.e. number of plays) is also stored as a total.
So the data I have to work with is:
Overall rating for the track (number between 1 and 100)
Number of ratings for the track
Number of plays for the track
In the chart system I want to create a ranking that uses the above 3 sets of data to create a fair balance between quality (overall rating, normalized with number of ratings) and popularity (number of plays). BUT the system should factor quality more heavily than popularity, so for example the quality aspect makes up 75% of the normalized ranking and popularity 25%.
After a search on this site I found the IMDB Bayesian-style system which is helpful for working out the quality aspect, but how do I add in the popularity (number of plays) and have it balanced in the way I want?
The site is written in PHP and MySQL if that helps.
EDIT: the title says "number of clicks" but this is basically the direct equivalent of "number of plays".
You may want to try the following. The IMDB equation you mentioned uses weighing to lean toward either the average rating of the movie or the average rating of all movies:
WR = (v/(v+m)) × R + (m/(v+m)) × C
So
v << m => v/(v+m) -> 0; m/(v+m) -> 1 => WR -> C
and
v >> m => v/(v+m) -> 1; m/(v+m) -> 0 => WR -> R
This should generally be fair. Calculating a popularity score between 0 and 100 based on the number of plays is pretty tricky unless you really know your data. As a first try calculate the average number of plays avg(p) and the variance var(p) you can then use these to scale the number of plays using a technique call whitening:
WHITE(P) = (p - avg(p))/var(p)
This will give you a score between -1 and 1 by assuming your data looks like a bell curve. You can then scale this to be in the range 0 - 100 by scaling again:
POP = 50 * (1 + WHITE(P))
To combine the score based on some weighting factor w (e.g. 0.75) you'd simply do:
RATING = w x WR + (1 - w) x POP
Play with these and let me know how you get on.
NOTE: this does not account for the fact that a use can "game" the popularity buy playing a track many times. You could get around this by penalising multiple plays of a single song:
deltaP = (1 - (Puser - 1)/TPuser)
Where:
deltaP = Change in # plays
Puser = number of time this user has played this track
TPuser = total number of tracks (not unique) played by the user
So the more times a user plays just the one track the less it counts toward the total number of plays for that track. If the users listening habits are diverse then TPuser will be large and so deltaP will tend back to 1. This still can be gamed but is a good start.

Categories