Change a pseudo-code such that we get rid of a loop - algorithm

I have the following pseudo-code:
read n
p <- 1;
m <- 0;
k <- 0;
while ( n != 0 )
read x
for ( i <- 1, k )
x <- [x / 10]
if ( x != 0 )
c <- x % 10
else
c <- n % 10
m <- c * p + m
n <- [n / 10]
p <- p * 10
k <- k + 1
write m
and I have to transform this code such that we have just 1 loop. I went over examples over and over again and I don't see what I should do. I think we need that first while loop so I kept trying to get rid of that for loop function but I don't see how I could get the same behavior with just one loop.
(Excuse the terrible style of pseudo-code)

If you are talking about the
for ( i <- 1, k )
x <- [x / 10]
loop, it divides x by 10 ** k, and
x <- [x / 10**k]
accomplishes exactly what the loop does. If you have a feeling that raising to a power is a loop in disguise, consider
power_of_ten = 1
while ( n != 0 )
read x
x <- [x / power_of_ten]
....
power_of_ten <- power_of_ten * 10

Related

How to find the count of numbers which are divisible by 7?

Given an integer N, how to efficiently find the count of numbers which are divisible by 7 (their reverse should also be divisible by 7) in the range:
[0, 10^N - 1]
Example:
For N=2, answer:
4 {0, 7, 70, 77}
[All numbers from 0 to 99 which are divisible by 7 (also their reverse is divisible)]
My approach, simple brute-force:
initialize count to zero
run a loop from i=0 till end
if a(i) % 7 == 0 && reverse(a(i)) % 7 == 0, then we increase the count
Note:
reverse(123) = 321, reverse(1200) = 21, for example!
Let's see what happens mod 7 when we add a digit, d, to a prefix, abc.
10 * abc + d =>
(10 mod 7 * abc mod 7) mod 7 + d mod 7
reversed number:
abc + d * 10^(length(prefix) =>
abc mod 7 + (d mod 7 * 10^3 mod 7) mod 7
Note is that we only need the count of prefixes of abc mod 7 for each such remainder, not the actual prefixes.
Let COUNTS(n,f,r) be the number of n-digit numbers such that n%7 = f and REVERSE(n)%7 = r
The counts are easy to calculate for n=1:
COUNTS(1,f,r) = 0 when f!=r, since a 1-digit number is the same as its reverse.
COUNTS(1,x,x) = 1 when x >= 3, and
COUNTS(1,x,x) = 2 when x < 3, since 7%3=0, 8%3=1, and 9%3=2
The counts for other lengths can be figured out by calculating what happens when you add each digit from 0 to 9 to the numbers characterized by the previous counts.
At the end, COUNTS(N,0,0) is the answer you are looking for.
In python, for example, it looks like this:
def getModCounts(len):
counts=[[0]*7 for i in range(0,7)]
if len<1:
return counts
if len<2:
counts[0][0] = counts[1][1] = counts[2][2] = 2
counts[3][3] = counts[4][4] = counts[5][5] = counts[6][6] = 1
return counts
prevCounts = getModCounts(len-1)
for f in range(0,7):
for r in range(0,7):
c = prevCounts[f][r]
rplace=(10**(len-1))%7
for newdigit in range(0,10):
newf=(f*10 + newdigit)%7
newr=(r + newdigit*rplace)%7
counts[newf][newr]+=c
return counts
def numFwdAndRevDivisible(len):
return getModCounts(len)[0][0]
#TEST
for i in range(0,20):
print("{0} -> {1}".format(i, numFwdAndRevDivisible(i)))
See if it gives the answers you're expecting. If not, maybe there's a bug I need to fix:
0 -> 0
1 -> 2
2 -> 4
3 -> 22
4 -> 206
5 -> 2113
6 -> 20728
7 -> 205438
8 -> 2043640
9 -> 20411101
10 -> 204084732
11 -> 2040990205
12 -> 20408959192
13 -> 204085028987
14 -> 2040823461232
15 -> 20408170697950
16 -> 204081640379568
17 -> 2040816769367351
18 -> 20408165293673530
19 -> 204081641308734748
This is a pretty good answer when counting up to N is reasonable -- way better than brute force, which counts up to 10^N.
For very long lengths like N=10^18 (you would probably be asked for a the count mod 1000000007 or something), there is a next-level answer.
Note that there is a linear relationship between the counts for length n and the counts for length n+1, and that this relationship can be represented by a 49x49 matrix. You can exponentiate this matrix to the Nth power using exponentiation by squaring in O(log N) matrix multiplications, and then just multiply by the single digit counts to get the length N counts.
There is a recursive solution using digit dp technique for any digits.
long long call(int pos , int Mod ,int revMod){
if(pos == len ){
if(!Mod && !revMod)return 1;
return 0;
}
if(dp[pos][Mod][revMod] != -1 )return dp[pos][Mod][revMod] ;
long long res =0;
for(int i= 0; i<= 9; i++ ){
int revValue =(base[pos]*i + revMod)%7;
int curValue = (Mod*10 + i)%7;
res += call(pos+1, curValue,revValue) ;
}
return dp[pos][Mod][revMod] = res ;
}

Is there any way of optimizing a multiplication loop?

Let's say I have to repeat the process of multiplying a variable by a constant and modulus the result by another constant, n times to get my desired result.
the obvious solution is iterating n times, but it's getting time consuming the greater n is.
Code example:
const N = 1000000;
const A = 123;
const B = 456;
var c = 789;
for (var i = 0; i < n; i++)
{
c = (c * a) % b;
}
log("Total: " + c);
Is there any algebraic solution to optimize this loop?
% has two useful properties:
1) (x % b) % b = x % b
2) (c*a) % b = ((c%b) * (a%b))%b
This implies that e.g.
(((c*a)%b)*a) % b = ((((c*a)%b)%b) * (a%b)) % b
= (((c*a) % b) * (a%b)) % b
= (c*a*a) % b
= (c*a^2) % b
Hence, in your case the final c that you compute is equivalent to
(c*a^n)%b
This can be computed efficiently using exponentiation by squaring.
To illustrate this equivalence:
def f(a,b,c,n):
for i in range(n):
c = (c*a)%b
return c
def g(a,b,c,n):
return (c*pow(a,n,b)) % b
a = 123
b = 456
c = 789
n = 10**6
print(f(a,b,c,n),g(a,b,c,n)) #prints 261, 261
First, note that c * A^n is never an exact multiple of B = 456 since the former is always odd and the latter is always even. You can generalize this by considering the prime factorizations of the numbers involved and see that no repetition of the factors of c and A will ever give you something that contains all the factors of B. This means c will never turn into 0 as a result of the iterated multiplication.
There are only 456 possible values for c * a mod B = 456; therefore, if you iterate the loop 456 times, you will see at least value of c repeated. Suppose the first value of c that repeats is c', when i= i'. Say it first saw c' when i=i''. By continuing to iterate the multiplication, we would expect to see c' again:
we saw it at i''
we saw it at i'
we should see it at i' + (i' - i'')
we should see it at i' + k(i' - i'') as well
Once you detect a repeat you know that pattern is going to repeat forever. Therefore, you can compute how many patterns are needed to get to N, and the offset in the repeating pattern that you'd be at for i = N - 1, and then you'd know the answer without actually performing the multiplications.
A simpler example:
A = 2
B = 3
C = 5
c[0] = 5
c[1] = 5 * 2 % 3 = 1
c[2] = 1 * 2 % 3 = 2
c[3] = 2 * 2 % 3 = 1 <= duplicate
i' = 3
i'' = 1
repeating pattern: 1, 2, 1
c[1+3k] = 1
c[2+3k] = 2
c[3+3k] = 1
10,000 = 1 + 3k for k = 3,333
c[10,000] = 1
c[10,001] = 2
c[10,002] = 1

