How many such permutation exists? - permutation

We are looking for permutations of numbers 1,2,⋯,50, when 10 and 20 are next to each other (in any order). How many such permutation exists?
Select one:
249
49!
5049
49!⋅2
50!

The amount of permutations for 50 numbers with no conditions is 50!,
hence if we assume 10 and 20 are one number (as they have to be adjacent) we're down to 49! permutations.
finally for each permutation x ... 10, 20, ... xn exists a permutation x, ... 20, 10, ...xn
so we get a total of 2 * 49! permutation.

Related

How to count pairs (a[i], a[j]), i < j and a[i] + a[j] can be divided by k without remainder

I wander if it is possible to solve the problem in less than O(N^2).
There is array a of length N and divisor k. Need to count all possible pairs (a[i], a[j]) such as i < j and a[i] + a[j] can be divided by k without remainder.
All I can get is two nested loops.
I can create array with all remainders of a[i] divided by k, but then it is need to do similar nested loops through this array and it is O(N^2) again.
We can solve this in O(n) using a hash map where the key is the remainder and the value is the count of how many times we've seen this remainder as we iterate. For each number, after the first has been inserted, before the element, A[i], is inserted, add to the result the value at the key, k - (A[i] mod k) if it exists in the map. Then increment by 1 the count at key A[i] mod k.
Sort the array on a[i] mod k. This is done in time O(N Log N).
Scan the array with two indexes, left-to-right and right-to-left, in such a way that you detect the sequences of elements such that the sum mod k is 0, and multiply the lengths of these sequences. This is done in time O(N).
E.g. with k=5
2, 9, 21, 13, 1, 8, 22, 6
After sorting,
1, 21, 6, 22, 2, 13, 8, 9
1 1 1 2 2 3 3 4
and the sequences are
||1, 21, 6|2, 22|13, 8|9|
||1 1 1|2 2| 3 3|4|
Hence 3x1 + 2x2 pairs.
You need some extra trick to avoid counting the pairs i≥j. For instance, you can append to every element its initial index in the array, and sort lexicographically on the value mod k then on the index. Then when counting pairs, by a kind of merging process you can enumerate the valid pairs. The total complexity remains O(N).
2, 9, 21, 13, 1, 8, 22, 6
0 1 2 3 4 5 6 7
After sorting,
21, 1, 6, 2, 22, 13, 8, 9
1 1 1 2 2 3 3 4
2 4 7 0 6 3 5 1
and the sequences are
||21, 1, 6|2, 22|13, 8|9|
|| 1 1 1|2 2| 3 3|4|
|| 2 4 7|0 6| 3 5|1|
Now to count the valid pairs from |2, 22|13, 8|, we see that 2 was followed by 13, 8 and 22 was followed by nothing, hence there are 2+0 valid pairs.
Create a bucket of remainders from 0 to k-1. Now divide every number of array with divisor k and put the number in remainder bucket based on the remainder yielded after dividing by k. Now create the pair like this -
Every number yielded remainder 1 can make pair with all numbers yielded remainder k - 1 because their sum will be perfectly divided by k (without remainder).
Similarly numbers in remainder 2 bucket will make pair with numbers in remainder k - 2 bucket. Do this for i<=j.
Also, all numbers in remainder 0 bucket will make pair among themselves.
Time complexity is O(n) and space complexity is O(k) (for bucket of remainders).
EDIT:
If just need to count the number of pairs then the remainder bucket can be like a simple array (whose all elements initialised by 0) and every element, at a particular index, will contain the number of elements of array yielded the remainder equivalent to that index. Do simple calculation - number at remainder bucket index 1 multiply by number at remainder bucket index k - 1, number at index 2 multiply by number at index k - 2 and so on (i<=j). Also, calculate the possible pairs of number at index 0. Add them all and this gives the answer.
Write a recursive function then you will see there are oerlapping results (you are doing same calculations again). Then convet the program to a dynamic programing model which would save result for a given sub array.

