From dbc1be0317ad5e70afb895648f4d6c8f0fbc1080 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 1 Jul 2017 21:22:28 +1200 Subject: Better implementation of pks(6df) Needs a lot of random numbers, but only one pass --- games/pks.awk | 75 ++++++++++++++------------------------------------------ man/man6/pks.6df | 12 ++++++--- 2 files changed, 28 insertions(+), 59 deletions(-) diff --git a/games/pks.awk b/games/pks.awk index ff316fb9..c490e8dc 100644 --- a/games/pks.awk +++ b/games/pks.awk @@ -1,28 +1,5 @@ # Ha, ha, ha! Awk! -# Print either two or three "has" and the given word, capitalized -function haha(wr) { - - # Two or three "has"? Important decisions here folks - srand() - hr = int(rand()*2+1) - for (ha = "Ha"; hi < hr; hi++) - ha = ha ", ha" - - # Capitalise the word - wr = toupper(substr(wr,1,1)) substr(wr,2) - - # Return the laughter and the word - return ha "! " wr "!" -} - -# Ha, ha! Failure! -function fail(str, ex) { - af = 1 - print haha(str) | "cat >&2" - exit(ex) -} - # Process arguments BEGIN { @@ -35,47 +12,33 @@ BEGIN { ARGV[1] = "/usr/share/dict/words" } - # Check the user hasn't tried stdin - for (ai = 1; ai < ARGC; ai++) - if (ARGV[ai] == "-") - fail("standard input", 2) - - # Count the number of lines in the files (pass 1) - for (ai = 1; ai < ARGC; ai++) - while (getline < ARGV[ai]) - lc++ - - # If all files were empty, we can't go on - if (lc == 0) - fail("no data", 1) - - # Pick a random line number + # Seed the random number generator srand() - lr = int(lc*rand()+1) } -# Iterate over the file until we get to the selected line (pass 2) -NR >= lr { +# Iterate over the lines, randomly assigning the first field of each one with a +# decreasing probability; this method +rand() * NR < 1 { wr = $1 } + +# Ha, ha, ha! Incompetent! +END { - # Find the first word-looking thing - for (i = 1; !wr && i <= NF; i++) - if (tolower($i) ~ /[[:lower:]]/) - wr = $i + # Check that we processed at least one line + if (!NR) + exit 1 # Strip trailing possessives sub(/'s*$/, "", wr) - # No word? Uh, better keep going - if (!length(wr)) - next + # Two or three "has"? Important decisions here folks + srand() + hr = int(rand()*2+1) + for (ha = "Ha"; hi < hr; hi++) + ha = ha ", ha" - # Ha, ha! Suboptimal! - print haha(wr) - exit(0) -} + # Capitalise the word + wr = toupper(substr(wr,1,1)) substr(wr,2) -# Ha, ha, ha! Incompetent! -END { - if (!af && !length(wr)) - fail("error", 1) + # Return the laughter and the word + printf "%s! %s!\n", ha, wr } diff --git a/man/man6/pks.6df b/man/man6/pks.6df index 03ab7251..30ae4ba1 100644 --- a/man/man6/pks.6df +++ b/man/man6/pks.6df @@ -8,13 +8,19 @@ .B pks FILE1 FILE2 .br +program | +.B pks +- +.br DICT=$HOME/dict .B pks .SH DESCRIPTION .B pks -picks a random word from a set of files and laughs at it. If no files are -given, it defaults to /usr/share/dict/words, or the value of DICT (ha, ha!) if -specified in the environment. +picks the first word from a random line on a set of files and laughs at it. If +no files are given, it defaults to /usr/share/dict/words, or the value of DICT +(ha, ha!) if specified in the environment. +.P +A hyphen character "-" can be given as an argument to select standard input. .SH SEE ALSO .SH AUTHOR -- cgit v1.2.3