Quickies C Source for short utilities and examples

Here are the source files for some short programs I've written which may be useful or interesting to others. Please don't use them for your homework solutions. For one thing, you might flunk. I'm not a professional programmer, and don't even play one on T.V. These represent the best work I can do, but hopefully not the best work you can do.

• The towers of hanoi. A classic elementary programming exercise in recursion.

• Boxtext: A little utility for printing text in a box. The text can be given on the command line or read from stdin. You can use this to spiff up your interactive shell scripts.

• Implementation of the Euclidean Algorithm. The Euclidean Algorithm is an elementary algorithm for finding the greatest common divisor of two numbers.

• A template for processing command-line arguments. This is basically an elaboration of the stuff in section 5.10 of K&R. Supports option arguments, combining single-letter options, and using -- to denote the end of options.

• Miles, a utilty for runners. Prints all combinations of lanes and laps on a track that equal an even number of miles to within a desired tolerance.

• Benford, a program for investigating Benford's Law.

Benford's law, a curious empirical observation, says that the relative frequency for the most significant digit equaling k is commonly distributed as log((k+1)/k). The story is that the pages near the beginning of the book in old tables of common logarithms were often more heavily worn than pages near the end. Since people usually went to such tables to look up the logarithms of data they observed, this would seem to imply a nonuniform distribution for the most significant digit of the mantissa.

There is by now a sizable literature on Benford's law. See, for example, T.P. Hill, "The Significant-Digit Phenomenon", Amer. Math. Monthly, April 1995, 322-327, and the references given there.

• A utility to copy over an existing file. In both Unix and DOS the redirection > first truncates the target file to zero length. The redirection >> appends new data at the end of the target file. This program allows new data to be written on top of an existing file starting from the beginning.

• Calculate the expected amount of time to cover (i.e., obtain for the first time) a specified sequence of binary digits in a stream of random digits. (Contains another potentially useful routine, PrintAsDecimal, which prints an arbitrarily long string of 0s and 1s as a base 10 decimal.)

Algorithm: (pointed out to me by P.Griffin ) If s is the given string of length n Then E T(s) = E T(t) + 2^n, where t is the longest string such that s starts and ends with t. Perhaps surprisingly, the algorithm shows that the expected time is always an integer.

The algorithm applies much more generally, e.g., to find the expected time to first encounter a given sequence of states in a finite-state ergodic Markov chain. (In that case, 2^n must be replaced by a quantity depending on the transition matrix and stationary probabilities.)

Also see:

• Example 4.20, pp 160-161 in S.M. Ross, Introduction to Probability Models 5th Ed., Academic Press, San Diego, 1993

• G. Blom, On the mean number of random digits until a given sequence occurs, J. Appl. Prob. 19(1982), 136-143.

• P.T. Nielsen, On the expected duration of a search for a fixed pattern in random data, IEEE Trans. Information Theory 19(1973), 702-704.

For a proof and other discussion, consult my paper The Expected time to find a string in a random binary sequence.

Here is a cgi-based demo which accepts only strings of 32 digits or fewer.

• Program to print out examples of the long division algorithm. With the advent of calculators the long division algorithm is quickly becoming a lost art. So that future generations may understand how we suffered in 4th grade, I offer this program. It is capable of solving very large examples.

Try a cgi-based demo .

• C code for solving Kepler's equation. This code illustrates 5 different methods for solving kepler's equation, a transcendental equation whose solution is one of the key steps in determining the position of a planet or satellite on its orbit. The source code is extensively documented including references to sources for further information.

• An implementation of the bisection method for finding roots of equations. Not an efficient method, but instructive for calculus students studying the intermediate value theorem.

• The definitive leapyear program.

• Calculate the date of Easter and related things.

• A recursive descent parser for translating roman numerals into integers. For the history of roman numerals see pp 242-246 of Number Words and Number Symbols: A Cultural History of Numbers, Karl Menninger (transl. Paul Broneer), MIT press, 1977.

• Tutney

Tutney is a spelling language which my parents used to communicate with each other when I was a toddler and they didn't want me to be able to follow what they were saying. I am unsure of the origins of tutney. My parents claim it originated in the part of upstate New York where they grew up (Boonville area,) but I have met people from other parts of the world who know tutney. The rules are simple: vowels are pronounced as is, but consonants (except for a few exceptions) are pronounced by doubling the consonant with the letter u interposed. The exceptions are q (prounounced quack), y (pronounced yack), j (pronounced judge), w (pronounced wack), and h (pronounced hash). Surprising proficiency can be attained with a little practise.

For example, here is a translation of the previous paragraph into tutney. And here is a lex source file for a program to translate English ( or any language using the same alphabet!) into tutney. Here is C language source file for a program to do the same thing. Finally, here is an executable for Windows XP built from the C source. This is a console application. To use it, you would say the following at a command prompt: tutney < source > destination. Or say tutney /h for further usage information.

