Variable Alphabetics Permutation Algorithm - Simple yet mind-boggling - algorithm

I recently came across an apparently simple problem but it turned out to be SO mind boggling that I couldn't sleep for 2 days.
Here is the problem:
a variable will consist of number of characters -> Say $i=5. You need to print every possible alphabetical combination from $i=2 to $i=5.
The output for $i=5 needs to be:
aa
ab
ac
...
zz
aaa
aab
...
zzz
aaaa
aaab
....
zzzz
aaaaa
.....
zzzzz
You need to use ONLY for loops or foreach or while loops to achieve this (no functions to be used) and PRINT the output for each string formed instead of saving in an array. Please do not use a for loop inside of for loop inside of for loop because $i can be 100 or 200.
You can take an array of alphabets from 'a' to 'z'. Can someone please help me out with a simple elegant solution to this?

Before the loop you have an array aa. In the loop look at the array.
If the array is the sequence of all z then replace the contents with a sequence of all a that has a length incremented by 1. If new array has length larger than maximum then exit the loop.
Otherwise look at the tail of the array, which is always in the form Xz*, where X is any letter except z, followed by zero or more letters z. Replace this tail of the array with Ya*, where Y is the letter that follows X, ie. Y = X + 1, and a* is the sequence of letters a of the exact same length as was the original sequence of letters z (remember that length can be zero).
In any case write the new contents of the array to output and repeat the loop.
You'll need just two loops. Outer is the main loop that prints a new value in each iteration. Inner is the loop that converts all z's into a's.

Related

Pair up strings to form palindromes

Given N strings each of at max 1000 length. We can concatenate pair of strings by ends. Like if one is "abc" and other is "cba" then we can get "abccba" as well as "cbaabc". Some string may be left without concatenation to any other string. Also no string can be concatenated to itself.
We can only concatenate those two strings that form a palindrome. So I need to tell the minimum number of strings left after making such pairs.
Example : Let we have 9 strings :
aabbaabb
bbaabbaa
aa
bb
a
bbaa
bba
bab
ab
Then here answer is 5
Explanation : Here are 5 strings :
"aabbaabb" + "bbaabbaa" = "aabbaabbbbaabbaa"
"aa" + "a = "aaa"
"bba" + "bb" = "bbabb"
"bab" + "ab" = "babab"
"bbaa"
Also there can be 1000 such strings in total.
1) Make a graph where we have one node for each word.
2) Go through all pairs of words and check if they form palindrome if we concatenate them. If they do connect corresponding nodes in graph with edge.
3) Now use matching algorithm to find maximum number of edges you can match: http://en.wikipedia.org/wiki/Blossom_algorithm
Time complexity: O(N) for point 1, O(n*n*1000) for point 2 and O(V^4) for point 3 yielding total complexity of O(n^4).

How to get histogram data object from matlab