Find amount of natural numbers generated from array of digit characters

Good day.
I have an array of digit characters ['9','0'] or ['9','5','2','0','0','0']. Need to find amount of all natural numbers with length equal to array size generated from a source array. For example for ['9','0'] it will be only 90 and answer is 1.
If array has no 0 and digits duplication amount of numbers can be calculated by factorial:
['5','7','2'] => 3! => 6
['1','2','3','4','5','6','7'] => 7! => 5040.
When zeros and duplication appears it's become changeable.
More examples: https://www.codewars.com/kumite/5a26eb9ab6486ae2680000fe?sel=5a26eb9ab6486ae2680000fe
Thank you
P.S. Better to find formula, I know how solve this problem by loops
def g(a)
answer = a.permutation(a.size)
.select{|x| x.join.to_i.to_s.split("").size == a.size }.to_a.uniq.size
answer
end
The only difference with '0' is that you can't have leading '0', aka first digit cannot be 0.
The formula given an array of N numbers become
(N - Number of zeros) * (N-1)!
When there is no zero, it is just N!.
Now consider the case with duplication, lets say there are K '1' in the array. For every permutation you have in the previous calculation, you can swap the '1' in K! permutation, thus you need to divide your result with K!. This need to be done for every single digits with duplicates. When there is no duplication (0 or 1 such digit), you are dividing by 0! or 1! thus division does not change the value.
Sample case: [0, 0, 1, 1]
4 digits, 2 zeros, 2 ones
(4-2) * 3! / (2! * 2!) = 3
Possible permutation: 1001, 1010, 1100

Changes in array of coprime numbers

I'm given an array and have to determine the minimum number of additions(ADDITION BY 1) that have to be done to the elements such that they are all no longer coprime(GCD>1)
I could recursively check if the gcd is >1. If it is not, I thought that the easiest GCD to get would be 2, so I can add 1 to all the odd numbers and get the GCD as 2 however this fails for cases with very few/no even numbers and where it is easier to generate other GCDs such as 11, 33, 55 and 76. Here I can add 1 to 76 and change the GCD from 1 to 11 in 1 step rather than changing 11,33 and 55 by making 3 additions and getting GCD as 2.
I wanted to know the most efficient way of doing this. Also checking the GCD of the array would be O(nlogn).
You could find the prime factorization of each element, then count how many elements have each prime in the factorization. The number of additions required is [Element count] - [MAX(Prime Count)].
For example, the factorization for [11, 33, 55, 76] is:
11: 11^1
33: 3^1 * 11^1
55: 5^1 * 11^1
76: 2^2 * 19^1
The prime counts are:
2: 1
3: 1
5:1
11: 3
19: 1
The highest count is 3, there are 4 elements, so you need 1 addition (4 - 3). If you need to know which elements need to be added to, it's the elements whose factorization don't include the max counted prime.

find unique adjacent indices in 2d array

