Number of valid parenthesis - algorithm

I have to find out the number of valid parenthesis.Parenthesis are of two type [] ,(). How many ways are there to construct a valid sequence using X and Y number of [] ,(). For this problem we consider ([]) is invalid way i.e () can't hold [].
Is there any better solution than recursion.
For Example X=1 and Y=1
[]()
()[]
[()]

For any given combination of grouped, self-enclosed round parentheses and a given arrangement of square brackets, we can use the multiset combination to determine the number of arrangements:
n + k - 1 choose k, where k is the smaller of the number of self-enclosed parenthetical groups and the total number of square brackets, and n is the larger of the two + 1.
The number of arragements of square brackets is the nth Catalan number.
One way to generate the groups of parentheses is to assign an increasing number of groups, and calculate the number of distinct permutations for each partition of (X - number of assigned groups) multiplied by the sum of the parts-as-nth-Catalan. For example:
X = 4
Counts for each grouping:
1 group: Cat 3
2 groups: Cat 2 * 2 + 1 // partitions [2,0] * 2 and [1,1]
3 groups: 3 // partition [1,0,0] * 3
4 groups: 1 // partition [0,0,0,0]
I have yet to think of a way to avoid the partitions and would be interested to learn.

Because square brackets cannot be inside round brackets, every sequence of round brackets has to be complete (i.e. the count of the number of open minus close brackets is back down to zero) before each occurance of a square bracket.
1 012 1 0
()[(())()][[()()]((()))]()
10 121010 1010 123210 10
This effectively means that the square brackets split the round brackets into seperate independent sequences:
1 0 1 2 1 0
...[...]...[...[...]...]...
where complete sequences of round brackets can be placed anywhere between the square brackets.
As mentioned by Paul Hankin, the number of valid sequences of just one type of brackets is given by the Catalan Number. This gives you the number of valid sequences for the square brackets, and the number of valid sequences for any number of round brackets to be inserted somewhere inbetween the square brackets.
Unfortunately, finding out in what ways the round brackets can be distributed to the different locations inbetween the square brackets is a partitioning problem, and the logical way to solve this is by recursion. So this train of thought could lead to an algorithm, but not to one which avoids recursion.
However, the number of recursions needed to find partitions is much smaller than the Catalan number (e.g. 20 has 627 partitions, but the Catalan number for 20 is 6,564,120,420), so this method will be much faster than recursively enumerating every valid sequence.
Here's a simple example to demonstrate how this would work:
X=2, Y=3
The valid sequences of square brackets:
CatalanNumber(2) = 2
1. [ ] [ ]
2. [ [ ] ]
The positions for the round brackets:
2 × X + 1 = 5
1[2]3[4]5
1[2[3]4]5
The partitions of the round brackets:
p(Y) = 3
3
2,1
1,1,1
The permutations of the partitions:
partition: 3 (number of parts: 1)
→ 5 = 5
3,0,0,0,0 0,3,0,0,0 0,0,3,0,0 0,0,0,3,0 0,0,0,0,3
partition: 2,1 (number of parts: 2)
→ 5 × 4 = 20
2,1,0,0,0 2,0,1,0,0 2,0,0,1,0 2,0,0,0,1
1,2,0,0,0 0,2,1,0,0 0,2,0,1,0 0,2,0,0,1
1,0,2,0,0 0,1,2,0,0 0,0,2,1,0 0,0,2,0,1
1,0,0,2,0 0,1,0,2,0 0,0,1,2,0 0,0,0,2,1
1,0,0,0,2 0,1,0,0,2 0,0,1,0,2 0,0,0,1,2
partition: 1,1,1 (number of parts: 3, identical: 3)
→ (5 × 4 × 3) / (1 × 2 × 3) = 10
1,1,1,0,0 1,1,0,1,0 1,1,0,0,1
1,0,1,1,0 1,0,1,0,1 1,0,0,1,1
0,1,1,1,0 0,1,1,0,1 0,1,0,1,1 0,0,1,1,1
The valid sequences of round brackets:
CatalanNumber(3) = 5
1. ()()()
2. ()(())
3. (())()
4. (()())
5. ((()))
CatalanNumber(2) = 2
1. ()()
2. (())
CatalanNumber(1) = 1
1. ()
CatalanNumber(0) = 1
1.
The valid sequences per partition:
3,0,0,0,0 5 x 1 x 1 x 1 x 1 = 5
2,1,0,0,0 2 x 1 x 1 x 1 x 1 = 2
1,1,1,0,0 1 x 1 x 1 x 1 x 1 = 1
The total number of valid sequences:
Square brackets: 2
Round Brackets: 75
5 x 5 = 25
20 x 2 = 40
10 x 1 = 10
Total: 2 × 75 = 150

