I would like to generate a permutation of some lines. We have random,
which is vageuly similar. This adds a -p option to instead permute
instead of randomly select.

Index: random.6
===================================================================
RCS file: /cvs/src/games/random/random.6,v
retrieving revision 1.7
diff -u -p -r1.7 random.6
--- random.6    31 May 2007 19:19:18 -0000      1.7
+++ random.6    22 Dec 2014 20:57:06 -0000
@@ -37,7 +37,7 @@
 .Nd random lines from a file or random numbers
 .Sh SYNOPSIS
 .Nm random
-.Op Fl er
+.Op Fl epr
 .Op Ar denominator
 .Sh DESCRIPTION
 .Nm
@@ -58,6 +58,8 @@ does not read or write anything, and sim
 exit value of 0 to
 .Ar denominator
 \&- 1, inclusive.
+.It Fl p
+Read lines from standard input and output a permutation of all of them.
 .It Fl r
 The
 .Fl r
Index: random.c
===================================================================
RCS file: /cvs/src/games/random/random.c,v
retrieving revision 1.12
diff -u -p -r1.12 random.c
--- random.c    27 Oct 2009 23:59:26 -0000      1.12
+++ random.c    22 Dec 2014 20:55:31 -0000
@@ -40,6 +40,7 @@
 #include <err.h>
 #include <errno.h>
 #include <stdio.h>
+#include <string.h>
 #include <stdlib.h>
 #include <time.h>
 #include <unistd.h>
@@ -47,6 +48,42 @@
 
 void usage(void);
 
+static void
+permute(void)
+{
+       char **array = NULL;
+       size_t numlines = 0;
+       size_t maxlines = 0;
+       size_t linelen;
+       char *line;
+       size_t j;
+
+       while ((line = fgetln(stdin, &linelen))) {
+               if (line[linelen - 1] == '\n')
+                       linelen--;
+               if (numlines == maxlines) {
+                       maxlines = maxlines ? maxlines : 16;
+                       array = reallocarray(array, maxlines,
+                           2 * sizeof(char *));
+                       if (!array)
+                               err(1, "out of memory");
+                       maxlines *= 2;
+               }
+               if (!(array[numlines] = strndup(line, linelen)))
+                       err(1, "out of memory");
+               numlines++;
+       }
+       for (j = numlines; j > 1; j--) {
+               size_t s = arc4random_uniform(j);
+               char *tmp = array[s];
+               array[s] = array[j - 1];
+               array[j - 1] = tmp;
+       }
+       for (j = 0; j < numlines; j++)
+               puts(array[j]);
+}
+
+
 int
 main(int argc, char *argv[])
 {
@@ -55,7 +92,7 @@ main(int argc, char *argv[])
        char *ep;
 
        random_exit = unbuffer_output = 0;
-       while ((ch = getopt(argc, argv, "erh")) != -1)
+       while ((ch = getopt(argc, argv, "eprh")) != -1)
                switch (ch) {
                case 'e':
                        random_exit = 1;
@@ -63,6 +100,9 @@ main(int argc, char *argv[])
                case 'r':
                        unbuffer_output = 1;
                        break;
+               case 'p':
+                       permute();
+                       return (0);
                default:
                case '?': case 'h':
                        usage();

Reply via email to