Assume I have a 2d array of objects, N x N. Assume that a pair can be made of every adjacent pair of objects, horizontally, vertically or diagonally. How can I count how many unique pairs there are for any value of N?
For example for N = 2
0 1
2 3
You can get 01 02 03 21 23 31, note that 03 is the same as 30
Is there a formula to determine how many of these pairs there are for a given N, and even better an algorithm for generating these?
Language is not that important but I will be using c++.
Using the below algorithm and eliminating duplicate indices, I get following counts. Not sure what the formula is yet.
For size N=2
Unique pairs is =6
For size N=3
Unique pairs is =20
For size N=4
Unique pairs is =42
For size N=5
Unique pairs is =72
For size N=6
Unique pairs is =110
For size N=7
Unique pairs is =156
For size N=8
Unique pairs is =210
For size N=9
Unique pairs is =272
Interesting, the formula appears to be 2^2+2, 4^2+4, 6^2+6, 8^2+8 ...
I find it easiest to pick a representative object of each type of pair (in other words, the top object of a vertical pair, the left most of a horizontal pair, and take your pick for diagonal pairs). This gives n(n-1) vertical pairs, n(n-1) horizontal pairs, and 2(n-1)^2 diagonal pairs (equal amounts of each variety). That totals up to 2(n-1)(n+n-1)=2(n-1)(2n-1), in agreement with your guess.
Each row has n-1 intra-row pairs and there are n rows.
Each column has n-1 intra-column pairs and there are n columns.
Each adjacent pair of rows have 2*(n-1) diagonal pairs and there are (n-1) adjacent row pairs.
Multiply and add these numbers and you will get your solution.
Here's the fixed formula for counting unique pairs.
(4 C 2)*(N-1)^2 - 2*(N-2)*(N-1)
Basically you just use the approach in dasblinkenlight's answer and subtract the "duplicate" edges. The duplicate edges will always be the edges between quadrants. I've added an explanation for the counting of duplicates below.
Using the original formula (4 C 2) * (N-1)**2 for N > 2, you will count duplicates. What you want to do is subtract these duplicate edges from the calculation.
Let's examine the simplest cases for N > 2. Suppose N = 3.
0-1-2
|x*x|
3*4*5
|x*x|
6-7-8
See the places where I marked an asterisk instead of an edge? Those edges will be counted twice by the formula. We can calculate them by breaking them up into horizontal and vertical edges. The number of vertical edges that are counted twice will be (N-2)*(N-1).
In the case of N=3, this will be 1 * 2 = 2. The number of horizontal edges that are counted twice will also be (N-2)*(N-1).
So if we simply add up the number of duplicate vertical edges and duplicate horizontal edges, we get
(N-2)*(N-1) + (N-2)*(N-1) = 2*(N-2)*(N-1)
We can simply subtract that number from our total to get the right number of edges.
Testing count in Python:
from math import factorial
def choose(n, k):
return factorial(n)/(factorial(k) * factorial(n-k))
for N in range(2, 10):
print choose(4, 2) * (N-1)**2 - 2 * (N-2) * (N-1)
The program prints:
6
20
42
72
110
156
210
272

Finding a sub-array where every pair has sum greater than a given K

