Count the coins including permutations of the same sequence - algorithm

I've found a code to find number of possibilities to make change using given coins: How to count possible combination for coin problem. But how to count it, if we think about different permutations of the same sequence? I mean that, e.g. amount is 12, and "4 4 2 2" and "4 2 4 2" should be counted as 2, not 1.

As you've mentioned inside your question you can count the possible combinations as stated in How to count possible combination for coin problem. But in order to include the permutations into your answer:
If you distinguish the permutation of the same numbers [1 7 7] and [1 7 7] e.g. just count each sequence([1 7 7] here) as n! (n = # of elements in the sequence) [instead of 1]
Otherwise : multiply each sequence by n!/(m!l!...) where m = number of equal elements of type 1, l is number of equal elements of type 2 and so on... . For example for sequence like [a b b c c c] you should count this 6!/(2!*3!) [instead of 1]
So use the algorithm inside that link, that I don't repeat again, but just instead of counting each combination as 1 use the formula that I said (depending on the case you desire).
(! is factorial.)

Related

Advanced Algorithms Problems ("Nice Triangle"): Prime number Pyramid where every number depends on numbers above it

I'm currently studying for an advanced algorithms and datastructures exam, and I simply can't seem to solve one of the practice-problems which is the following:
1.14) "Nice Triangle"
A "nice" triangle is defined in the following way:
There are three different numbers which the triangle consists of, namely the first three prime numbers (2, 3 and 5).
Every number depends on the two numbers below it in the following way.
Numbers are the same, resulting number is also the same. (2, 2 => 2)
Numbers are different, resulting number is the remaining number. (2, 3 => 5)
Given an integer N with length L, corresponding to the base of the triangle, determine the last element at the top
For example:
Given N = 25555 (and thus L = 5), the triangle looks like this:
2
3 5
2 5 5
3 5 5 5
2 5 5 5 5
=> 2 is the result of this example
What does the fact that every number is prime have to do with the problem?
By using a naive approach (simply calculating every single row), one obtains a time-complexity of O(L^2).
However, the professor said, it's possible with O(L), but I simply can't find any pattern!!!
I'm not sure why this problem would be used in an advanced algorithms course, but yes, you can do this in O(l) = O(log n) time.
There are a couple ways you can do it, but they both rely on recognizing that:
For the problem statement, it doesn't matter what digits you use. Lets use 0, 1, and 2 instead of 2, 3, and 5. Then
If a and b are the input numbers and c is the output, then c = -(a+b) mod 3
You can build the whole triangle using c = a+b mod 3 instead, and then just negate every second row.
Now the two ways you can do this in O(log n) time are:
For each digit d in the input, calculate the number of times (call it k) that it gets added into the final sum, add up all the kd mod 3, and then negate the result if you started with an even number of digits. That takes constant time per digit. Alternatively:
recognize that you can do arithmetic on n-sized values in constant time. Make a value that is a bit mask of all the digits in n. That takes 2 bits each. Then by using bitwise operations you can calculate each row from the previous one in constant time, for O(log n) time altogether.
Here's an implementation of the 2nd way in python:
def niceTriangle(n):
# a vector of 3-bit integers mod 3
rowvec = 0
# a vector of 1 for each number in the row
onevec = 0
# number of rows remaining
rows = 0
# mapping for digits 0-9
digitmap = [0, 0, 0, 1, 1, 2, 2, 2, 2, 2]
# first convert n into the first row
while n > 0:
digit = digitmap[n % 10]
n = n//10
rows += 1
onevec = (onevec << 3) + 1
rowvec = (rowvec << 3) + digit
if rows%2 == 0:
# we have an even number of rows -- negate everything
rowvec = ((rowvec&onevec)<<1) | ((rowvec>>1)&onevec)
while rows > 1:
# add each number to its neighbor
rowvec += (rowvec >> 3)
# isolate the entries >= 3, by adding 1 to each number and
# getting the 2^2 bit
gt3 = ((rowvec + onevec) >> 2) & onevec
# subtract 3 from all the greater entries
rowvec -= gt3*3
rows -= 1
return [2,3,5][rowvec%4]

Convert the permutation sequence A to B by selecting a set in A then reversing that set and inserting that set at the beginning of A

