How many ways can we split a number into k unequal summands? - algorithm

I am taking a challenge online and came across this question, where I need to find the number of ways to split a number 'n' into 'k' unequal summands. For example,
3 - Can be split into 2 and 1.
4 - Can be split into 3 and 1. Note: We cannot do 2 and 2 because, they are equal
5 - (3,2) and (4,1). and so on..
Is there any algorithm for this.

Code in python:
def minArgument(x):
s = 0
i = 1
while s < x:
s += i
i += 1
return i - 1
def maxArgument(x):
return x - 1
def number_of_sumsDP(M, K):
lowerLimit = minArgument(M)
if K < lowerLimit:
return 0
else:
if K - 1 >= M // 2:
return 1 + number_of_sumsDP(M, K - 1)
else:
return 0
def number_of_sums_simple(n):
if n % 2 == 0:
return n // 2 - 1
else:
return n // 2
for i in range(2, 100):
if number_of_sumsDP(i, maxArgument(i)) != number_of_sums_simple(i):
print("mistake")
print("works")
First thought dynamic programming (number_of_sumsDP(M, K)) - number of sums is equal to number of sums with the biggest possible number (subject - 1) and sums without it (with obvious stop when number is less than min arg - it doesn't make sense to add up to 10 with numbers less than 4 [minArgument] and when we start repeating ourself [if K - 1 < M // 2]).
After few prints it leads to even simpler and much efficient algorithm:
number_of_sums_simple - return division in integers by 2 when odd and the same minus one when even; as a proof I convinced myself that it works.

Related

How do I find the number of ways to place blocks of length 1 and 3, in a walkway, using recursion?

I have been given the following problem. Given a walkway of length n, design a recursive algorithm that tells the number of ways to place blocks of size 1 and size 3 on the walkway. I understand the strategy to apply recursion to this problem -
Put in base cases for cases where the walkway is of lengths 1, 2, and 3.
Assume that you already have figured out the number of ways to place blocks of length 1 on the walkway
Assume that you already have figured out the number of ways to place blocks of length 3 on the walkway
Add 2) and 3)
My problem is that I don't know how to code 2) and 3). Here's my code below -
def countPatterns(n):
if(n==1 or n==2):
return 1
elif(n==3):
return 2
elif(n<1):
return 0
else:
# return 2) and 3)
This problem is the same as given the target sum and you need to count number of ways that you can get that target sum just by adding numbers 1 and 3.
Example:
sum = 4
ways:
1: 1 + 1 + 1 + 1
2: 1 + 3
3: 3 + 1
So your function for sum = 4 should return 3.
I think your approach is wrong. Here is my solution:
def numWays(tSum):
if tSum < 0:
return 0
if tSum <= 2:
return 1
return numWays(tSum - 1) + numWays(tSum - 3)

Count the total number ways to reach the nth stair using step 1, 2 or 3 but the step 3 can be taken only once

For any given value N we have to find the number of ways to reach the top while using steps of 1,2 or 3 but we can use 3 steps only once.
for example if n=7
then possible ways could be
[1,1,1,1,1,1,1]
[1,1,1,1,1,2]
etc but we cannot have [3,3,1] or [1,3,3]
I have managed to solve the general case without the constraint of using 3 only once with dynamic programming as it forms a sort of fibonacci series
def countWays(n) :
res = [0] * (n + 1)
res[0] = 1
res[1] = 1
res[2] = 2
for i in range(3, n + 1) :
res[i] = res[i - 1] + res[i - 2] + res[i - 3]
return res[n]
how do I figure out the rest of it?
Let res0[n] be the number of ways to reach n steps without using a 3-step, and let res1[n] be the number of ways to reach n steps after having used a 3-step.
res0[i] and res1[i] are easily calculated from the previous values, in a manner similar to your existing code.
This is an example of a pretty common technique that is often called "graph layering". See, for example: Shortest path in a maze with health loss
Let us first ignore the three steps here. Imagine that we can only use steps of one and two. Then that means that for a given number n. We know that we can solve this with n steps of 1 (one solution), or n-2 steps of 1 and one step of 2 (n-1 solutions); or with n-4 steps of 1 and two steps of 2, which has n-2×n-3/2 solutions, and so on.
The number of ways to do that is related to the Fibonacci sequence. It is clear that the number of ways to construct 0 is one: just the empty list []. It is furthermore clear that the number of ways to construct 1 is one as well: a list [1]. Now we can proof that the number of ways Wn to construct n is the sum of the ways Wn-1 to construct n-1 plus the number of ways Wn-2 to construct n-2. The proof is that we can add a one at the end for each way to construct n-1, and we can add 2 at the end to construct n-2. There are no other options, since otherwise we would introduce duplicates.
The number of ways Wn is thus the same as the Fibonacci number Fn+1 of n+1. We can thus implement a Fibonacci function with caching like:
cache = [0, 1, 1, 2]
def fib(n):
for i in range(len(cache), n+1):
cache.append(cache[i-2] + cache[i-1])
return cache[n]
So now how can we fix this for a given step of three? We can here use a divide and conquer method. We know that if we use a step of three, it means that we have:
1 2 1 … 1 2 3 2 1 2 2 1 2 … 1
\____ ____/ \_______ _____/
v v
sum is m sum is n-m-3
So we can iterate over m, and each time multiply the number of ways to construct the left part (fib(m+1)) and the right part (fib(n-m-3+1)) we here can range with m from 0 to n-3 (both inclusive):
def count_ways(n):
total = 0
for m in range(0, n-2):
total += fib(m+1) * fib(n-m-2)
return total + fib(n+1)
or more compact:
def count_ways(n):
return fib(n+1) + sum(fib(m+1) * fib(n-m-2) for m in range(0, n-2))
This gives us:
>>> count_ways(0) # ()
1
>>> count_ways(1) # (1)
1
>>> count_ways(2) # (2) (1 1)
2
>>> count_ways(3) # (3) (2 1) (1 2) (1 1 1)
4
>>> count_ways(4) # (3 1) (1 3) (2 2) (2 1 1) (1 2 1) (1 1 2) (1 1 1 1)
7