I have been given an array A of integers. Now I have to found out a sub-array(a sub-sequence of original array) where sum of every pair is greater than or equal to a pre-defined K.
What I thought :-
Will sort the array in O(nlgn) or O(n) depending upon range of values in array.
Find out i in sorted array such that sorted[i] + sorted[i+1]>=k
Set max to sorted[i]
Traverse the original array to delete all value smaller than max, which is the required sub-sequence
Repeat the above for all the elements of the array.
Running Time :- O(nlgn)
Is the solution optimal ? Can we further improve it ?
Example :-
-10 -100 5 2 4 7 10 23 81 5 25
Sorted Array
-100 -10 2 4 5 5 7 10 23 25 81
Let K = 20
Sub Array : -
10 23 25 81
Had the question been to find out longest sub-array, algorithm suggested by alestanis in the answers would work fine :)
Here is a fairly simple solution.
>>> def f(A, k):
... solution = [item for item in A if 2*item >= k]
... m = min(solution)
... for item in A:
... if item + m >= k and 2*item < k:
... solution.append(item)
... break
... return solution
...
>>> f([-10, -100, 5, 2, 4, 7, 10, 23, 81, 5, 25], 20)
[10, 23, 81, 25]
>>>
Here's a slightly different approach, hinted at by one of the earlier comments and similar to the answer by alestanis, but slightly different, in that it doesn't depend on splitting arrays. It makes a single pass through the array (although that doesn't guarantee O(N) ), and just needs to track the two minimum values as well as the start and end point of the subsequence being considered.
For a contiguous subsequence to have all possible pairs sum to 20, the sum of the two least elements must be >= 20. So start by considering subsequent pairs of elements (array[0] and array[1] to start). If they don't sum to 20 or more, then move on to array[1] and array[2]. If they add up to 20 or more, then expand the right hand endpoint by one. If the new element is greater than the other two, then it will sum to 20 or greater with anything already in the subsequence, and you can expand the right hand again. If it's less, then you need to pick the two least elements with a couple comparisons, and if the two new least elements now don't sum to 20 or more, then remove the element you've just added from the subsequence, and note this particular subsequence, then start over with the second and third elements of the existing subsequence. At the end, you will in general have a list of subsequences that fit the constraints, and it should be easy to pick the first or largest or whatever you need.
Example, using the sequence you listed:
-10 -100 5 2 4 7 10 23 81 5 25
Start with -10, -100. They don't sum to 20, so move right one to -100, 5. Again, these don't sum to 20, so continue. The first pair that does sum to 20 is 10, 23. So now, we expand the range to 10, 23, 81. 81 is greater than both the two minimums, so we expand again, to 10, 23, 81, 5. 5 is less than both 10 and 23, so the new minimums are 5 and 10, which don't sum to 20, so adding 5 was a mistake and we need to backtrack. We find 10, 23, 81 is one such subsequence. Next we continue with 23, 81, which will lead us to the subsequence 23, 81, 5, 25, which meets the criteria as well.
So, at the end, we have four possible subsequences that meet the critieria - 10, 23, 81, 23, 81, 5, 25, 81, 5, 25, and 5, 25. The last two could be pruned by not finding additional solutions once we have one that includes the last element in the original list, which would leave just the first two possibilities. From there we can pick either the first or the longest.
First of all, you can't sort your set. I think that part of the problem is to find sub-arrays of the original array given as input.
This can be solved using some recursion:
Find the two minimums of your array, m1 and m2
If m1 + m2 < K then split your array into at most two smaller arrays that don't contain m1 and m2 simultaneously. If indexes for m1 and m2 are i and j with i<j then subarrays are [O, j-1] and [i+1, n].
Repeat from step 1.
If m1 + m2 >= K then your current array is a feasible solution to your problem: return its length.
Add some pruning to discard useless arrays
Let's apply this on your example:
Initialize max = 0;
A1 = -10* -100* 5 2 4 7 10 23 81 5 25
Its two minimums are -10 and -100. Split the array around these values, which gives us only one array (we're lucky!)
A2 = 5 2* 4* 7 10 23 81 5 25
The two minimums of A2 are 2 and 4. We split into
A3_1 = 5* 4* and A3_2 = 2* 7 10 23 81 5* 25
This continues with the following iterations:
A3_1 discarded
A3_2 becomes A4_1 = 2* 7* 10 23 81 A4_2 = 7* 10 23 81 5* 25
A5_1 = 7* 10* 23 81
A5_2 = 7* 10* 23 81 -> Duplicate, discarded
A5_3 = 10* 23 81 5* 25
A6_1 = 10* 23* 81 -> Yay! update max = 3
A6_2 = 10* 23* 81 -> Length <= max. Discarded
A6_3 = 23 81 5* 25 -> Yay! update max = 4
In this example, I pruned the search space by:
Eliminating duplicate subsets (this can be done by storing them in a set for instance)
Discarding subarrays shorter or equal to the current max length known
This algorithm has a complexity of:
O(nlogn) average,
O(n^2) worst case. This happens when array is sorted and minimums are always on one of the sides of the array, so the array can't be split into smaller subarrays (like the first iteration of the example).
void sub_array(int ar[],int n,int val)
{
int max=0;
for(int i=0;i<n;i++)
{
if(ar[max]<ar[i])
max=i;
}
int b[n];
max=ar[max];
int p=0;
int min=0;
for(int i=0;i<n;i++)
{
if(ar[i]+max>val)
{
b[p]=ar[i];
if(ar[i]<max)
{
min=p;
max=ar[i];
}
p++;
}
else
{
if(ar[i]>max)
{
max=ar[i];
b[min]=ar[i];
}
}
}
for(int i=0;i<p;i++)
{
cout<<b[i]<< " " ;
}
}

Resources