Best Algorithm to distribute n elements to x groups

What is the best way to distribute n items (say 2 up to 100) into x groups.
Each group should have about the same amount of items in it.
Easy example would be n=100; x=2;
100/2 = 50 items per group
What if we've got floating numbers involved, like n=100; x=3;
100/3 = 33.33
We would need two groups nesting 33 items and one group nesting 34.
Another example: n=8; x=3
8/3 = 2.66
Any suggestions on how to tackle this?
Not that it matters, but just for curious minds, the usecase:
In my UI im trying to divide tabstripes into multiple rows, only showing one row at a time, so that if all the tabstripes don't fit into one row we can distribute them programmatically.
Looking forward to your answers!
After distributing floor(n / x) items over x groups you're left with n mod x = n - floor(n / x) * x items, that's a value in [0, x). You can easily add 1 to each group i=1..x with i <= n mod x.
for i=1..x
group[i] <- floor(n / x) + (i <= n mod x ? 1 : 0)
this is the same as
for i=1..(n mod x)
group[i] <- ceil(n / x)
for i=(n mod x + 1)..x
group[i] <- floor(n / x)
E.g. n = 11, x = 3 you'll end up with:
group[1] <- 3 + (1 <= 2 ? 1 : 0) = 4
group[2] <- 3 + (2 <= 2 ? 1 : 0) = 4
group[3] <- 3 + (3 <= 2 ? 1 : 0) = 3
Assuming that your groups are in some form of arrays indexed from 0 with 'groupCount' groups, a simple distribution "by rows" would be something like:
g = 0
for each element e
allocate e to group groups[g]
g++
g = (g % groupCount)
If the allocation to a group one element at a time is too slow, it can be faster to allocate 'by columns'. Assuming that the counters 'remainingElements' and 'remainingGroups' are initialized appropriately, it would look like:
for each group g
size = floor(remainingElements / remainingGroups)
allocate size elements to group g
remainingElements = remainingElements - size
--remainingGroups