How to find all possible reachable numbers from a position?

Given 2 elements n, s and an array A of size m, where s is initial position which lies between 1 <= s <= n, our task is to perform m operations to s and in each operation we either make s = s + A[i] or s = s - A[i], and we have to print all the values which are possible after the m operation and all those value should lie between 1 - n (inclusive).
Important Note: If during an operation we get a value s < 1 or s > n,
we don't go further with that value of s.
I solved the problem using BFS, but the problem is BFS approach is not optimal here, can someone suggest any other more optimal approach to me or an algorithm will greatly help.
For example:-
If n = 3, s = 3, and A = {1, 1, 1}
3
/ \
operation 1: 2 4 (we don’t proceed with 4 as it is > n)
/ \ / \
operation 2: 1 3 3 5
/ \ / \ / \ / \
operation 3: 0 2 2 4 2 4 4 6
So final values reachable by following above rules are 2 and 2 (that is two times 2). we don't consider the third two as it has an intermediate state which is > n ( same case applicable if < 1).
There is this dynamic programming solution, which runs in O(nm) time and requires O(n) space.
First establish a boolean array called reachable, initialize it to false everywhere except for reachable[s], which is true.
This array now represents whether a number is reachable in 0 steps. Now for every i from 1 to m, we update the array so that reachable[x] represents whether the number x is reachable in i steps. This is easy: x is reachable in i steps if and only if either x - A[i] or x + A[i] is reachable in i - 1 steps.
In the end, the array becomes the final result you want.
EDIT: pseudo-code here.
// initialization:
for x = 1 to n:
r[x] = false
r[s] = true
// main loop:
for k = 1 to m:
for x = 1 to n:
last_r[x] = r[x]
for x = 1 to n:
r[x] = (last_r[x + A[k]] or last_r[x - A[k]])
Here last_r[x] is by convention false if x is not in the range [1 .. n].
If you want to maintain the number of ways that each number can be reached, then you do the following changes:
Change the array r to an integer array;
In the initialization, initialize all r[x] to 0, except r[s] to 1;
In the main loop, change the key line to:
r[x] = last_r[x + A[k]] + last_r[x - A[k]]

the number of trailing zeros in a factorial of a given number - Ruby

