Fortune
April 5, 2011
We have today another in our occasional series of re-implementations of Unix V7 commands. The fortune
command prints a random aphorism on the user’s terminal; many people put the fortune
command in their login script so they get a new aphorism every time they login. Here’s the man page:
NAME
fortune
SYNOPSIS
fortune [ file ]
DESCRIPTION
Fortune prints a one-line aphorism chosen at random. If a file is specified, the sayings are taken from that file; otherwise they are selected from /usr/games/lib/fortunes.
FILES
/usr/games/lib/fortunes - sayings
The fortunes are stored in a file, one fortune per line. The original Unix V7 fortunes file, available from http://minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/games/lib/fortunes, is reproduced at the end of the exercise.
Your task is to implement the Unix V7 fortune
program. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
[…] today’s Programming Praxis exercise, our goal is to implement the fortune Unix command line tool. […]
My Haskell solution (see http://bonsaicode.wordpress.com/2011/04/05/programming-praxis-fortune/ for a version with comments):
A Python solution:
Beauty of awk :
My first solution is similar to Dave Webb’s, but I also wrote up an iterative
function that will use less resources if the fortune file is large.
Woops, line 14 should read
i = 0 if randrange(n) >= 1 else 1
After writing my above solution, I took this as an opportunity to play
with pylint a sourcecode analyzer.
My new version is available here.
Another variation on solutions posted by Dave and Graham.
Nice one Mike; I need to learn more about the itertools module.
Quick question, though:
randint(0, n)
uniformly picks a random integer from[0, n]
(inclusive), so doesn’t this use the probability
1/(n + 1)
instead of1/n
?@Graham. Yes, my program calculates the probability as 1/(n+1). However, n starts at 0.
So, for fortune lines 0, 1, 2, …, the probabilities are 1/1, 1/2, 1/3, ….
This is the same as n starting at 1 and calculating the probability as 1/n.
An version in Common Lisp:
and a completely golfed command line Perl version
perl -ne 'rand($.)<1&&($l=$_)}{print$l'
just because the awk version was still readable.@Mike: My mistake! Thanks for clearing that up.
In F#,
[…] reimplemented a basic version of Fortune. This version prints to the standard output a randomly chosen line from a text file. You can […]