Unique Permutations - with exceptions - algorithm

I just did a quiz and it had a question that I brute forced... but I'm certain there is a "mathmatical" formula that "solves" it.
Permutations of a String
Say you have a string "abcdef"... count all unique permutations of the string. For a string with all unique options, this is simple: Length Factoral. So 6! = 720 unique combinations.
Unique Permutations
Now, when you add duplicates... you take the factoral, and devide by the product of the unique letters: "aaabbb" => 6! / (3! * 3!) => 720 / 36 => 20 unique combinations.
Unique Permutations, with exclusions
The part that stumps me:
You have a string, possibly with duplicate data... except now, exclude permutations that start with a space (or a dot, for visibility):
"aa.bb" => "aabb." is a valid permutation... ".aabb" is not.
"aa.bb.cc" => "aa..bbcc" valid permutation. ".aabbcc." not valid. "..aabbcc" is not valid
"a.." => has one valid permutation: "a.."... the others are all duplicates or start with spaces.
My Solution
My solution - brute force - was to create the permutations... and manually exclude those starting with spaces... O(N!) if I remember correctly.
I know it has something to do with factorals and the number of spaces. But the final answer eludes me.
I should be able to take the length, divide by the counts... and the calculate the distinct number that start with spaces and subtract that.

You partition the first character as a separate case: there are fewer choices for that character. This changes the first factor of the numerator of the calculation. For instance, aa.bb.cc has only 6 choices for the first character, not 8. Therefore, the calculation that was
8! / (2! 2! 2! 2!) -- four duplicates
is now
(6 * 7!) / (2! 2! 2! 2!) -- we still have four duplicates

Let's say that you have 5 unique letters,
so you'll have 5! combinations.
Now when you have 5 unique alphabets and one ., then
In the first position, you'll put one of those 5 alphabets. Then, you'll put the rest of them (4 alphabets and 1 .) in 5! ways,
The result being 5*5!
So, the answer according to me should be along the lines of
Let's say you have x unique alphabets, y alphabets in all and z spaces
So the answer should be
y * (y+z-1)! / (diving for repeated alphabets and spaces combinations)

Related

Encoding Permutations With Repeating Values

I'm trying to generate all combinations of A,B,C,D,E in three positions:
A,A,A
A,A,B
C,A,E
C,B,A
C,B,B
etc...
I've learned about factorial number systems and combinatorial number systems, but I'm still stuck finding the right implementation. Generally in the past I've used recursion to solve this problem, but in this case I don't want to generate the whole list to find one value, so I need an encoding.
Ideally I have an integer encoding for the combinations, so I can simply call a function with an iteration integer to generate the correct permutation.
Also what is this called and how can I learn more about the variations in approaches? Some similar solutions I've seen generate only non-repeating combinations (ABC,ABD) others don't reuse values.
My guess based on my past recursion approach is that permutation(0) would result in aaa and permutation(100) would result in adw.
The specific combinations you look for seem to be just "any of A,B,C,D,E on each position".
In this case, they are much akin a "pentary" (base 5) positional numeral system: you have three digits, and each of them may independently be 0 (A), 1 (B), 2 (C), 3 (D), or 4 (E).
The same goes for encoding these as integers: just number them from 0 to 53-1.
For a number k, the "combination" is "(k div 52) mod 5, (k div 51) mod 5, (k div 50) mod 5, with ABCDE encoded as 01234, respectively.
For a "combination" like "xyz", first map letters ABCDE to digits 01234 as x, y, and z, and then the encoding number is x*52 + y*51 + z*50.

Combining permutation groups

