summaryrefslogtreecommitdiff
path: root/ipl/progs/choose.icn
diff options
context:
space:
mode:
Diffstat (limited to 'ipl/progs/choose.icn')
-rw-r--r--ipl/progs/choose.icn73
1 files changed, 73 insertions, 0 deletions
diff --git a/ipl/progs/choose.icn b/ipl/progs/choose.icn
new file mode 100644
index 0000000..3d715a5
--- /dev/null
+++ b/ipl/progs/choose.icn
@@ -0,0 +1,73 @@
+############################################################################
+#
+# File: choose.icn
+#
+# Subject: Program to pick lines from a file
+#
+# Author: Gregg M. Townsend
+#
+# Date: January 14, 2002
+#
+############################################################################
+#
+# This file is in the public domain.
+#
+############################################################################
+#
+# usage: choose [-N] [file...]
+#
+# This program randomly selects N lines from the input stream and
+# outputs them in order. If N is omitted, one line is chosen.
+# If the input stream supplies fewer than N lines, all are output.
+#
+############################################################################
+#
+# Links: random
+#
+############################################################################
+
+link random
+
+global wanted # number of lines wanted
+global seen # number of lines read so far
+
+record chosen( # one tentatively chosen input line
+ lnum, # line number
+ text) # data
+
+global llist # list of tentatively chosen lines
+
+procedure main(args)
+ local fname
+
+ if wanted := abs(integer(args[1])) then
+ get(args)
+ else
+ wanted := 1
+
+ llist := []
+ seen := 0
+ randomize()
+
+ if *args = 0 then
+ dofile(&input)
+ else while fname := get(args) do
+ dofile(open(fname)) | stop("cannot open ", fname)
+
+ llist := sortf(llist, 1)
+ every write((!llist).text)
+end
+
+procedure dofile(f)
+ local line
+
+ while line := read(f) do {
+ seen +:= 1
+ if seen <= wanted then
+ put(llist, chosen(seen, line))
+ else if ?0 < wanted / real(seen) then
+ ?llist := chosen(seen, line)
+ }
+ close(f)
+ return
+end