aboutsummaryrefslogtreecommitdiffhomepage
path: root/libslang/examples/sort.sl
blob: c2eb7adb74599e5f881653b59532846c67926524 (plain)
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 ();