I am developing a probability analysis program for a board game. As part of an algorithm* I need to calculate the possible permutations of partitions of a number (plus some padding), such that all partition components cannot occupy any position that is lower than the total length of the permutation, in digits, minus the value of the component.
(It is extremely unlikely, however, that the number that will be partitioned will ever be higher than 8, and the length of the permutations will never be higher than 7.)
For instance, say I have the partition of 4, "211", and I want to find the permutations when there is a padding of 2, i.e. length of 5:
0 1 2 3 4 (array indexes)
5 4 3 2 1 (maximum value of partition component that can be allocated to each index)
2 1 1 _ _ (the partition plus 2 empty indexes)
This is represented as an array like so {2,1,1,0,0}
There are 6 permutations when 2 is in the 0 index (4! / 2! 2!), and there are 4 indexes that 2 can occupy (2 cannot be placed into the last index) so overall there are 24 permutations for this case (a 1 can occupy any index).
The output for input "21100":
21100, 21010, 21001, 20110, 20101, 20011
02110, 02101, 02011, 12100, 12010, 12001
00211, 10210, 11200, 10201, 01210, 01201
10021, 01021, 00121, 11020, 10120
01120
Note that this is simply the set of all permutations of "21100" minus those where 2 is in the 4th index. This is a relatively simple case.
The problem can be described as combining n different permutation groups, as the above case can be expressed as the combining of the permutations of x=1 n=4 and those of x=2 n=5, where x is the value count and n is the "space" count.
My difficulty is formulating a method that can obtain all possibilities computationally, and any advice would be greatly appreciated. -Please excuse any muddling of terminology in my question.
*The algorithm answers the following question:
There is a set of n units that are attacked k times. Each
attack has p chance to miss and q (1 - p) chance to damage
a random unit from the set. A unit that is damaged for a second time is destroyed
and is removed from the set.
What is the probability of there being
x undamaged units, y damaged units and z destroyed units after the attacks?
If anyone knows a more direct approach to this problem, please let me know.
I am going to use the algorithm to generate all permutations of the multiset as given in the answer to this question
How to generate all the permutations of a multiset?
and then filter to fit my criteria.

Number of possible palindrome anagrams for a given word

I have to find No. of palindrome anagrams are possible for a given word.
Suppose the word is aaabbbb.My approach is
Prepare a hash map that contains no. of time each letter is appearing
For my example it will be
a--->3
b--->4
If length of string is even then no. of occurrence of each letter should be even to form palindrome of given word else no of
palindrome anagrams is 0
If length of string is odd then at max one occurrence of letter can be odd and other should be even.
This two above steps was for finding that weather a given word can can form palindrome or not.
Now for finding no of palindrome anagrams, what approach should I follow?
First thing to notice is that if the word is an odd length, then there must be exactly one character with an odd number of occurrences. If the word is an even length, then there must be no characters with an odd number of occurrences. In either case, you're looking for how many ways you can arrange the pairs of characters. You're looking for the number of permutations since order matters:
n = number of character pairs (aaaabbb would have 3 pairs, aabbcccc would have 4 pairs)
(n)!/( number_of_a_pairs! * number_of_b_pairs! * etc..)
So in the aaaabbb case, you're finding the permutations of aab:
3!/2!1! = 3
baa = baabaab
aba = abababa
aab = aabbbaa
And in the aabbcccc case, you're finding the permutations of abcc:
4!/2! = 12:
abcc
acbc
accb
bacc
bcac
bcca
cabc
cacb
cbac
cbca
ccab
ccba

Using dynamic programming to count the number of permutations

I have a string A of length N. I have to find number of strings (B) of length N that have M (M<=N) same characters as string A but satisfies the condition that A[i]!=B[i] for all i. Assume the characters that have to be same and the different ones are also given. What will be the recurrence relation to find number of such strings?
Example
123 is string A and M=1, and the character which is same is '1', and the new characters are '4' and '5'. The valid permutations are 451, 415, 514, 541. So it is a sort of derangement of 1 item of the given 3.
I am able to find the answer using inclusion-exclusion principle but wanted to know whether there is a recurrence relation to do the same?
Let us call g(M,N) the number of permutations satisfying your condition.
If M is 0, then the answer is N!
Otherwise, M>0 and consider placing the first character that is in string A.
There are M important positions corresponding to the places in the string where we are not allowed to place a certain character.
If we put our first character in one of these (M-1) important places (we cannot put it in position 1 due to the restriction), then we must take the place of one of the restricted characters, and so the number of restrictions reduces by 2 (1 for the character we place, and 1 for the character whose position we occupied).
If we put our first character in one of the N-M unimportant places, then we have only reduced the number of restrictions by 1.
Therefore the recurrence relation is:
g(M,N)=(M-1)g(M-2,N-1)+(N-M)g(M-1,N-1) if M>0
=N! if M=0
For your example, we wish to calculate g(1,3) (1 character matches, total of 3 characters placed)
g(1,3)=(3-1)g(0,2)
=(3-1).2!
=4