Related

Diagonal Matrices in J

I do a lot of work with eigenvalues and hence building / unbuilding diagonal matrices is something I do a lot. In the spirit of J, I've come up with some simple definitions, but wonder if I have missed a simpler way? I couldn't find anything in the phrasebook, but may have been looking in the wrong place.
Make Diagonal matrix from list of diagonal entries:
diag =: * =#i.##
Extract diagonal entries from a matrix:
extract =: +/#(* =#i.##)
Diagonal entries of a matrix have a standar definition in J:
extract =: (<0 1)&|:
This is, unfortunately, hidden somewhere in the vocabulary. (You can see it passing in transpose)
I usually use diag as
diag =: 3 :'(2##y) $ ,_1 (((#y)#0),~])\y'
but I no longer remember why. Your version is better.
(* =) 2 3 4
2 0 0
0 3 0
0 0 4
If you are working with unique elements.
diag=: * = NB. a hook defined tacitly
diag 89 3 56.6
89 0 0
0 3 0
0 0 56.6
The = breaks down if the elements are not unique as the matrix is no longer square
diag 3 4 4
|length error: diag
| diag 3 4 4
Another solution involves using "copy-fill".
diag =: (2 ##) $ (#~ 1 j. #)
This is longer than OP's original formulation, but it works for both numbers and characters (as long as you want spaces to play the role of zero).
Short explanation (primarily for "future me", as I'm fairly new to J):
Consider the following example (with y =: 1 2 5 7 representing the diagonal entries):
4 4 $ 1j4 # y NB. the required diagonal matrix
The complex number argument 1j4 to the left of # inserts 4 zeros after every copied item from y. Reshaping this into a 4 x 4 matrix gives the diagonal matrix.
The 4's above are nothing but the number of items in y: #y. So we can generalise as (2 # #y) $ (1 j. #y) # y. The tacit equivalent of this is given at the top.

Cannot understand an answer to an algorithm

I was doing this question today.
Basically, question asks for the largest 'Decent' Number having N digits where 'Decent' number is:
Only 3 and 5 as its digits.
Number of times 3 appears is divisible by 5.
Number of times 5 appears is divisible by 3.
Input Format
The 1st line will contain an integer T, the number of test cases,
followed by T lines, each line containing an integer N i.e. the number
of digits in the number
Output Format
Largest Decent number having N digits. If no such number exists, tell
Sherlock that he is wrong and print '-1'
Sample Input
4
1
3
5
11
Sample Output
-1
555
33333
55555533333
Explanation
For N=1 , there is no such number. For N=3, 555 is only possible
number. For N=5, 33333 is only possible number. For N=11 , 55555533333
and all of permutations of digits are valid numbers, among them, the
given number is the largest one.
I've solved it using normal method but saw this answer:
t = int(raw_input())
for _ in range(t):
n = int(raw_input())
c3 = 5*(2*n%3)
if c3 > n:
print -1
else:
print '5' * (n-c3) + '3'*c3
Can anyone explain the method please? Especially the line 'c3 = 5*(2*n%3)', thanks
We are looking for integer solutions of n = 5*x + 3*y where 5*x is the number of 3s and 3*y is the number of 5s. Both x and y must be >= 0 and x should be as small as possible since we can build larger numbers if we have more 5s.
Transforming this gives y = (n-5*x)/3. In order for y to be an integer n-5*x must be a multiple of 3 so we can calculate modulo 3 (I write == for is congruent modulo 3 from now on).
n-5*x == 0
n == 5*x == 2*x (because 5 == 2)
multiplying both sides by 2 gives
2*n == 4*x == x (because 4 == 1)
Since we want x small we take x = 2 * n % 3 and y = (n-5*x)/3
There is no solution if y < 0.

Arithmetic operation on sequence on integers

I have N integers numbers: 1,2,3...N
The task is to use +,-,*,/ to make expression 0.
For example -1*2+3+4-5=0
How can I do it?
May be some code on C/C++ ?
If N % 4 == 0, for every four consecutive integers a, b, c, d, take a - b - c + d
If N % 4 == 1, use 1 * 2 to start, then proceed as before. (i.e., 1*2 - 3 - 4 + 5 + 6 - 8 - 8 + 9 ...)
If N % 4 == 2, start with 1 - 2 + 3 * 4 - 5 - 6, then proceed as in the N % 4 == 0 example.
If N % 4 == 3, start with 1 + 2 - 3, then proceed as in the N%4 == 0 example.
All of these find a way to get zero out of the first few integers, leaving a multiple of four integers to work on, then take advantage of the fact that the pattern a - b - c + d = 0 for any four consecutive integers.
This is essentially SAT, or do you know that the numbers are a sequence (e.g. 2 1 8 is forbidden). What about negative numbers?
If the sequence is not too large, i would recommend to simply bootforce it. A greedy solution would be to reduce the problem by finding subsets which can be evaluated to zero.

Minimize maximum absolute difference in pairs of numbers

The problem statement:
Give n variables and k pairs. The variables can be distinct by assigning a value from 1 to n to each variable. Each pair p contain 2 variables and let the absolute difference between 2 variables in p is abs(p). Define the upper bound of difference is U=max(Abs(p)|every p).
Find an assignment that minimize U.
Limit:
n<=100
k<=1000
Each variable appear at least 2 times in list of pairs.
A problem instance:
Input
n=9, k=12
1 2 (meaning pair x1 x2)
1 3
1 4
1 5
2 3
2 6
3 5
3 7
3 8
3 9
6 9
8 9
Output:
1 2 5 4 3 6 7 8 9
(meaning x1=1,x2=2,x3=5,...)
Explaination: An assignment of x1=1,x2=2,x3=3,... will result in U=6 (3 9 has greastest abs value). The output assignment will get U=4, the minimum value (changed pair: 3 7 => 5 7, 3 8 => 5 8, etc. and 3 5 isn't changed. In this case, abs(p)<=4 for every pair).
There is an important point: To achieve the best assignments, the variables in the pairs that have greatest abs must be change.
Base on this, I have thought of a greedy algorithm:
1)Assign every x to default assignment (x(i)=i)
2)Locate pairs that have largest abs and x(i)'s contained in them.
3)For every i,j: Calculate U. Swap value of x(i),x(j). Calculate U'. If U'<U, stop and repeat step 3. If U'>=U for every i,j, end and output the assignment.
However, this method has a major pitfall, if we need an assignment like this:
x(a)<<x(b), x(b)<<x(c), x(c)<<x(a)
, we have to swap in 2 steps, like: x(a)<=>x(b), then x(b)<=>x(c), then there is a possibility that x(b)<<x(a) in first step has its abs become larger than U and the swap failed.
Is there any efficient algorithm to solve this problem?
This looks like http://en.wikipedia.org/wiki/Graph_bandwidth (NP complete, even for special cases). It looks like people run http://en.wikipedia.org/wiki/Cuthill-McKee_algorithm when they need to do this to try and turn a sparse matrix into a banded diagonal matrix.

