## sort-array.pl

In class someone asked about sorting an array, but preserving the information about where a value had come from in the source array. For examples, given the array:

 Index Value 0 1 2 3 4 'e' 'c' 'a' 'b' 'd'

we should be able to output:

```0. a (came from 2)
1. b (came from 3)
2. c (came from 1)
3. d (came from 4)
4. e (came from 0)
```

This program does exactly that, in several different ways. This is by no means exhaustive, but it covers a number of techniques.

```#! /usr/bin/perl
use strict;
use warnings;

my(@input) = ('e','c','a','b','d');

# This is the solution I created on the chalkboard in class:
my @indices = 0..(scalar(@input) - 1);
my(@sorted_indices) = sort { \$input[\$a] cmp \$input[\$b] } @indices;
for(my \$i = 0; \$i < @sorted_indices; \$i++) {
my \$original_index = \$sorted_indices[\$i];
my \$value = \$input[\$original_index];
print "\$i. \$value (came from \$original_index)\n";
}
print "---\n";

# We can implement the solution above, but using a hash.  It doesn't
# get us much.
my %input;
for(my \$i = 0; \$i < @input; \$i++) {
\$input{\$i} = \$input[\$i];
}
@sorted_indices = sort { \$input{\$a} cmp \$input{\$b} } keys %input;
for(my \$i = 0; \$i < @sorted_indices; \$i++) {
my \$original_index = \$sorted_indices[\$i];
my \$value = \$input{\$original_index};
print "\$i. \$value (came from \$original_index)\n";
}
print "---\n";

# We can put the values in the keys of the hash.  This might make the code more
# straightforward, but fails if the same value appears in the array twice!
%input = (); # Reset hash
for(my \$i = 0; \$i < @input; \$i++) {
if(exists \$input{\$input[\$i]}) {
die "FATAL ERROR: \$input[\$i] appears twice in this array and it can not be represented!";
}
\$input{\$input[\$i]} = \$i;
}
my @sorted_values = sort keys %input;
for(my \$i = 0; \$i < @sorted_values; \$i++) {
my \$value = \$sorted_values[\$i];
my \$original_index = \$input{\$value};
print "\$i. \$value (came from \$original_index)\n";
}
print "---\n";

# Finally, we might store the original index alongside the data.
my @input_pairs;
for(my \$i = 0; \$i < @input; \$i++) {
\$input_pairs[\$i] = [\$input[\$i], \$i];
}
my @sorted_pairs = sort { \$a->[0] cmp \$b->[0] } @input_pairs;
for(my \$i = 0; \$i < @sorted_pairs; \$i++) {
my \$value = \$sorted_pairs[\$i][0];
my \$original_index = \$sorted_pairs[\$i][1];
print "\$i. \$value (came from \$original_index)\n";
}
print "---\n";
```