• A program for studying happy numbers. A happy number n is one with the following property: let f(n) be the sum of squares of the decimal digits of n. The sequence f(n), f(f(n)), ... must eventually fall into a cycle. If the cycle is 1,1,1,..., then the number n is happy. Otherwise it is unhappy. Our program allows different bases and also introduces the concept of an ecstatic number: an ecstatic number is happy in every base up to a certain limit (which measures its ecstasy.) (Also see the Mathematica site for more on this somewhat obscure topic.)

• A program for simulating J. Parrondo's paradoxical game. This involves two games of chance which by themselves are unfavorable, but which when alternated at random become favorable. See J. Parrondo's website for more information.

• A program for printing a nicely formatted pascal's triangle. It is written for simplicity rather than efficiency.

• C source for an implementation of the strstr library routine using the Knuth-Morris-Pratt algorithm. Includes a wrapper main program that allows searching for the first occurrence of a string in a file, printing the failure failure, counting the number of occurrences of a string in a file, and other applications. For further information on the algorithm, consult the paper Knuth, D.E., J.H. Morris, and V.R. Pratt, "Fast pattern matching in strings", SIAM J. Computing, 6:2, 323-350.

• C source for a study of recursive functions. As it stands, this is the world's slowest implementation of the power function. It could easily be extended to give even slower implementations of other, more complex, arithmetic functions.

• A program that writes the set-theoretic definition of ordinal numbers. The sequence of ordinals is defined in terms of the null set, 0, by 0, {0}, {0,{0}}, ...

• A program to search a dictionary for anagrams. The idea for this comes from Programming Pearls, Jon Bentley, 2nd Ed., Addison Wesley, Reading, 2000. Bentley's book is an excellent source of ideas for programming projects.

• A program to print numbers in led style. I.e., like this:
``` _               _   _
_|   | |_|   | |_  |_|
_|   |   |   |  _|   |

```

• A program illustrating several methods for generating all permutations of 1...n. This subject has a large and interesting literature, and this program only begins to scratch the surface. See, e.g., the survey article: R. Sedgewick, Permutation Generation Methods, ACM Computing Surveys 9(1977), 137-164.

• A program to generate pages of random arithmetic problems. Research has shown that mental exercise can help stave off dementia. Use this program to generate a list of random arithmetic exercises with an additional page of answers.

• A program to illustrate a constructive proof of the Schroder-Bernstein Theorem. The proof in question is due to M. Hellman. See, e.g, E. Mendelson, Introduction to Mathematical Logic, 3rd Edition, Wadsworth and Brooks/Cole, Monterey, 1987, pp 198-199.

• A program to tabulate the hypergeometric function. Allows you to vary the parameters and variable at will, and can used either from the command line or in an interactive mode. Output can also be written in XML which links a stylesheet named function_table.css, if it exists. By rolling your own stylesheet you can control the appearance of the tables produced. I intend to use this code as the base for a suite of programs to calculate various special functions if my ambition does not desert me. At any rate, tables of the hypergeometric function are hard to find, so this may fill a need. (This program is very naive. It is only a starting point.)

• Lisper: a program to generate random balanced parenthisis expressions, i.e., things like (()()((()()))). The name is based upon the unoffical reading of the Lisp programming language acronym: Lots of Insipid Silly Parentheses.

• Ackermann: a program to calculate Ackermann's function (as far as that is possible.) The source code hopefully contains instructive comments related to this function and its properties and significance.

• An introspective C program. It prints its own source code listing to stdout. This output could then be compiled and run; that output could be compiled and run .... In essence, it is a very simple, source code level, computer virus. (Addendum: Such programs have been termed "quines" after the logician W. Quine. Apparently the writing of one's own quine is a kind of rite of passage for programmers. See The Quine Page for much more information.)

• A program to demonstrate information packing functions. An information packing function is a function C(x,y) of whole numbers with whole number values which is 1-1. The idea is that such a function packs the information in 2 natural numbers into a single natural number. Suitable extraction functions H ("head") and T ("tail") then retrieve the information via H(C(x,y)) = x and T(C(x,y)) = y. With some care, all 3 functions can be constructed so as to be primitive recursive. The importance of such functions in recursion theory is that they allow functions of several variables to be treated as functions of a single variable. This program illustrates a particularly simple and efficient function C. The idea comes from the beautiful book of Marvin Minsky, Computation: finite and infinite machines, Prentice Hall, Englewood Cliffs, N.J., 1967.

• Euler's totient function. The implementation is highly recursive.

• My own solution to the firing squad synchronization problem. This old problem, attributed to J. Myhill, asks the following: suppose we have n determinisitic finite automata arranged in a line. All the machines have identical state transition diagrams except for the two on either end, which are allowed to be different. The transitions of each machine are allowed to depend on the states of its nearest neighbors, but not on those of any other machine. The machine on the left end is designated "the general." Alone among the machines it has some volition, so that at some time it enters a special state we may call "fire when ready." The problem is to design all the machines so that they will at some point enter a state called "fire" simultaneously. The trick is to make the design independent of n, so that if we inserted an arbitrary additional number of machines in the line, the solution would still work (though it would probably take longer for the machines to synchonize.) My solution is neither efficient nor elegant, but it does seem to work. The code could use lots of polishing, but I can't stand to look at it anymore.

• More to come ... ?