Three-Level Control-Break
September 29, 2017
In many data-processing shops it is standard practice to write programs that generate reports that summarize data in hierarchical groups, say a report of population by city nested within county nested within state nested with a grand total. The input data is a set of records, already sorted in the required order. The output is a printed report, often written on sprocket-fed green-bar paper (where I work, we had a high-speed line printer as late as about ten years ago). The trick, of course, is that you never know that a break has occurred until you read the record after the break, so you have to be careful to keep track of where you are in the hierarchy, and to properly initialize and complete each level of the hierarchy; the first and last records in the data set are always potential spots for error.
Your task is to write a program that produces a three-level control-break report; use any data set that interests you. When you are finished, you are welcome to read a suggested solution, or to post your own solution or discuss the exercise in the comments below.
Data Laundry
September 26, 2017
We have a simple task today, converting a file from one format to another. Such tasks are often called data laundry, in the sense of washing or cleaning the data as it moves from one format to another. Here’s the input:
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384 options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP> inet 127.0.0.1 netmask 0xff000000 inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 nd6 options=201<PERFORMNUD,DAD> gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280 en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500 ether f4:0f:24:29:df:4d inet6 fe80::1cb5:1689:1826:cc7b%en0 prefixlen 64 secured scopeid 0x4 inet 10.176.85.19 netmask 0xffffff00 broadcast 10.176.85.255 nd6 options=201<PERFORMNUD,DAD> media: autoselect status: active en1: flags=963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX> mtu 1500 options=60<TSO4,TSO6> ether 06:00:58:62:a3:00 media: autoselect <full-duplex> status: inactive p2p0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 2304 ether 06:0f:24:29:df:4d media: autoselect status: inactive
The desired output is a comma-separated values file with three fields:
interface,inet,status lo0,127.0.0.1, gif0,, en0,10.176.85.19,active en1,,inactive p2p0,,inactive
Your task is to write a program that converts the input shown above to the desired output. 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.
Comma Quibbling
September 22, 2017
Eric Lippert, at his blog Fabulous Adventures in Coding, discusses the problem of comma quibbling, which turns a list of words like (“ABC” “DEF” “G” “H”) into the string “ABC, DEF, G and H” with commas between each pair of words except the last pair, which gets the word “and” (without a comma). Here are the rules:
- If the input is empty, so is the output.
- If the input has a single word, so does the output.
- If the input has two words, the output is the two words separated by “and”.
- If the input has more than two words, the output is all the words, separated by commas, but with the last comma replaced by “and”.
A word is a maximal sequence of characters not containing a comma or a space.
Your task is to write a function that adds commas to a list of words, using the rules described above. 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.
Catalan’s Triangle
September 19, 2017
Since our exercise a week ago, I’ve been reading about Catalan numbers, primarily based on the references at OEIS. Catalan’s Triangle (A009766) is a number triangle
1 1 1 1 2 2 1 3 5 5 1 4 9 14 14 1 5 14 28 42 42 1 6 20 48 90 132 132
such that each element is equal to the one above plus the one to the left.
Your task is to write a program that calculates a Catalan triangle. 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.
Compile Chez Scheme On Android ARM
September 15, 2017
In a recent exercise I described my new tablet computer, and talked about installing Guile Scheme because I could not get Chez Scheme to compile. I have finally been able to compile my preferred Scheme interpreter, Chez Scheme, on my Android ARM tablet. This note describes how I did it.
Chez Scheme is written partly in C and partly in Scheme; as a consequence, it requires a working Scheme compiler to be compiled. For popular platforms, such as Linux, Chez Scheme is distributed with the Scheme portion of the compiler already compiled, but for the Android ARM platform, we have to compile the Scheme portion of the compiler ourselves. The procedure is to compile Chez Scheme on some available platform (we will use Linux), cross-compile the Scheme portion of the compiler for the Android ARM platform, compile the C portion of the compiler on Android ARM, and then complete the build on Android ARM. It’s easier than it sounds. First, if you don’t already have Chez Scheme running on your Linux platform, perform the following steps to obtain and compile Chez Scheme (similar instructions apply on other platforms, go to the Chez Scheme Project Page for assistance):
cd /usr/local/src sudo wget https://github.com/cisco/ChezScheme/archive/v9.4.tar.gz gunzip v9.4.tar.gz tar -xvf v9.4.tar sudo rm v9.4.tar cd ChezScheme-9.4 sudo ./configure sudo make install
At this point you should have a working Chez Scheme system on the Linux computer. You might want to stop and play with it to make sure it works. Assuming that you compiled on an Intel system, the machine type was a6le
, so perform the following steps to cross-compile to machine type arm32le
for the Android ARM:
sudo mkdir boot/arm32le cd a6le sudo make -f Mf-boot arm32le.boot cd .. sudo ./configure -m=arm32le sudo ./configure --workarea=arm32le cd arm32le/s sudo make -f Mf-cross m=a6le xm=arm32le base=../../a6le
Now the cross-compilation is complete and you are ready to work on the Android ARM system. Still on the desktop, pack up the complete Chez Scheme system:
cd /usr/local/src sudo tar -czvf ChezScheme-9.4.tar.gz ChezScheme-9.4
We look next at the Android ARM tablet. We will be running under GnuRoot, so that must first be installed and configured. On the tablet, go to the Google Play Store and install program GnuRoot Debian; it should take only a few minutes. The environment installed by GnuRoot is minimal, so perform the following steps to install some useful software on your system:
apt-get update && apt-get -y upgrade apt-get install build-essential ed vim m4 gawk apt-get install ssh guile-2.0 python wget curl
Depending on your aspirations, you might want to install some other packages, or omit some of those shown above. Next, copy the .gz file to directory /usr/local/src on an Android tablet running GnuRoot; I did it by performing the following commands on the tablet, which was connected to my local network, but they are unlikely to work unmodified on your machine:
cd /usr/local/src sftp phil@192.168.1.65 cd /usr/local/src get ChezScheme-9.4.tar.gz quit
Once you have copied the .gz file to the tablet, perform the following steps there. It is odd to install and then uninstall X-windows, but Chez Scheme requires X-windows to compile, and doesn’t require it to run, so this sequence is correct (that was the trick that took me so long to figure out, delaying the compilation by several weeks):
apt-get install libncurses5-dev libncursesw5-dev gunzip ChezScheme-9.4.tar.gz tar -xvf ChezScheme-9.4.tar rm ChezScheme-9.4.tar cd ChezScheme-9.4 apt-get x11-common libx11-dev cd arm32le/c make apt-get purge x11-common libx11-dev cd ../s make allx cd ../..
At this point the program is compiled and ready to use. However, the install script doesn’t work properly, for some reason, so the program must be installed manually with the following commands:
cp arm32le/bin/scheme /usr/local/bin cp arm32le/bin/petite /usr/local/bin chmod +x /usr/local/bin/scheme chmod +x /usr/local/bin/petite mkdir /usr/local/csv9.4/arm32le cp boot/arm32le/scheme.boot /usr/local/csv9.4/arm32le cp boot/arm32le/petite.boot /usr/local/csv9.4/arm32le
And that’s it. To test your installation, type scheme
at the command-line prompt; you should be rewarded with the Chez Scheme welcome text followed by a Scheme prompt:
Chez Scheme Version 9.4 Copyright 1984-2016 Cisco Systems, Inc. >
Your task is to get your preferred programming environment working on your mobile device, and let us know how it works. If anyone installs Chez Scheme, I would appreciate your feedback on the instructions given above, particularly if you find any errors.
Catalan Numbers
September 12, 2017
Today’s exercise is an Amazon interview question for software engineers and developers:
How many unique binary search trees can be made from a series of numbers 1, 2, 3, 4, …, n, for any given n?
Your task is to compute the number of unique binary search trees. 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.
Linked List Palindrome
September 8, 2017
Today’s exercise is an Amazon interview question from Career Cup (this is the exact question asked):
There is a given linked list where each node can consist of any number of characters :- For example
a–>bcd–>ef–>g–>f–>ed–>c–>ba.
Now please write a function where the linked list will return true if it is a palindrome .
Like in above example the linked list should return true
Your task is to write a program to determine if a list of strings forms a palindrome. 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.
Three Bit Hacks
September 5, 2017
We have three problems today that involve twiddling bits. In all three cases you are not permitted to perform any branching operation (so no if-else statement) nor are you permitted to perform a loop; you must write a single statement that performs the requested task:
1) Determine the absolute value of an integer.
2) Determine if an integer is a power of 2.
3) Determine the minimum and maximum of two integers.
The restrictions on branching and loops are useful for modern CPUs that have instruction caches that you want to stay inside for speed.
Your task is to write the three bit hacks described above. 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.
Generator Push-Back
September 1, 2017
Generators are a useful programming tool; we provide an implementation in the Standard Prelude. Here is a Python prime-number generator that we discussed in a previous exercise:
def primegen(): # http://stackoverflow.com/a/20660551 yield 2; yield 3 # prime (!) the pump ps = primegen() # sieving primes p = next(ps) and next(ps) # first sieving prime D, q, c = {}, p*p, p # initialize def add(x, s): # insert multiple/stride while x in D: x += s # find unused multiple D[x] = s # save multiple/stride while True: # infinite list c += 2 # next odd candidate if c in D: # c is composite s = D.pop(c) # fetch stride add(c+s, s) # add next multiple elif c < q: yield c # c is prime; yield it else: # (c == q) # add sqrt(c) to sieve add(c+p+p, p+p) # insert in sieve p = next(ps) # next sieving prime q = p * p # ... and its square
I recently needed to interrupt a prime generator, then restart it; I needed all the primes up to a limit, but of course I didn’t know I had reached the limit until the generator produced the first prime past the limit. I could have saved the too-large prime, then used it before restarting the generator, but that’s inconvenient; it needs a separate variable for the saved prime, and a test to determine if a saved prime is available each time through the restarted generator. A better solution is to push back the value onto the generator:
def pushback(val,gen): yield val while True: yield next(gen)
Your task is to add push-back to the generator of your favorite language. 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.