Page 1 of 2

[Solved] Looking for a function for factor based number series thingy, whatever its called.

Posted: Thu Aug 10, 2017 12:16 pm
by BorhilIan
Solution

Lets say i have a max of 100, what i want is to define an exponent and get a proper series of numbers.
For example something like..

Code: Select all

local series = expNumberThingy(100, 4)
which would return a table like this {5, 15, 30, 50}

The numbers need to be whole and add up to the target number. Unfortunately I don't know the terminology associated with what I'm looking for.

I'm working on a tiny game I'll probably post here, don't expect graphics other than dots and lines. (It's a test of sorts for a bigger project of mine)

Re: Looking for an equation that exponentially increases to a max number.

Posted: Thu Aug 10, 2017 12:51 pm
by MasterLee
Your equation is an square one not exponential
5/2*(n²+n)

Re: Looking for an equation that exponentially increases to a max number.

Posted: Thu Aug 10, 2017 1:19 pm
by BorhilIan
So where do I put my two numbers in your equation? Seems it only takes a single number.
I release its just 5 + 10 + 15 + 20 in my example, basically i want to get '5' but for a divisor which in my example is four.

Re: Looking for an equation that exponentially increases to a max number.

Posted: Thu Aug 10, 2017 3:02 pm
by zorg
My math is kinda bad but here's my thought process:

Your constraints are the following;
- Results must be whole numbers,
- Results must fit a specific slope/curve defined by a function (probably scaled as well),
- The count of numbers returned on the curve is given,
- The results must sum up to a given number.

Now do realize that depending on the curve of your function, and the number of elements you divide it up to, you might not get back perfectly fitting numbers, that are integers, for the sole reason that a solution such as that may not exist; that said, in that case, you probably want the algorithm to cheat, as in, round a few results, and then adjust others so the numbers will sum up to your desired value.

1. X axis goes from 0 to sumValue (your first parameter)
2. divide up X axis by resultCount (your second parameter); for now, the distances between each point is linear, i.e. they're the same; this is fine. (You don't need the last point which is exactly equal to sumValue on the X axis)
3. apply your function to the values you got from the specific points on the X axis, hence getting values you can map onto the Y axis.
4. now even though the sum of the current values may be smaller/larger than what you want, you need to scale the values equally:
5. add up the resultCount values you got, then put that sum, divided by sumValue, into a variable; that will be your scaling constant.
6. scale all the results you got with said constant.
7. floor/ceil them so you get whole numbers; do keep track of whether you need to add or subtract one whenever, so that the sum stays correct.
8. return the values.

I haven't tested the above pseudocode, but hopefully with a few tweaks, it might do what you want it to; though i'd experiment with different functions, with different slopes, maybe you'll find one that fits your needs.

Also, just to explain it, MasterLee's answer is what WolframAlpha barfs out if you give it your initial number series; that's where that generator function comes from.

Re: Looking for an equation that exponentially increases to a max number.

Posted: Thu Aug 10, 2017 3:10 pm
by BorhilIan
Good post zorg, you nailed what I'm after. As for the method you posted it gives me a few ideas, I'll post what I wind up with shortly.

Re: Looking for an equation that exponentially increases to a max number.

Posted: Thu Aug 10, 2017 3:51 pm
by BorhilIan
Got it, finally the math made some sense to me. Here it is in all its glory. :P

So here's how to use it, first 'number' is the total number you want the values to add up to. Second 'series' is how many numbers you want the function to return. Third is the 'factor' which adjust how quickly it will reach that number (The curve).

Code: Select all

--	Returns a 'series' of numbers that when added together will equal 'number'.
--	Will use 'factor' to scale the growth between each element in the 'series'.
function seriesNumber( number, series, factor )
	local temp = {}
	for x = 1, series do
		for y = 1, number do
			if ( y / number <= ( x / series ) ^ factor ) then
				temp[ x ] = y
			end
		end
	end
	local out = {}
	for x, y in pairs( temp ) do
		out[ x ] = ( y - ( temp[ x - 1 ] or 0 ) )
	end
	return out
end
Here are some examples of using the above function, give it a whirl.

Code: Select all

--	First example using a small number and series with a large factor.
local series = seriesNumber( 100, 5 , 5 )
local total = 0
print( "series-1:" )
for x, y in pairs( series ) do
	total = total + y
	print( "", x, y, total )
end
print( "total-1:", total )
print()

--	Second example using a larg number and short series with a moderate factor.
local series = seriesNumber( 5000, 7 , 3 )
local total = 0
print( "series-2:" )
for x, y in pairs( series ) do
	total = total + y
	print( "", x, y, total )
end
print( "total-2:", total )
print()

--	Third example using a tiny number and moderate series with a tiny factor.
local series = seriesNumber( 7, 15 , 0.5 )
local total = 0
print( "series-3:" )
for x, y in pairs( series ) do
	total = total + y
	print( "", x, y, total )
end
print( "total-3:", total )

Re: Looking for an equation that exponentially increases to a max number.

Posted: Thu Aug 10, 2017 3:51 pm
by Nelvin
Hi there, Newbie here (actually my first post) I'm just toying around with Love a bit.

Here's some code which might do what you want?

It simply distributes the values along a squared function. The integer scaling is done in a simple 2 pass calc - I first sum up the normalized (0-1) values and use that sum to scale to the appropriate integers in the second pass.
It tracks the remainding value in the second pass so the last value fixes any accumulated rounding errors due to float->int conversions.

Code: Select all

local expSquared = function( val )
    return val*val
end

local expCubed = function( val )
    return val*val*val
end

local genTable = function( steps, scale, expFunc )

    local fullRange = 0
    for i = 1, steps do
        local x = i/steps
        fullRange = fullRange + expFunc(x)
    end

    local results = {}
    local remainder = scale
    for i = 1, steps-1 do
        local x = i/steps
        local scaled = math.floor((expFunc(x)*scale)/fullRange)
        results[#results+1] = scaled
        remainder = remainder - scaled
    end

    results[#results+1] = remainder
    return results
end

local squaredTab = genTable( 4, 100, expSquared )

Re: [Solved] Looking for an equation that exponentially increases to a max number.

Posted: Thu Aug 10, 2017 4:03 pm
by BorhilIan
Howdy there Nelvin I finished my solution above. Tested yours and it does indeed work to. :3

Re: [Solved] Looking for an equation that exponentially increases to a max number.

Posted: Thu Aug 10, 2017 5:24 pm
by Nelvin
Ah posted at the very same minute :)

Have fun ...

Re: Looking for an equation that exponentially increases to a max number.

Posted: Fri Aug 11, 2017 9:00 am
by MasterLee
BorhilIan wrote: Thu Aug 10, 2017 1:19 pm So where do I put my two numbers in your equation? Seems it only takes a single number.
I release its just 5 + 10 + 15 + 20 in my example, basically i want to get '5' but for a divisor which in my example is four.
5/2*(n²+n)
gives for n=1:
5/2*(1²+1)=5/2*(1+1)=5/2*2=5
for n=2
5/2*(2²+2)=5/2*(4+2)=5/2*6=15
for n=3
5/2*(3²+3)=5/2*(9+3)=5/2*12=30
for n=4
5/2*(4²+4)=5/2*(16+4)=5/2*20=50
so you calculated wrong
and i did not want make an solution before i clear the problem about your question. You asked for an exponential increase but you example series has square increase. Then all solutions showed here only make square, cubic or polynomial like increase. So there is no solution with has exponential increase. That would be the case if you have something like factor^n and not n^factor.