% ./p2
combinations of 2 from: a b c
------------------------------
c a
c b
a b
permutations of 3 from: a b c
------------------------------
a b c
a c b
b a c
b c a
c a b
c b a
See perldoc Math::Combinatorics for details ... cheers, drl
Ok, here's a rough, kind of ugly brute force way using arrays with ksh93 on Solaris. Hopefully someone will come up with a more elegant solution. It loops 10 times, jumbling the blocks as the OP defined. If this is not exactly what you were looking for, hopefully you'll get some ideas.
#!/usr/dt/bin/dtksh
CHARSET="Abcdefghij1"
integer ctr=10 # Number of times to loop.
# Arrays for original blocks
set -A a_block1
set -A a_block2
set -A a_block3
# Arrays for new mixed blocks
set -A na_block1
set -A na_block2
set -A na_block3
# Split CHARSET into the original blocks.
for (( i=0;i<4;i++ ))
do
a_block1[${i}]=${CHARSET:${i}:1}
done
for (( i=0;i<3;i++ ))
do
a_block2[${i}]=${CHARSET:${i}+4:1}
done
for (( i=0;i<4;i++ ))
do
a_block3[${i}]=${CHARSET:${i}+7:1}
done
# Print out starting blocks.
print "Block 1: \"${a_block1[0]}${a_block1[1]}${a_block1[2]}${a_block1[3]}\""
print "Block 2: \"${a_block2[0]}${a_block2[1]}${a_block2[2]}\""
print "Block 3: \"${a_block3[0]}${a_block3[1]}${a_block3[2]}${a_block3[3]}\""
print
## Function to generate a random number between 1 and the number passed
## in inclusive. Sets $random_nbr.
get_random_nbr() {
if [[ $1 == 0 ]]; then
return 1
else
random_nbr=$(( ($RANDOM % $1 ) +1 ))
fi
}
# Mix 'em up. Jumble each block, copying into the new mixed array. Do it for each
# block. This should be made into a function but I just repeated it to get done quicker.
for (( k=0;k<${ctr};k++ ))
do
# For the length of the array...
for (( i=0;i<${#a_block1
[*]};i++ ))
do
# Get a random number...
get_random_nbr ${#a_block1
[*]}
(( j=$random_nbr -1 ))
# Use the random number as an index into the mixed array and see if
# it is not null.
while [[ -n ${na_block1[${j}]} ]]
do
# if not null, get another random number until the array location is null.
get_random_nbr ${#a_block1
[*]}
(( j=$random_nbr -1 ))
done
# The character at the index is null so plug in the character
# from the original array.
na_block1[${j}]=${a_block1[${i}]}
done
for (( i=0;i<${#a_block2
[*]};i++ ))
do
get_random_nbr ${#a_block2
[*]}
(( j=$random_nbr -1 ))
while [[ -n ${na_block2[${j}]} ]]
do
get_random_nbr ${#a_block2
[*]}
(( j=$random_nbr -1 ))
done
na_block2[${j}]=${a_block2[${i}]}
done
for (( i=0;i<${#a_block3
[*]};i++ ))
do
get_random_nbr ${#a_block3
[*]}
(( j=$random_nbr -1 ))
while [[ -n ${na_block3[${j}]} ]]
do
get_random_nbr ${#a_block3
[*]}
(( j=$random_nbr -1 ))
done
na_block3[${j}]=${a_block3[${i}]}
done
print "\"${na_block1[0]}${na_block1[1]}${na_block1[2]}${na_block1[3]}\" \c"
print "\"${na_block2[0]}${na_block2[1]}${na_block2[2]}${na_block2[3]}\" \c"
print "\"${na_block3[0]}${na_block3[1]}${na_block3[2]}${na_block3[3]}\""
# Clear the new array blocks for the next run.
set -A na_block1
set -A na_block2
set -A na_block3
done
exit 0