Given the sequence A and B consisting of N numbers that are permutations of 1,2,3,...,N. At each step, you choose a set S in sequence A in order from left to right (the numbers selected will be removed from A), then reverse S and add all elements in S to the beginning of the sequence A. Find a way to transform A into B in log2(n) steps.
Input: N <= 10^4 (number of elements of sequence A, B) and 2 permutations sequence A, B.
Output: K (Number of steps to convert A to B). The next K lines are the set of numbers S selected at each step.
Example:
Input:
5 // N
5 4 3 2 1 // A sequence
2 5 1 3 4 // B sequence
Output:
2
4 3 1
5 2
Step 0: S = {}, A = {5, 4, 3, 2, 1}
Step 1: S = {4, 3, 1}, A = {5, 2}. Then reverse S => S = {1, 3, 4}. Insert S to beginning of A => A = {1, 3, 4, 5, 2}
Step 2: S = {5, 2}, A = {1, 3, 4}. Then reverse S => S = {2, 5}. Insert S to beginning of A => A = {2, 5, 1, 3, 4}
My solution is to use backtracking to consider all possible choices of S in log2(n) steps. However, N is too large so is there a better approach? Thank you.
For each operation of combined selecting/removing/prepending, you're effectively sorting the elements relative to a "pivot", and preserving order. With this in mind, you can repeatedly "sort" the items in backwards order (by that I mean, you sort on the most significant bit last), to achieve a true sort.
For an explicit example, lets take an example sequence 7 3 1 8. Rewrite the terms with their respective positions in the final sorted list (which would be 1 3 7 8), to get 2 1 0 3.
7 -> 2 // 7 is at index 2 in the sorted array
3 -> 1 // 3 is at index 0 in the sorted array
1 -> 0 // so on
8 -> 3
This new array is equivalent to the original- we are just using indices to refer to the values indirectly (if you squint hard enough, we're kinda rewriting the unsorted list as pointers to the sorted list, rather than values).
Now, lets write these new values in binary:
2 10
1 01
0 00
3 11
If we were to sort this list, we'd first sort by the MSB (most significant bit) and then tiebreak only where necessary on the subsequent bit(s) until we're at the LSB (least significant bit). Equivalently, we can sort by the LSB first, and then sort all values on the next most significant bit, and continuing in this fashion until we're at the MSB. This will work, and correctly sort the list, as long as the sort is stable, that is- it doesn't change the order of elements that are considered equal.
Let's work this out by example: if we sorted these by the LSB, we'd get
2 10
0 00
1 01
3 11
-and then following that up with a sort on the MSB (but no tie-breaking logic this time), we'd get:
0 00
1 01
2 10
3 11
-which is the correct, sorted result.
Remember the "pivot" sorting note at the beginning? This is where we use that insight. We're going to take this transformed list 2 1 0 3, and sort it bit by bit, from the LSB to the MSB, with no tie-breaking. And to do so, we're going to pivot on the criteria <= 0.
This is effectively what we just did in our last example, so in the name of space I won't write it out again, but have a look again at what we did in each step. We took the elements with the bits we were checking that were equal to 0, and moved them to the beginning. First, we moved 2 (10) and 0 (00) to the beginning, and then the next iteration we moved 0 (00) and 1 (01) to the beginning. This is exactly what operation your challenge permits you to do.
Additionally, because our numbers are reduced to their indices, the max value is len(array)-1, and the number of bits is log2() of that, so overall we'll only need to do log2(n) steps, just as your problem statement asks.
Now, what does this look like in actual code?
from itertools import product
from math import log2, ceil
nums = [5, 9, 1, 3, 2, 7]
size = ceil(log2(len(nums)-1))
bit_table = list(product([0, 1], repeat=size))
idx_table = {x: i for i, x in enumerate(sorted(nums))}
for bit_idx in range(size)[::-1]:
subset_vals = [x for x in nums if bit_table[idx_table[x]][bit_idx] == 0]
nums.sort(key=lambda x: bit_table[idx_table[x]][bit_idx])
print(" ".join(map(str, subset_vals)))
You can of course use bitwise operators to accomplish the bit magic ((thing << bit_idx) & 1) if you want, and you could del slices of the list + prepend instead of .sort()ing, this is just a proof-of-concept to show that it actually works. The actual output being:
1 3 7
1 7 9 2
1 2 3 5

Simple math task: 2 numbers given, we have to find the third. I just need a formula for it

I need a formula for counting the number of combinations within a given limit of numbers. There must only be 2 numbers given, we have to find the third.
For example, for 2(number of repetitions) and 3(limit number), the result would be 3, because there are 3 combinations for the digits: 1 and 2, 1 and 3, 2 and 3.
For 2 and 4 the result is 6,
For 3 and 5 the result is 10,
For 6 and 7 the result is 7, etc.
The first number has to be smaller than the second.
A formula is needed for figuring out the result, if the first number is A, the second is B, what would C is going to be?
You're describing combination. The formula is going to be C = B! / (A!*(B-A)!) (where ! is the factorial operation). It's also worth noting that the first number can be equal to the second -- there should only be one repetition in that case. By convention 0! == 1 and it is OK where both numbers are equal because C(n, n) = 1 and this means n!/(n! * 0!).
Unfortunately, since factorial grows very quickly (21! is too large for a 64-bit unsigned integer), you probably can't compute this directly. Wikipedia has a few algorithms you can use here.

Find the number of non-decreasing and non-increasing subsequences in an array

I am attempting to complete a programming challenge from Quora on HackerRank: https://www.hackerrank.com/contests/quora-haqathon/challenges/upvotes
I have designed a solution that works with some test cases, however, for many the algorithm that I am using is incorrect.
Rather than seeking a solution, I am simply asking for an explanation to how the subsequence is created and then I will implement a solution myself.
For example, with the input:
6 6
5 5 4 1 8 7
the correct output is -5, but I fail to see how -5 is the answer. The subsequence would be [5 5 4 1 8 7] and I cannot for the life of me find a means to get -5 as the output.
Problem Statement
At Quora, we have aggregate graphs that track the number of upvotes we get each day.
As we looked at patterns across windows of certain sizes, we thought about ways to track trends such as non-decreasing and non-increasing subranges as efficiently as possible.
For this problem, you are given N days of upvote count data, and a fixed window size K. For each window of K days, from left to right, find the number of non-decreasing subranges within the window minus the number of non-increasing subranges within the window.
A window of days is defined as contiguous range of days. Thus, there are exactly N−K+1 windows where this metric needs to be computed. A non-decreasing subrange is defined as a contiguous range of indices [a,b], a<b, where each element is at least as large as the previous element. A non-increasing subrange is similarly defined, except each element is at least as large as the next. There are up to K(K−1)/2 of these respective subranges within a window, so the metric is bounded by [−K(K−1)/2,K(K−1)/2].
Constraints
1≤N≤100,000 days
1≤K≤N days
Input Format
Line 1: Two integers, N and K
Line 2: N positive integers of upvote counts, each integer less than or equal to 10^9
Output Format
Line 1..: N−K+1 integers, one integer for each window's result on each line
Sample Input
5 3
1 2 3 1 1
Sample Output
3
0
-2
Explanation
For the first window of [1, 2, 3], there are 3 non-decreasing subranges and 0 non-increasing, so the answer is 3. For the second window of [2, 3, 1], there is 1 non-decreasing subrange and 1 non-increasing, so the answer is 0. For the third window of [3, 1, 1], there is 1 non-decreasing subrange and 3 non-increasing, so the answer is -2.
Given a window size of 6, and the sequence
5 5 4 1 8 7
the non-decreasing subsequences are
5 5
1 8
and the non-increasing subsequences are
5 5
5 4
4 1
8 7
5 5 4
5 4 1
5 5 4 1
So that's +2 for the non-decreasing subsequences and -7 for the non-increasing subsequences, giving -5 as the final answer.

Maximize the sum of product of adjacent numbers

Here is a question that I encountered during an Interviewstreet codesprint.
I was unable to find a a solution or even think in its direction. I'd be thankful if someone could help me find the soultion, or explain me how the problem neeeds to be dealt with.
Given numbers 1, 2, 3, .., N, arrange them in a order such that the
sum of product of adjecent numbers is maximized.
For example: if N = 3, and we order them as ( 1, 2, 3 ), the sum of
products is 1*2 + 2*3 = 8 and if we order them as ( 1, 3 ,2 ) the sum
of products is 1*3 + 3*2 = 9.
Input format :
First line of the input contains T, the number of test-cases. Then
follow T lines, each containing an integer N.
Output format :
For each test case print the maximum sum of product of adjacent
numbers.
Sample input :
2 2 4
Sample output :
2 23
Explanation :
In first test case given permutation is ( 1, 2 ). So maximum sum of
product is 1*2. In Second test case the numbers are (1,2,3,4).
Arrangement 1,3,4,2 has sum of product of adjacent numbers as
1*3+3*4+4*2 = 23. No other arrange has sum of product of adjacent
numbers more than 23.
Constraints :
1 <= T <= 10 1 <= N <= 200000
The maximum sum-of-adjacent-products comes when the largest value is in the middle of the sequence, and the successively lower values alternate to its left and right. That is, your sequence for a given value n would be [..., n-3, n-1, n, n-2, n-4, ...] (or the reverse of this, which will have the same sum of products).
So, leaving out the input-parsing bits, here's the heart of the algorithm (in Python, but easily translated to other languages):
def maximumSumOfAdjacentProducts(n):
if n == 1: # special case needed for a one element sequence
return 1
sumOfProducts = n * (n-1) # this pair is the "center" of the sequence
for i in range(n-2, 0, -1): # iterate downward from n-2 to 1
sumOfProducts += i*(i+2) # each adjacent pair is separated by 2
return sumOfProducts
Sort the array, call it sortedArray in ascending order.
Remove max1, max2 and put them in a result list.
Remove the next element and add it to the side of MAX(max1, max2).
Update max1 and max2. i.e. max1 is left side and max2 is right side of the list.
Repeat steps 3 & 4 until the sorted input array has elements.
Example:
inputArray: 1,3,4,2,5
sortedArray: 1,2,3,4,5
Add 5 and 4 to the list first.
result = [5, 4]
Remove 3 and add it to MAX(5,4)
result = [3, 5, 4]
Remove 2 and add it to MAX(3,4)
result = [3, 5, 4, 2]
Remove 1 and add it to MAX(3,2)
result = [1, 3, 5, 4, 2]

Resources