How can I take the modulus of two very large numbers?

I need an algorithm for A mod B with
A is a very big integer and it contains digit 1 only (ex: 1111, 1111111111111111)
B is a very big integer (ex: 1231, 1231231823127312918923)
Big, I mean 1000 digits.
To compute a number mod n, given a function to get quotient and remainder when dividing by (n+1), start by adding one to the number. Then, as long as the number is bigger than 'n', iterate:number = (number div (n+1)) + (number mod (n+1))Finally at the end, subtract one. An alternative to adding one at the beginning and subtracting one at the end is checking whether the result equals n and returning zero if so.
For example, given a function to divide by ten, one can compute 12345678 mod 9 thusly:
12345679 -> 1234567 + 9
1234576 -> 123457 + 6
123463 -> 12346 + 3
12349 -> 1234 + 9
1243 -> 124 + 3
127 -> 12 + 7
19 -> 1 + 9
10 -> 1
Subtract 1, and the result is zero.
1000 digits isn't really big, use any big integer library to get rather fast results.
If you really worry about performance, A can be written as 1111...1=(10n-1)/9 for some n, so computing A mod B can be reduced to computing ((10^n-1) mod (9*B)) / 9, and you can do that faster.
Try Montgomery reduction on how to find modulo on large numbers - http://en.wikipedia.org/wiki/Montgomery_reduction
1) Just find a language or package that does arbitrary precision arithmetic - in my case I'd try java.math.BigDecimal.
2) If you are doing this yourself, you can avoid having to do division by using doubling and subtraction. E.g. 10 mod 3 = 10 - 3 - 3 - 3 = 1 (repeatedly subtracting 3 until you can't any more) - which is incredibly slow, so double 3 until it is just smaller than 10 (e.g. to 6), subtract to leave 4, and repeat.

Resources