Having a little trouble trying calculate the number of trailing zeros in a factorial of a given number. This is one of the challenges from Codewars- can't get mine to pass.
zeros(12) = 2 #=> 1 * 2 * 3 .. 12 = 479001600
I think I'm on the wrong path here and there is probably a more elegant ruby way. This is what I have down so far.
def zeros(n)
x = (1..n).reduce(:*).to_s.scan(/[^0]/)
return 0 if x == []
return x[-1].length if x != []
end
This is more of a math question. And you're right, you are off on a wrong path. (I mean the path you are on is going to lead to a very inefficient solution)
Try to reduce the problem mathematically first. (BTW you are shooting for a log N order algorithm.)
In my answer I will try to skip a few steps, because it seems like a homework question.
The number of trailing zeros is going to be equal to the total power of 5s in the multiplication of the series.
the numbers between 1 and n will have n/5, n/25, n/125 numbers which are multiples of 5s, 25s, 125s respectively... and so on.
Try to take these hints and come up with an algorithm to count how many powers of 10 will be crammed in to that factorial.
Spoilers Ahead
I've decided to explain in detail below so if you want to try and solve it yourself then stop reading, try to think about it and then come back here.
Here is a step by step reduction of the problem
1.
The number of trailing zeros in a number is equivalent to the power of 10 in the factor of that number
e.g.
40 = 4 * 10^1 and it has 1 trailing zero
12 = 3 * 4 * 10^0 so it has 0 trailing zeros
1500 = 3 * 5 * 10^2 so it has 2 trailing zeros
2.
The number power of 10 in the factors is the same as the minimum of the power of 2 and power of 5 in the factors
e.g.
50 = 2^1 * 5^2 so the minimum power is 1
300 = 3^1 * 2^2 * 5^2 so the minimum is 2 (we are only concerned with the minimum of the powers of 2 and 5, so ignore powers of 3 and all other prime factors)
3.
In any factorial there will be many more powers of 2 than the powers of 5
e.g.
5! = 2^3 * 3^1 * 5^1
10! = 2^8 * 3^4 * 5^2 * 7^1
As you can see the power of 2 is going to start increasing much faster so the power of 5 will be the minimum of the two.
Hence all we need to do is count the power of 5 in the factorial.
4.
Now lets focus on the power of 5 in any n!
4! ~ 5^0
5! ~ 5^1 (up to 9!)
10! ~ 5^2 (up to 14!)
15! ~ 5^3 (up to `19!)
20! ~ 5^4 (up to 24!)
25! ~ 5^6 (notice the jump from 5^4 to 5^6 because the number 25 adds two powers of 5)
5.
The way I'd like to count the total power of five in a factorial is... count all the multiples of 5, they all add one power of 5. Then count all the multiples of 25, they all add an extra power of 5. Notice how 25 added two powers of 5, so I can put that as, one power because it's a multiple of 5 and one extra power because it's a multiple of 25. Then count all the multiple of 125 (5^3) in the factorial multiplication, they add another extra power of 5... and so on.
6.
So how'd you put that as an algorithm ?
lets say the number is n. So...
pow1 = n/5 (rounded down to an integer)
pow2 = n/25
pow3 = n/125
and so on...
Now the total power pow = pow1 + pow2 + pow3 ...
7.
Now can you express that as a loop?
So, now that #Spunden has so artfully let the cat out of the bag, here's one way to implement it.
Code
def zeros(n)
return 0 if n.zero?
k = (Math.log(n)/Math.log(5)).to_i
m = 5**k
n*(m-1)/(4*m)
end
Examples
zeros(3) #=> 0
zeros(5) #=> 1
zeros(12) #=> 2
zeros(15) #=> 3
zeros(20) #=> 4
zeros(25) #=> 6
zeros(70) #=> 16
zeros(75) #=> 18
zeros(120) #=> 28
zeros(125) #=> 31
Explanation
Suppose n = 128.
Then each number between one and 128 (inclusive) that is divisible by 5^1=>5 provides at least one factor, and there are 128/5 => 25 such numbers. Of these, the only ones that provide more than one factor are those divisible by 5^2=>25, of which there are 128/25 => 5 (25, 50, 75, 100, 125). Of those, there is but 128/125 => 1 that provides more than two factors, and since 125/(5^4) => 0, no numbers contribute more than three divisors. Hence, the total number of five divisors is:
128/5 + 128/25 + 128/125 #=> 31
(Note that, for 125, which has three divisors of 5, one is counted in each of these three terms; for 25, 50, etc., which each have two factors of 5, one is counted in each of the first terms.)
For arbitrary n, we first compute the highest power k for which:
5**k <= n
which is:
k <= Math.log(n)/Math.log(5)
so the largest such value is:
k = (Math.log(n)/Math.log(5)).to_i
As #spundun noted, you could also calculate k by simply iterating, e.g.,
last = 1
(0..1.0/0).find { |i| (last *= 5) > n }
The total number of factors of five is therefore
(n/5) + (n/25) +...+ (n/5**k)
Defining:
r = 1/5,
this sum is seen to be:
n * s
where
s = r + r**2 +...+ r**k
The value of s is the sum of the terms of a geometric series. I forget the formula for that, but recall how it's derived:
s = r + r**2 +...+ r**k
sr = r**2 +...+ r**(k+1)
s-sr = r*(1-r**k)
s = r*(1-r**k)/(1-r)
I then did some rearrangement so that only only integer arithmetic would be used to calculate the result.
def zeros(n)
zeros = 0
zeros += n /= 5 while n >= 1
zeros
end
If N is a number then number of trailing zeroes in N! is
N/5 + N/5^2 + N/5^3 ..... N/5^(m-1) WHERE (N/5^m)<1
You can learn here how this formula comes.
Here's a solution that is easier to read:
def zeros(num)
char_array = num.to_s.split('')
count = 0
while char_array.pop == "0"
count += 1
end
count
end
Let me know what you think and feel free to edit if you see an improvement!
The article A Note on Factorial and its Trailing Zeros in GanitCharcha is insightful and has explained the Mathematics behind this well. Take a look.
http://www.ganitcharcha.com/view-article-A-Note-on-Factorial-and-it's-Trailing-Zeros.html
My solution
def zeros(n)
trailing_zeros = []
fact = (1..n).inject(:*)
fact.to_s.split('').reverse.select {|x| break if (x.to_i != 0); trailing_zeros << x}
return trailing_zeros.count
end
n = int (raw_input())
count = 0
num = 1
for i in xrange(n+1):
if i != 0:
num = num * i
while(num >= 10):
if num%10 == 0:
count+=1
num = num/10
else:
break
print count
As per the explanation given by #spundan and apart from #cary's code you can find number of trailing zero by just very simple and efficient way..see below code..
def zeros(n)
ret = 0
while n > 0 do
ret += n / 5
n = n/5
end
ret
end
For example zeros(100000000) this will give you output -> 24999999
With the time Time Elapsed -> 5.0453e-05(Just See 5.0453e-05 )
This is the part of even milliseconds.
n=int(input())
j=5
c=int(0)
while int(n/j)>0:
c=c+int(n/j)
j=j*5
print(c)
count = 0
i =5
n = 100
k = n
while(n/i!=0):
count+=(n/i)
i=i*5
n = k
print count
def zeros(n)
n < 5 ? 0 : (n / 5) + zeros(n / 5)
end

Is there an infinite loop in my code for solving Collatz sequence?

My code is trying to find the answer to this problem: The following iterative sequence is defined for the set of positive integers:
n → n/2 (n is even)
n → 3n + 1 (n is odd)
Using the rule above and starting with 13, we generate the following sequence:
13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1
It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.
Which starting number, under one million, produces the longest chain?
NOTE: Once the chain starts the terms are allowed to go above one million.
And here is my code:
step_count = 1
score = {}
largest_score = 1
(1..1000000).map do |n|
while n >= 1 do
if n%2 == 0 then
n/2
step_count += 1
else
(3*n)+1
step_count += 1
end
end
score = {n => step_count}
end
score.each {|n, step_count| largest_score = step_count if largest_score < step_count}
puts score.key(largest_score)
I ran it for over an hour and still no answer. Is there an infinite loop in my code, or maybe some different problem, and if so what is it?
I am using Ruby 1.8.7
Yes, you've got an infinite loop. It's here:
while n >= 1 do
if n%2 == 0 then
n/2
step_count += 1
else
(3*n)+1
step_count += 1
end
end
The condition in your while loop is testing n, but nothing within the loop is changing its value. What you probably meant to do is this:
while n >= 1 do
if n % 2 == 0
n = n / 2
step_count += 1
else
n = (3 * n) + 1
step_count += 1
end
end
A few sidenotes:
It looks like you mean to be updating the score hash with new key-value pairs, but as written, score = { n => step_count } will replace it entirely on each iteration. To add new pairs to the existing Hash, use score[n] = step_count.
It's much more efficient to look up a value in a Hash by its key than the other way around, so you might want to reverse your Hash storage: score[step_count] = n, finding the largest score with score.each { |step_count, n| #... and reading it out with score[largest_score]. This has the added advantage that you won't have to store all million results; it'll only store the last number you reach that results in a chain of a given length. Of course, it also means that you'll only see one number that results in the largest chain, even if there are multiple numbers that have the same, highest chain length! The problem is worded as though the answer is unique, but if it isn't, you won't find out.
To debug problems like this in the future, it's handy to drop your loop iterations to something tiny (ten, say) and sprinkle some puts statements within your loops to watch what's happening and get a feel for the execution flow.
Try the following solution for your problem:
def solve(n)
max_collatz = 0; max_steps = 0
(1..n).each do |k|
next if k % 2 == 0
next if k % 3 != 1
steps = collatz_sequence_count(k)
if steps > max_steps
max_steps = steps
max_collatz = k
end
end
max_collatz
# answer: 837799 with 525 steps, in nearly 2.2 seconds on my machine
end
def collatz_sequence_count(k)
counter = 1
while true
return counter if k == 1
k = k % 2 == 0 ? k/2 : 3 * k + 1
counter += 1
end
end
# You can then use the above methods to get your answer, like this:
answer = solve 1000000
puts "answer is: #{answer}"
Results (uses a custom home-brewed gem to solve ProjectEuler problems):
nikhgupta at MacBookPro in ~/Code/git/ProjectEuler [ master: ✗ ] 48d
± time euler solve 14 +next: 2 | total: 22 | ▸▸▸▹▹▹▹▹▹▹
0014 | Longest Collatz sequence | It took me: 2.166033 seconds. | Solution: 837799
euler solve 14 3.30s user 0.13s system 99% cpu 3.454 total

Resources