Script to output custom characters in different order

Need a script to print a set of characters in different combination. What's the key to accomplish this.

e.g charset: "Abcdefghij1" without quotes.

block 1: "Abcd"
block 2: "efg"
block 3: "hij1"

I need this script to change the order of the characters and print it to stdout
e.g
print out the blocks separately

"Abcd" "efg" "hij1"
"Acbd" "feg" "h1ji"
"Adbc" "fge" "j1hi"
...

Or is there a better way to accomplish this with something else?

Hi.

Here's a perl script that uses a module for the hard parts:

#!/usr/bin/env perl

# @(#) p2	Demonstrate combinations and permutations.

use Math::Combinatorics;

my @n = qw(a b c);
print "combinations of 2 from: " . join( " ", @n ) . "\n";
print "------------------------" . ( "--" x scalar(@n) ) . "\n";
print join( "\n", map { join " ", @$_ } combine( 2, @n ) ), "\n";
print "\n";
print "permutations of 3 from: " . join( " ", @n ) . "\n";
print "------------------------" . ( "--" x scalar(@n) ) . "\n";
print join( "\n", map { join " ", @$_ } permute(@n) ), "\n";

exit(0);

producing:

% ./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

Thanx drl. I'll try to change your code to fit my need. I have no pre-knowledge off working with perl though

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. :slight_smile:

#!/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

Output:

$ efs
Block 1: "Abcd"
Block 2: "efg"
Block 3: "hij1"

"Adbc" "egf" "h1ji"
"Abcd" "feg" "h1ij"
"cdbA" "feg" "hj1i"
"cdAb" "gfe" "jhi1"
"cdbA" "egf" "ji1h"
"dbcA" "feg" "ij1h"
"Acdb" "egf" "h1ij"
"bdcA" "gef" "h1ji"
"bdcA" "egf" "ji1h"
"bcdA" "gef" "ji1h"
$