Lets say I have a matrix x=[ 1 2 1 2 1 2 1 2 3 4 5 ]. To look at its histogram, I can do h=hist(x).
Now, h with retrieve a matrix consisting only the number of occurrences and does not store the original value to which it occurred.
What I want is something like a function which takes a value from x and returns number of occurrences of it. Having said that, what one thing histeq does should we admire is, it automatically scales nearest values according!
How should solve this issue? How exactly people do it?
My reason of interest is in images:
Lets say I have an image. I want to find all number of occurrences of a chrominance value of image.
I'm not really shure what you are looking for, but if you ant to use hist to count the number of occurences, use:
[h,c]=hist(x,sort(unique(x)))
Otherwise hist uses ranges defined by centers. The second output argument returns the corresponding number.
hist has a second return value that will be the bin centers xc corresponding to the counts n returned in form of the first return value: [n, xc] = hist(x). You should have a careful look at the reference which describes a large number of optional arguments that control the behavior of hist. However, hist is way too mighty for your specific problem.
To simply count the number of occurrences of a specific value, you could simply use something like sum(x(:) == 42). The colon operator will linearize your image matrix, the equals operator will yield a list of boolean values with 1 for each element of x that was 42, and thus sum will yield the total number of these occurrences.
An alternative to hist / histc is to use bsxfun:
n = unique(x(:)).'; %'// values contained in x. x can have any number of dims
y = sum(bsxfun(#eq, x(:), n)); %// count for each value

Random access to an enumeration of sorted sets of 3 symbols from a fixed alphabet

Imagine we have an alphabet of, say, 5 chars: ABCDE.
We now want to enumerate all possible sets of 3 of those letters. Each letter can only be present once is a set, and the order of letters doesn't matter (hence the letters in the set should be sorted).
So we get the following sets:
ABC
ABD
ABE
ACD
ACE
ADE
BCD
BCE
BDE
CDE
For a total of 10 sets. The order is lexicographical.
Let's now assume that the alphabet length is N (5 in this example) and the length of the set in M (3 in this example). Knowing N and M, how could we, if at all possible:
Tell the total number of combinations in at worst O(M+N) (the answer is 10 in this example)?
Output the combination with any given number (given 1, return ABC; given 5, return ACE and so on) in at worst O(M+N)?
It's trivial to do those things with O(M^N) complexity by generating the whole list, but I wonder if there's a better solution.
The answer to the first question is straightforward: it is C(n,r), where we are to choose all combinations of r items from a set of size n. The formula is here among other places:
C(n,r) = n! / (r! (n-r)!)
The ability to select the i'th combination without computing all the others will depend on having an encoding that relates the combination number i to the combination. That would be much more challenging and will require more thought ...
(EDIT)
Having given the problem more thought, a solution looks like this in Python:
from math import factorial
def combination(n,r):
return factorial(n) / (factorial(r) * factorial(n-r))
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def showComb(n,r,i,a):
if r < 1:
return ""
rr = r-1
nn = max(n-1,rr)
lasti = i
i -= combination(nn,rr)
j = 0
while i > 0:
j += 1
nn = max(nn-1,1)
rr = min(rr,nn) # corrected this line in second edit
lasti = i
i -= combination(nn,rr)
return a[j] + showComb(n-j-1,r-1,lasti,a[(j+1):])
for i in range(10):
print(showComb(5,3,i+1,alphabet))
... which outputs the list shown in the question.
The approach I've used is to find the first element of the i'th output set using the idea that the number of combinations of the remaining set elements can be used to find which should be the first element for a given number i.
That is, for C(5,3), the first C(4,2) (=6) output sets have 'A' as their first character, then the next C(3,1) (=3) output sets have 'B' then C(1,1) (=1) sets have 'C' as their first character.
The function then finds the remaining elements recursively. Note that showComb() is tail-recursive so it could be expressed as a loop if you preferred, but I think the recursive version is easier to understand in this case.
For further testing, the following code may be useful:
import itertools
def showCombIter(n,r,i,a):
return ''.join(list(itertools.combinations(a[0:n],r))[i-1])
print ("\n")
# Testing for other cases
for i in range(120):
x = showComb(10,3,i+1,alphabet)
y = showCombIter(10,3,i+1,alphabet)
print(i+1,"\t",x==y,"\t",x,y)
... which confirms that all 120 examples of this case are correct.
I haven't calculated the time complexity exactly but the number of calls to showComb() will be r and the while loop will execute n times or fewer. Thus, in the terminology of the question, I am pretty sure the complexity will be less than O(M+N), if we assume that the factorial() function can be calculated in constant time, which I don't think is a bad approximation unless its implementation is naive.
Agree the first part is easy, put a similar equation to this into a language of your choice.
x=12
y=5
z=1
base=1
until [[ $z -gt y ]]
do
base=`echo $x $z $base|awk '{print ($1/$2) * $3}'`
x=`expr $x - 1`
z=`expr $z + 1`
echo base:$base
done
echo $base
The above example uses 12 Items, arranged in sets of 5 for 792 combinations.
To do the second part of your question... I am just thinking about it, but it is not straight forward by any stretch.

Algorithm to find

the logic behind this was (n-2)3^(n-3) has lots of repetitons like (abc)***(abc) when abc is at start and at end and the strings repated total to 3^4 . similarly as abc moves ahead and number of sets of (abc) increase
You can use dynamic programming to compute the number of forbidden strings.
The algorithms follow from the observation below:
"Legal string of size n is the legal string of size n - 1 extended with one letter, so that the last three letters of the resulting string are not all distinct."
So if we had all the legal strings of size n-1 we could try extending them to obtain the legal strings of size n.
To check whether the extended string is legal we just need to know the last two letters of the previous string (of size n-1).
In the algorithm we will compute two arrays, where
different[i] # number of legal strings of length i in which last two letters are different
same[i] # number of legal strings of length i in which last two letters are the same
It can be easily proved that:
different[i+1] = different[i] + 2*same[i]
same[i+1] = different[i] + same[i]
It is the consequence of the following facts:
Any 'same' string of size i+1 can be obtained either from 'same' string of size i (think BB -> BBB) or from 'different' string (think AB -> ABB) and these are the only options.
Any 'different' string of size i+1 can be obtained either from 'different' string of size i (think AB-> ABA ) or from the 'same' string in two ways (AA -> AAB or AA -> AAC)
Having observed all this it is easy to write an algorithm that computes the result in O(n) time.
I suggest you use recursion, and look at two numbers:
F(n), the number of legal strings of length n whose last two symbols are the same.
G(n), the number of legal strings of length n whose last two symbols are different.
Is that enough to go on?
get the ASCII values of the last three letters and add the square values of these letters. If it gives a certain result, then it is forbidden. For A, B and C, it would be fine.
To do this:
1) find out how to get characters from your string.
2) find out how to get ASCII value of a character.
3) Multiply these ASCII values with themselves.
4) Do that for the three letters each time and add their values.

