File: sort.sl

package info (click to toggle)
slang2 2.3.0-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 10,588 kB
  • ctags: 10,558
  • sloc: ansic: 95,506; sh: 3,277; makefile: 945; pascal: 143
file content (58 lines) | stat: -rwxr-xr-x 1,532 bytes parent folder | download | duplicates (7)
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
#! /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.

private variable Keys, Values;
private 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 slsh_main ()
{
   variable line, len, i, vals;
   foreach line (stdin)
     {
	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 = atoi (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], " "));
     }
}