repeated sum of digits big o complexity - time-complexity

Lets say for example we have the number 12345.
This sums to 15 when you add 1 + 2 + 3 + 4 + 5, which sums to 6 when you add 1 + 5.
My question is, what would the time complexity be for a repetitive adding algorithm like this be? This process is happens until there is only a single digit left.
I know that for any given number, the # of digits is approximately ln(n). Im thinking that this means that the big o would look something like (ln(n))^k, for some k. However, I am not confident because each time you sum, the number of digits gets smaller (first summed 5 digits, then only 2).
How would I go about figuring this out?

Related

Distribute numbers as close to possible

This seems to be a 2 step problem I'm trying to solve.
Let's say we have N records, and we are trying to distribute as evenly as possible into K groups.
The second problem - each group in K can only accept an M amount of records.
For example, if we have 5 records, and 3 groups, then we would distribute 2 into Group K1, 2 into Group K2 and 1 record into Group K3. However, if say in group 1, it only accepts at most 1 record. Then the arrangement would need to be 1 into Group K1, 2 into Group K2, and 2 into Group K3.
I'm not necessary after the solution but what algorithm I might need to use to solve this? Apparently for the distribution, I need to use the Greedy algorithm? But for the second step, this seems to be a bit more complicated
Edit:
The example I'm looking at is:
Number of records: 23
Groups: 10
Max records for each group
G1 = 4
G2 = 1
G3 = 0
G4 = 5
G5 = 0
G6 = 0
G7 = 2
G8 = 4
G9 = 2
G10 = 2
if N=12 and K=3 then in normal situation,you just split it V=12/3=4 for each group. but since you have M limitation, and for example K3 can only accept 1 then the distribution can be 6-5-1 which is not evenly distributed.
So i guess you need to sort K based on the M limitation, so for the example above the groups order become K3-K1-K2.
then if the distributed value V is bigger than the accepted amount M for that group, you need to take the remainder and distribute it again to the remaining group (K3=1, then 4-1=3 must be distributed to K1 and K2).
the implementation might be complicated, i hope you can find more simple solution for this
From what I understood, you need to separate all groups which allows a fixed number of values first and then equally distribute records among remaining groups. Let's take an example, let's say we have 15 records which needs to be distributed among 5 groups (G1, G2, G3, G4 and G5). Also let's assume that G2 and G4 allows max records of 2 and 4 respectively. Now algorithm should go like this:
Get average(ceiling integer) of records based on number of groups (In this example we'll get 3).
Add all max allowed records which are smaller than our average (In this example it's G2 only who's max limit(i.e. 2) is less than our average hence the number comes as 2).
Now subtract our number from step 2 from total records and also subtract the number of groups involved in step 2 from total groups. (remaining total records: 13, remaining total groups 4).
Get the new average(ceiling integer) using remaining records and groups. (New average 4).
Get average (Integer) (i.e. 3) and allot equal number of records to remaining groups - 1.
Get Mod (i.e. 1) and allot that number to the last group.
Now what we finally will have here:
G1(No limit): 4
G2(Limit 2): 2
G3(No limit): 4
G4(Limit 4): 4
G5(No limit): 1
Let me know if you think that this algo might fail for some scenarios.
Formula to get ceiling integer average
floor((#total_records + #total_groups-1) / #total_groups)

Set outcome of formula to working days

I would like to change the outcome of a SQL statement formula to 1, 2, 3, 4 or 5 (these are working days).
Example 1: when I have day 1, minus 2 days the outcome should be 4.
Example 2: when I have day 4, plus 2 days the outcome should be 1.
Example 3: when I have day 5, minus 20 days, the outcome should be 5
At the moment I'm using a table as shown below (I have the input and days-back and the output is what i want to see):
Input, days-back, output:
1 0 1
Input, days-back, output:
1 1 5
Input, days-back, output:
1 2 4
Input, days-back, output:
2 4 3
P.s. I do not have a date, only day numbers.
I hope you understand what I'm looking for :)
If you want to have "days-back" greater than 5 you need to use the following formula:
((Input + ((5*days-back)-1) - days-back) % 5) + 1
How this works - If you look at the prior formula you can see I'm adding 5 to input to make sure we are always positive before I subtract one and the days back. I then mod by 5 and add the one back in so that we go from 1 to 5 instead of 0 to 4
Since I don't know how large days-back is going to be I need something larger but I also need to have it not effect the mod 5 calculation so I just multiply it by 5. I then subtract one (so I can add it later and offset 0 to 4 to 1 to 5) and we are done.
prior answer below
I note I missed the 5 case -- here is the formula that works for that:
((Input + 4 - days-back) % 5) + 1
original answer
You need to use use modulus math. The formula you want is
(Input + 5 - days-back) % 5
Where % means modulus. In SQL Server you can use % in Oracle it is MOD, etc -- it depends on the platform.
For those that care here is my DB2 test code:
WITH TEST_TABLE(input, days_back) AS
(
VALUES
(1,0),
(1,1),
(1,2),
(2,4)
)
SELECT TEST_TABLE.*
MOD(INPUT+4-DAYS_BACK,5)+1
FROM TEST_TABLE

Generating Even Random Numbers

I need a code to generate only random EVEN numbers 2-100
There is tutorials on the web that generate random numbers but they're odd and even.
Please understand i just need even numbers to generate.
1, generate numbers 1-50
2, multiply all the numbers by 2
all numbers multiplied by 2 are even
This will work:
NSInteger evenNumber = (arc4random_uniform(50) + 1) * 2;
arc4random_uniform(50) will give results in the range 0 - 49. Adding 1 gives a value in the range 1 - 50. Multiplying by two gives you even numbers in the range 2 - 100.

Is there a way to represent a number in binary where bits have approximately uniform significance?

I'm wondering if it is possible to represent a number as a sequence of bits, each having approximately the same significance, such that if we flip one of the bits, the overall value does not change by much.
For example, we can use sequences of 4-bits, where each group represents a value from 0 to 15 and the overall value is the sum of all these values.
0110 0101 1101 1010 1011 → 6 + 5 + 13 + 10 + 11 = 45
and now flipping any bit can only incur in a maximum difference of 8 in the final value.
Some drawbacks obviously exist with this approach:
values have multiple representations, with some values having more representations than other ones (for example, there are 39280 distinct representations for the number 38, and only 1 for the number 0);
the amount of values that can be represented is greatly reduced (this representation allows for integers from 0 to 75, while 20 bits could normally represent 220 ~ 1 million different integers).
Are there any resources I can find concerning this problem? I can't seem to find anything online, but maybe I'm not searching with the right keywords. What other alternatives exist to my approach? Do they improve on its disadvantages?

How to generate sequences with distinct subsums?

I'm looking for a way to generate some (6 for default) equations where all subsums are unique.
For example,
a+b+c=50
d+e+f=50
g+h+i=50
a, d and g have to be distinct.
a+b and d+e have to be distinct.
e+f and h+i have to be distinct.
a+c and d+f have to be distinct.
But, a+b and e+f can be the same. So I only care about the subsums of aligned parameters..
I could only found ways to check whether some sequence is subsum-distinct, but I found nothing on how to generate such a sequence..
You didn't state whether you need it to be a random sequence, so suppose that this is not required.
One simple approach is this:
1 + 2 + 47 = 50
3 + 4 + 43 = 50
5 + 6 + 39 = 50
7 + 8 + 35 = 50
9 + 10 + 31 = 50
11 + 12 + 27 = 50
First two numbers are 2 smallest available numbers, the third number is final sum - those numbers.
a and b are always increasing, c is always decreasing
a + b is always increasing, b + c and a + c are always decreasing
You can generate it this way in a loop.
EDIT after comment that it has to be a random sequence:
Possibly you could create several sets (some sort of hashset/hashmap would be the most appropriate)
set of first summands
set of sums of first and second summands
set of sums of second and third summands
set of sums of first and third summands
set of previously generated triples
You would generate random triples this way:
If total number of demanded triples was not achieved generate a random triple, otherwise finish.
Check if the triple was not previously generated, if not proceed with step 3.
Conduct checks for first four sets. If no sums are contained within those sets, add triple and proceed with step 1.
However, I am not sure if this approach guarantees that you will get results (especially in small final sums).
So, I would add an counter, if too many consecutive attempts are not successful, then I would switch to brute force approach (which should not be problem if final sums are small and on other hand is very unlikely to happen if a final sum is large).
Overall, performance should be good.