dc(1) and leading zeros

I've got a shell script and I do some calculations with dc(1).
I need to have one number printed with leading zeros; I can't find an easy and straightforward way to do this with dc itself, but the manpage does mention:
Z
Pops a value off the stack, calculates the number of digits
it has (or number of characters, if it
is a string) and pushes that
number. The digit count for a
number does not include any leading
zeros, even if those appear to the
right of the radix point.
Which sort of implies there is an easy and straightforward way ...
I know there are a zillion-and-one method of accomplishing this, and I the script is running happily with one of them. I'm just curious ;-)
Give this a try:
Enter:
[lc1+dsc0nld>b]sb
[sddZdscld>bp]sa
999
12lax
Output:
000000999
Enter:
3lax
Output:
999
The original number is left on the stack after the macro ends. Registers used: a (macro), b (macro), c (count), d (digits).
Explanation:
Macro a does the setup, calls b and prints the original number.
sd - store the number of digits to be output in register d
dZ - duplicate the original number and push the count of its digits
dsc - duplicate that count and store it in register c
ld>b - load the desired digits from register d, if it's greater than the count then call macro b
p - print the original number
Macro b outputs zeros until the count is greater than the number of desired digits
lc1+ - load the count from register c and increment it
dsc - duplicate the count and store it back to register c
0n - output a zero without a newline
ld>b - load the desired digits from register d, if it's still greater than the incremented count then loop back to run macro b again, otherwise it will return to the caller (macro a)
To use an arbitrary leading character:
[lclkZ+dsclknld>b]sb
[sksddZdscld>bp]sa
999 14 [ ] lax
999
[abc] 12 [-] lax
---------abc
In addition to the other registers, it uses k to store the character (which could actually be more than one):
[XYZ] 6 [def] lax
defXYZ
8 [ab] lax
abababXYZ
4 [ghjikl] lax
ghijklXYZ
The fill strings are used whole so the result may be longer than you asked for if the desired length number is larger than the length of the original string, but smaller than the length of the two strings (or integer multiples).
Here is an example, albeit inelegant. This prints out 999 with 2 leading zeros. You'll need to duplicate the code for more digits.
#Push number to print on stack
999
# macro to print a zero
[[0]P]sa
# Print a zero if less than 5 digits
dZ5>a
# Print a zero if less than 4 digits
dZ4>a
# Print a zero if less than 3 digits
dZ3>a
# Print a zero if less than 2 digits
dZ2>a
# Print out number
p
The solutions given work for decimal numbers. For hex (as well as for any other input) radix use. e.g.
c=18A; dc <<< "16i${c^^}d0r[r1+r10/d0<G]dsGx4+r-[1-[0]nlGx]sY[d0<Y]dsGxr10op"
^ radix formatted length ^ ^ leading symbol
You may also try
c=19; dc <<< "10i${c^^}d0r[r1+r10/d0<G]dsGx4+r-[1-[_]nlGx]sY[d0<Y]dsGxr10op"
c=607; dc <<< " 8i${c^^}d0r[r1+r10/d0<G]dsGx8+r-[1-[*]nlGx]sY[d0<Y]dsGxr10op"
c=1001; dc <<< " 2i${c^^}d0r[r1+r10/d0<G]dsGx8+r-[1-[ ]nlGx]sY[d0<Y]dsGxr10op"
G and Y are the registers used. First the number of digits is counted on the stack, then the number of symbols to be printed.
c=607; dc <<< "8i${c^^}d0r[r1+r10/d0<G]dsGx f 8+r-[1-[*]nlGx]sY f [d0<Y]dsGxr10op"

Resources