Trying to create an efficient algorithm for a function in Haskell

I'm looking for an efficient polynomial-time solution to the following problem:
Implement a recursive function node x y for calculating the (x,y)-th number in a number triangle defined as
g(x,y) = 0 if |x| > y
= 1 if (x,y) = (0,0)
= sum of all incoming paths otherwise
The sum of all incoming paths to a node is defined as the sum of the values of all possible paths from the root node (x, y) = (0, 0) to the node under consideration, where at each node (x,y) a path can either continue diagonally down and left (x−1,y+1), straight down (x,y+1), or diagonally down and right (x+1,y+1). The value of a path to a node is defined as the sum of all the nodes along that path up to, but not including, the node under consideration.
The first few entries in the number triangle are given in the table:
\ x -3 -2 -1 0 1 2 3
\
y \ _________________________
|
0 | 0 0 0 1 0 0 0
|
1 | 0 0 1 1 1 0 0
|
2 | 0 2 4 6 4 2 0
|
3 | 4 16 40 48 40 16 4
I am trying to work out a naive solution first, here is what I have:
node x y | y < 0 = error "number cannot be negative"
| (abs x) > y = 0
| (x == 0) && (y == 0) = 1
| otherwise = node (x+1) (y-1) + node x (y-1) + node (x-1) (y-1)
Whenever I run this I get:
"* Exception: stack overflow"?
I believe your problem is a bit more complicated than your example code suggests. First, let's be clear about some definitions here:
Let pathCount x y be the number of paths that end at (x, y). We have
pathCount :: Int -> Int -> Integer
pathCount x y
| y == 0 = if x == 0 then 1 else 0
| otherwise = sum [ pathCount (x + d) (y - 1) | d <- [-1..1]]
Now let's pathSum x y be the sum of all paths that end in (x, y). We have:
pathSum :: Int -> Int -> Integer
pathSum x y
| y == 0 = if x == 0 then 1 else 0
| otherwise = sum [ pathSum (x + d) (y - 1) + node x y * pathCount (x + d) (y - 1)
| d <- [-1..1] ]
With this helper, we can finally define node x y properly:
node :: Int -> Int -> Integer
node x y
| y == 0 = if x == 0 then 1 else 0
| otherwise = sum [ pathSum (x + d) (y - 1) | d <- [-1..1]]
This algorithm as such is exponential time in its current form. We can however add memoization to make the number of additions quadratic. The memoize package on Hackage makes this easy as pie. Full example:
import Control.Monad
import Data.List (intercalate)
import Data.Function.Memoize (memoize2)
node' :: Int -> Int -> Integer
node' x y
| y == 0 = if x == 0 then 1 else 0
| otherwise = sum [ pathSum (x + d) (y - 1) | d <- [-1..1]]
node = memoize2 node'
pathCount' :: Int -> Int -> Integer
pathCount' x y
| y == 0 = if x == 0 then 1 else 0
| otherwise = sum [ pathCount (x + d) (y - 1) | d <- [-1..1]]
pathCount = memoize2 pathCount'
pathSum' :: Int -> Int -> Integer
pathSum' x y
| y == 0 = if x == 0 then 1 else 0
| otherwise = sum [ pathSum (x + d) (y - 1) + node x y * pathCount (x + d) (y - 1)
| d <- [-1..1] ]
pathSum = memoize2 pathSum'
main =
forM_ [0..n] $ \y ->
putStrLn $ intercalate " " $ map (show . flip node y) [-n..n]
where n = 5
Output:
0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 1 1 1 0 0 0 0
0 0 0 2 4 6 4 2 0 0 0
0 0 4 16 40 48 40 16 4 0 0
0 8 72 352 728 944 728 352 72 8 0
16 376 4248 16608 35128 43632 35128 16608 4248 376 16
As you can see the algorithm the size of the numbers will get out of hands rather quickly. So the runtime is not O(n^2), while the number of arithmetic operations is.
You're thinking in terms of outgoing paths, when you should be thinking in terms of incoming paths. Your recursive step is currently looking for nodes from below, instead of above.
First of all, sorry if this is long. I wanted to explain the step by step thought process.
To start off with, you need one crucial fact: You can represent the "answer" at each "index" by a list of paths. For all the zeros, this is [[]], for your base case it is [[1]], and for example, for 0,2 it is [[6,1,1],[6,1,1],[6,1,1]]. This may seem like some redundancy, but it simplifies things down the road. Then, extracting the answer is head . head if the list is non empty, or const 0 if it is.
This is very useful because you can store the answer as a list of rows (the first row would be '[[1]], [], [] ...) and the results of any given row depend only on the previous row.
Secondly, this problem is symmetrical. This is pretty obvious.
The first thing we will do will mirror the definition of fib very closely:
type Path = [[Integer]]
triangle' :: [[Path]]
triangle' = ([[1]] : repeat []) : map f triangle'
We know this must be close to correct, since the 2nd row will depend on the first row only, the third on the 2nd only, etc. So the result will be
([[1]] : repeat []) : f ([[1]] : repeat []) : f ....
Now we just need to know what f is. Firstly, its type: [Path] -> [Path]. Quite simply, given the previous row, return the next row.
Now you may see another problem arising. Each invocation of f needs to know how many columns in the current row. We could actually count the length of non-null elements in the previous row, but it is simpler to pass the parameter directly, so we change map f triangle' to zipWith f [1..] triangle', giving f the type Int -> [Path] -> [Path].
f needs to handle one special case and one general case. The special case is x=0, in this case we simply treat the x+1,y-1 and x-1,y-1 recursions the same, and otherwise is identical to gn. Lets make two functions, g0 and gn which handle these two cases.
The actually computation of gn is easy. We know for some x we need the elements x-1, x, x+1 of the previous row. So if we drop x-1 elements before giving the previous row to the xth invocation of gn, gn can just take the first 3 elements and it will have what it needs. We write this as follows:
f :: Int -> [Path] -> [Path]
f n ps = g0 ps : map (gn . flip drop ps) [0..n-1] ++ repeat []
The repeat [] at the end should be obvious: for indices outside the triangle, the result is 0.
Now writing g0 and gs is really quite simple:
g0 :: [Path] -> Path
g0 (a:b:_) = map (s:) q
where
s = sum . concat $ q
q = b ++ a ++ b
gn :: [Path] -> Path
gn (a:b:c:_) = map (s:) q
where
s = sum . concat $ q
q = a ++ b ++ c
On my machine this version is about 3-4 times faster than the fastest version I could write with normal recursion and memoization.
The rest is just printing or pulling out the number you want.
triangle :: Int -> Int -> Integer
triangle x y = case (triangle' !! y) !! (abs x) of
[] -> 0
xs -> head $ head xs
triList :: Int -> Int -> Path
triList x y = (triangle' !! y) !! (abs x)
printTri :: Int -> Int -> IO ()
printTri width height =
putStrLn $ unlines $ map unwords
[[ p $ triangle x y | x <- [-x0..x0]] | y <- [0..height]]
where maxLen = length $ show $ triangle 0 height
x0 = width `div` 2
p = printf $ "%" ++ show maxLen ++ "d "

How to find multiplicative partitions of any integer?

I'm looking for an efficient algorithm for computing the multiplicative partitions for any given integer. For example, the number of such partitions for 12 is 4, which are
12 = 12 x 1 = 4 x 3 = 2 x 2 x 3 = 2 x 6
I've read the wikipedia article for this, but that doesn't really give me an algorithm for generating the partitions (it only talks about the number of such partitions, and to be honest, even that is not very clear to me!).
The problem I'm looking at requires me to compute multiplicative partitions for very large numbers (> 1 billion), so I was trying to come up with a dynamic programming approach for it (so that finding all possible partitions for a smaller number can be re-used when that smaller number is itself a factor of a bigger number), but so far, I don't know where to begin!
Any ideas/hints would be appreciated - this is not a homework problem, merely something I'm trying to solve because it seems so interesting!
The first thing I would do is get the prime factorization of the number.
From there, I can make a permutation of each subset of the factors, multiplied by the remaining factors at that iteration.
So if you take a number like 24, you get
2 * 2 * 2 * 3 // prime factorization
a b c d
// round 1
2 * (2 * 2 * 3) a * bcd
2 * (2 * 2 * 3) b * acd (removed for being dup)
2 * (2 * 2 * 3) c * abd (removed for being dup)
3 * (2 * 2 * 2) d * abc
Repeat for all "rounds" (round being the number of factors in the first number of the multiplication), removing duplicates as they come up.
So you end up with something like
// assume we have the prime factorization
// and a partition set to add to
for(int i = 1; i < factors.size; i++) {
for(List<int> subset : factors.permutate(2)) {
List<int> otherSubset = factors.copy().remove(subset);
int subsetTotal = 1;
for(int p : subset) subsetTotal *= p;
int otherSubsetTotal = 1;
for(int p : otherSubset) otherSubsetTotal *= p;
// assume your partition excludes if it's a duplicate
partition.add(new FactorSet(subsetTotal,otherSubsetTotal));
}
}
Of course, the first thing to do is find the prime factorisation of the number, like glowcoder said. Say
n = p^a * q^b * r^c * ...
Then
find the multiplicative partitions of m = n / p^a
for 0 <= k <= a, find the multiplicative partitions of p^k, which is equivalent to finding the additive partitions of k
for each multiplicative partition of m, find all distinct ways to distribute a-k factors p among the factors
combine results of 2. and 3.
It is convenient to treat the multiplicative partitions as lists (or sets) of (divisor, multiplicity) pairs to avoid producing duplicates.
I've written the code in Haskell because it's the most convenient and concise of the languages I know for this sort of thing:
module MultiPart (multiplicativePartitions) where
import Data.List (sort)
import Math.NumberTheory.Primes (factorise)
import Control.Arrow (first)
multiplicativePartitions :: Integer -> [[Integer]]
multiplicativePartitions n
| n < 1 = []
| n == 1 = [[]]
| otherwise = map ((>>= uncurry (flip replicate)) . sort) . pfPartitions $ factorise n
additivePartitions :: Int -> [[(Int,Int)]]
additivePartitions 0 = [[]]
additivePartitions n
| n < 0 = []
| otherwise = aParts n n
where
aParts :: Int -> Int -> [[(Int,Int)]]
aParts 0 _ = [[]]
aParts 1 m = [[(1,m)]]
aParts k m = withK ++ aParts (k-1) m
where
withK = do
let q = m `quot` k
j <- [q,q-1 .. 1]
[(k,j):prt | let r = m - j*k, prt <- aParts (min (k-1) r) r]
countedPartitions :: Int -> Int -> [[(Int,Int)]]
countedPartitions 0 count = [[(0,count)]]
countedPartitions quant count = cbParts quant quant count
where
prep _ 0 = id
prep m j = ((m,j):)
cbParts :: Int -> Int -> Int -> [[(Int,Int)]]
cbParts q 0 c
| q == 0 = if c == 0 then [[]] else [[(0,c)]]
| otherwise = error "Oops"
cbParts q 1 c
| c < q = [] -- should never happen
| c == q = [[(1,c)]]
| otherwise = [[(1,q),(0,c-q)]]
cbParts q m c = do
let lo = max 0 $ q - c*(m-1)
hi = q `quot` m
j <- [lo .. hi]
let r = q - j*m
m' = min (m-1) r
map (prep m j) $ cbParts r m' (c-j)
primePowerPartitions :: Integer -> Int -> [[(Integer,Int)]]
primePowerPartitions p e = map (map (first (p^))) $ additivePartitions e
distOne :: Integer -> Int -> Integer -> Int -> [[(Integer,Int)]]
distOne _ 0 d k = [[(d,k)]]
distOne p e d k = do
cap <- countedPartitions e k
return $ [(p^i*d,m) | (i,m) <- cap]
distribute :: Integer -> Int -> [(Integer,Int)] -> [[(Integer,Int)]]
distribute _ 0 xs = [xs]
distribute p e [(d,k)] = distOne p e d k
distribute p e ((d,k):dks) = do
j <- [0 .. e]
dps <- distOne p j d k
ys <- distribute p (e-j) dks
return $ dps ++ ys
distribute _ _ [] = []
pfPartitions :: [(Integer,Int)] -> [[(Integer,Int)]]
pfPartitions [] = [[]]
pfPartitions [(p,e)] = primePowerPartitions p e
pfPartitions ((p,e):pps) = do
cop <- pfPartitions pps
k <- [0 .. e]
ppp <- primePowerPartitions p k
mix <- distribute p (e-k) cop
return (ppp ++ mix)
It's not particularly optimised, but it does the job.
Some times and results:
Prelude MultiPart> length $ multiplicativePartitions $ 10^10
59521
(0.03 secs, 53535264 bytes)
Prelude MultiPart> length $ multiplicativePartitions $ 10^11
151958
(0.11 secs, 125850200 bytes)
Prelude MultiPart> length $ multiplicativePartitions $ 10^12
379693
(0.26 secs, 296844616 bytes)
Prelude MultiPart> length $ multiplicativePartitions $ product [2 .. 10]
70520
(0.07 secs, 72786128 bytes)
Prelude MultiPart> length $ multiplicativePartitions $ product [2 .. 11]
425240
(0.36 secs, 460094808 bytes)
Prelude MultiPart> length $ multiplicativePartitions $ product [2 .. 12]
2787810
(2.06 secs, 2572962320 bytes)
The 10^k are of course particularly easy because there are only two primes involved (but squarefree numbers are still easier), the factorials get slow earlier. I think by careful organisation of the order and choice of better data structures than lists, there's quite a bit to be gained (probably one should sort the prime factors by exponent, but I don't know whether one should start with the highest exponents or the lowest).
Why dont you find all the numbers that can divide the number and then you find permutations of the numbers that multiplications will add up to the number?
Finding all numbers that can divide your number takes O(n).
Then you can permute this set to find all possible sets that multiplication of this set will give you the number.
Once you find set of all possible numbers that divide the original number, then you can do dynamic programming on them to find the set of numbers that multiplying them will give you the original number.

Resources