String to Number and back algorithm

This is a hard one (for me) I hope people can help me. I have some text and I need to transfer it to a number, but it has to be unique just as the text is unique.
For example:
The word 'kitty' could produce 12432, but only the word kitty produces that number. The text could be anything and a proper number should be given.
One problem the result integer must me a 32-bit unsigned integer, that means the largest possible number is 2147483647. I don't mind if there is a text length restriction, but I hope it can be as large as possible.
My attempts. You have the letters A-Z and 0-9 so one character can have a number between 1-36. But if A = 1 and B = 2 and the text is A(1)B(2) and you add it you will get the result of 3, the problem is the text BA produces the same result, so this algoritm won't work.
Any ideas to point me in the right direction or is it impossible to do?
Your idea is generally sane, only needs to be developed a little.
Let f(c) be a function converting character c to a unique number in range [0..M-1]. Then you can calculate result number for the whole string like this.
f(s[0]) + f(s[1])*M + f(s[2])*M^2 + ... + f(s[n])*M^n
You can easily prove that number will be unique for particular string (and you can get string back from the number).
Obviously, you can't use very long strings here (up to 6 characters for your case), as 36^n grows fast.
Imagine you were trying to store Strings from the character set "0-9" only in a number (the equivalent of obtaining a number of a string of digits). What would you do?
Char 9 8 7 6 5 4 3 2 1 0
Str 0 5 2 1 2 5 4 1 2 6
Num = 6 * 10^0 + 2 * 10^1 + 1 * 10^2...
Apply the same thing to your characters.
Char 5 4 3 2 1 0
Str A B C D E F
L = 36
C(I): transforms character to number: C(0)=0, C(A)=10, C(B)=11, ...
Num = C(F) * L ^ 0 + C(E) * L ^ 1 + ...
Build a dictionary out of words mapped to unique numbers and use that, that's the best you can do.
I doubt there are more than 2^32 number of words in use, but this is not the problem you're facing, the problem is that you need to map numbers back to words.
If you were only mapping words over to numbers, some hash algorithm might work, although you'd have to work a bit to guarantee that you have one that won't produce collisions.
However, for numbers back to words, that's quite a different problem, and the easiest solution to this is to just build a dictionary and map both ways.
In other words:
AARDUANI = 0
AARDVARK = 1
...
If you want to map numbers to base 26 characters, you can only store 6 characters (or 5 or 7 if I miscalculated), but not 12 and certainly not 20.
Unless you only count actual words, and they don't follow any good countable rules. The only way to do that is to just put all the words in a long list, and start assigning numbers from the start.
If it's correctly spelled text in some language, you can have a number for each word. However you'd need to consider all possible plurals, place and people names etc. which is generally impossible. What sort of text are we talking about? There's usually going to be some existing words that can't be coded in 32 bits in any way without prior knowledge of them.
Can you build a list of words as you go along? Just give the first word you see the number 1, second number 2 and check if a word has a number already or it needs a new one. Then save your newly created dictionary somewhere. This would likely be the only workable solution if you require 100% reliable, reversible mapping from the numbers back to original words given new unknown text that doesn't follow any known pattern.
With 64 bits and a sufficiently good hash like MD5 it's extremely unlikely to have collisions, but for 32 bits it doesn't seem likely that a safe hash would exist.
Just treat each character as a digit in base 36, and calculate the decimal equivalent?
So:
'A' = 0
'B' = 1
[...]
'Z' = 25
'0' = 26
[...]
'9' = 35
'AA' = 36
'AB' = 37
[...]
'CAB' = 46657

Resources