1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
#! /usr/bin/env slsh
% This program presents the solution to a problem posed by
% Tom Christiansen <tchrist@mox.perl.com>. The problem reads:
%
% Sort an input file that consists of lines like this
%
% var1=23 other=14 ditto=23 fred=2
%
% such that each output line is sorted WRT to the number. Order
% of output lines does not change. Resolve collisions using the
% variable name. e.g.
%
% fred=2 other=14 ditto=23 var1=23
%
% Lines may be up to several kilobytes in length and contain
% zillions of variables.
%---------------------------------------------------------------------------
%
% The solution presented below works by breaking up the line into an
% array of alternating keywords and values with the keywords as the even
% elements and the values as the odd. It is about 30% faster than the
% python solution.
static variable Keys, Values;
static define sort_fun (i, j)
{
variable s, a, b;
s = Values[i] - Values[j];
!if (s)
return strcmp (Keys[i], Keys[j]);
return s;
}
define main ()
{
variable line, len, i, vals;
foreach (stdin)
{
line = ();
line = strtok (line, " \t\n=");
len = length(line)/2;
if (len == 0)
continue;
% Even elements are keys, odd are values
Keys = line[[0::2]];
vals = line[[1::2]];
Values = array_map(Int_Type, &integer, vals);
i = array_sort ([0:len-1], &sort_fun);
% There are different ways of writing the result. Here is a
% fast way that avoids a loop.
() = printf ("%s\n", strjoin (Keys[i] + "=" + vals[i], " "));
}
}
main ();
|