1. Re[4]: How to make routine like this
- Posted by aku at inbox.as Dec 14, 2001
- 585 views
I think this is wrong... I get 151200 for ? get_permutation( digits, 5, 0 ) but I can't repair the problem ( I don't understand. ) Can you correct that? Thanks! e> Warning! Untested: e> function get_permutation(sequence symbolSet, integer len, integer e> permutation) e> sequence remaining, out e> integer max, pos, divisor, element e> integer setLength e> setLength = length(symbolSet) e> -- Calculate total mumber of permutations and generate an index list e> max = 1 e> remaining = repeat(0, setLength) e> for i = 1 to setLength e> remaining[i] = i e> if i >= len then e> max *= i e> end if e> end for e> -- Actions based on permutation number e> if permutation = 0 then e> -- Handy for calculating exactly how many permutations there are e> return max e> elsif not (1 <= permutation and permutation <= max) then e> -- There are no permutations outside the 1..max range e> return -1 e> end if e> -- Generate the output using some cunning math(s) e> out = {} e> pos = permutation e> divisor = max e> for i = 1 to len do e> divisor /= len - i + 1 e> element = floor(pos / divisor) e> pos -= divisor * element e> element += 1 e> out &= symbolSet[remaining[element]] e> remaining = e> remaining[1..element-1] & e> remaining[element+1..length(remaining)] e> end for e> return out e> end function e> sequence digits e> digits = {0,1,2,3,4,5,6,7,8,9} e> ? get_permutation( digits, 5, 0 ) e> -- prints the number of permutations of 'digits' with 5 elements. e> -- (should be 30240) e> ? get_permutation( digits, 5, 50000 ) e> -- prints -1 -- there is no 50000th 5-digit permutation of 'digits'. e> ? get_permutation( digits, 5, 29050 ) e> -- prints the 29050th 5-digit permutation of 'digits' e> To generate all possible combinations like last time: e> for i = 1 to get_permutation( digits, 5, 0 ) do e> ? get_permutation( digits, 5, i ) e> end for e> HTH, e> Carl
2. Re: Re[4]: How to make routine like this
- Posted by rforno at tutopia.com Dec 14, 2001
- 601 views
Aku: I sent to the list another routine, that was tested and is very fast. You might not have noticed it, so I am including it next now: function var (sequence set, integer size, integer which) integer c, len, a if size <= 0 then return {} elsif size = 1 then return {set[which]} end if len = length(set) c = 1 for i = len - size + 1 to len - 1 do c *= i end for a = floor((which - 1) / c) which -= a * c a += 1 return set[a] & var(set[1..a - 1] & set[a + 1..len], size - 1, which) end function for i = 1 to 60 do ? var({1, 2, 3, 4, 5}, 3, i) end for ----- Original Message ----- From: <aku at inbox.as> To: "EUforum" <EUforum at topica.com> Sent: Friday, December 14, 2001 11:12 AM Subject: Re[4]: How to make routine like this > > > I think this is wrong... > > I get 151200 for ? get_permutation( digits, 5, 0 ) > > but I can't repair the problem ( I don't understand. ) > > Can you correct that? Thanks! > > e> Warning! Untested: > > e> function get_permutation(sequence symbolSet, integer len, integer > e> permutation) > e> sequence remaining, out > e> integer max, pos, divisor, element > e> integer setLength > > e> setLength = length(symbolSet) > > e> -- Calculate total mumber of permutations and generate an index list > e> max = 1 > e> remaining = repeat(0, setLength) > e> for i = 1 to setLength > e> remaining[i] = i > e> if i >= len then > e> max *= i > e> end if > e> end for > > e> -- Actions based on permutation number > e> if permutation = 0 then > e> -- Handy for calculating exactly how many permutations there are > e> return max > e> elsif not (1 <= permutation and permutation <= max) then > e> -- There are no permutations outside the 1..max range > e> return -1 > e> end if > > e> -- Generate the output using some cunning math(s) > e> out = {} > e> pos = permutation > e> divisor = max > > e> for i = 1 to len do > e> divisor /= len - i + 1 > e> element = floor(pos / divisor) > e> pos -= divisor * element > e> element += 1 > e> out &= symbolSet[remaining[element]] > e> remaining = > e> remaining[1..element-1] & > e> remaining[element+1..length(remaining)] > e> end for > e> return out > e> end function > > e> sequence digits > e> digits = {0,1,2,3,4,5,6,7,8,9} > > e> ? get_permutation( digits, 5, 0 ) > e> -- prints the number of permutations of 'digits' with 5 elements. > e> -- (should be 30240) > > e> ? get_permutation( digits, 5, 50000 ) > e> -- prints -1 -- there is no 50000th 5-digit permutation of 'digits'. > > e> ? get_permutation( digits, 5, 29050 ) > e> -- prints the 29050th 5-digit permutation of 'digits' > > e> To generate all possible combinations like last time: > > e> for i = 1 to get_permutation( digits, 5, 0 ) do > e> ? get_permutation( digits, 5, i ) > e> end for > > e> HTH, > e> Carl > > > >
3. Re: Re[4]: How to make routine like this
- Posted by rforno at tutopia.com Dec 14, 2001
- 619 views
Aku: The following routine is tested. function var (sequence set, integer size, integer which) integer c, len, a if size <= 0 then return {} elsif size = 1 then return {set[which]} end if len = length(set) c = 1 for i = len - size + 1 to len - 1 do c *= i end for a = floor((which - 1) / c) which -= a * c a += 1 if a > len or a <= 0 then return - 1 end if return set[a] & var(set[1..a - 1] & set[a + 1..len], size - 1, which) end function for i = 1 to 100 do ? var({1, 2, 3, 4, 5}, 3, i) end for ? var({1, 2, 3, 4, 5}, 3, 0) ----- Original Message ----- From: <aku at inbox.as> To: "EUforum" <EUforum at topica.com> Sent: Friday, December 14, 2001 11:12 AM Subject: Re[4]: How to make routine like this > > > I think this is wrong... > > I get 151200 for ? get_permutation( digits, 5, 0 ) > > but I can't repair the problem ( I don't understand. ) > > Can you correct that? Thanks! > > e> Warning! Untested: > > e> function get_permutation(sequence symbolSet, integer len, integer > e> permutation) > e> sequence remaining, out > e> integer max, pos, divisor, element > e> integer setLength > > e> setLength = length(symbolSet) > > e> -- Calculate total mumber of permutations and generate an index list > e> max = 1 > e> remaining = repeat(0, setLength) > e> for i = 1 to setLength > e> remaining[i] = i > e> if i >= len then > e> max *= i > e> end if > e> end for > > e> -- Actions based on permutation number > e> if permutation = 0 then > e> -- Handy for calculating exactly how many permutations there are > e> return max > e> elsif not (1 <= permutation and permutation <= max) then > e> -- There are no permutations outside the 1..max range > e> return -1 > e> end if > > e> -- Generate the output using some cunning math(s) > e> out = {} > e> pos = permutation > e> divisor = max > > e> for i = 1 to len do > e> divisor /= len - i + 1 > e> element = floor(pos / divisor) > e> pos -= divisor * element > e> element += 1 > e> out &= symbolSet[remaining[element]] > e> remaining = > e> remaining[1..element-1] & > e> remaining[element+1..length(remaining)] > e> end for > e> return out > e> end function > > e> sequence digits > e> digits = {0,1,2,3,4,5,6,7,8,9} > > e> ? get_permutation( digits, 5, 0 ) > e> -- prints the number of permutations of 'digits' with 5 elements. > e> -- (should be 30240) > > e> ? get_permutation( digits, 5, 50000 ) > e> -- prints -1 -- there is no 50000th 5-digit permutation of 'digits'. > > e> ? get_permutation( digits, 5, 29050 ) > e> -- prints the 29050th 5-digit permutation of 'digits' > > e> To generate all possible combinations like last time: > > e> for i = 1 to get_permutation( digits, 5, 0 ) do > e> ? get_permutation( digits, 5, i ) > e> end for > > e> HTH, > e> Carl > > > >
4. Re: Re[4]: How to make routine like this
- Posted by rforno at tutopia.com Dec 16, 2001
- 545 views
John: There is no problem. The difference crops up because you are using puts() instead of ?. puts() prints the ASCII value instead of the numeric value. The result, in case the number of the permutation (I think that in this case it is called variation, but it was long ago when I left my statistics books...) is out of range, is -1. But if you use puts(), -1 prints as ASCII(255), which is what is called a "substitute blank" and, in fact, prints as a blank. 255 comes from the binary representation of -1, which is 11111111111...etc . puts() takes the 8 lower bits to show the ASCII value (please look at the Euphoria manual). If in the function you substitute -1 by '*', you will see an asterisk as the output. To make it more technical, the function returns a sequence with the correct permutation when the "which" parameter is in the right range, and an atom otherwise. Being L the length of the original sequence, and T the length of the intended result, the range is 1 to L * (L - 1) * ... * (L - T + 1) or factorial(L) / factorial(L - T). Out of curiosity: are you living in Portugal for work or just for pleasure? Regards. ----- Original Message ----- From: "John McAdam" <johnmcadam at clix.pt> To: "EUforum" <EUforum at topica.com> Sent: Wednesday, December 12, 2001 6:02 PM Subject: RE: Re[4]: How to make routine like this > > If the loop is too long (more than 100) it prints empty lines. > How do you know there are only 100 combinations? > I am using this only very slightly modified code, > replacing numbers with letters and increasing the > loop size to 125. > > > function var (sequence set, integer size, integer which) > integer c, len, a > > if size <= 0 then > return {} > elsif size = 1 then > return {set[which]} > end if > > len = length(set) > c = 1 > for i = len - size + 1 to len - 1 do > c *= i > end for > > a = floor((which - 1) / c) > which -= a * c > a += 1 > if a > len or a <= 0 then > return - 1 > end if > return set[a] & var(set[1..a - 1] & set[a + 1..len], size - 1, which) > end function > > for i = 1 to 125 do --125 is too many! > puts(1,var({'A','B','C','D','E'}, 5, i)&"\n") > end for > ? var({1, 2, 3, 4, 5}, 3, 0) > > > >