Your task is to write a program that finds the *n*th smallest item in a binary search tree, without enumerating all of the items in the tree. 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.

]]>

I took the opportunity to do things other than write an exercise. I apologize. I’ll be back with another exercise on Friday. Probably. The beautiful weather is supposed to last another few days. . . .

In the meantime, pick an exercise you have done yet, and solve it. Or, enjoy the weather where you are.

]]>

Given a two-dimensional matrix of integers, for any cell that initially contains a zero, change all elements of that cell’s row and column to zero.

Your task is to write the indicated 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.

]]>

Given a list of daily stock prices for a month, find the day on which you can buy a stock and the day on which you can sell the stock that gives the maximum gain.

Your task is to write a program that finds the optimal starting and ending dates for stock purchase and sale. 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.

]]>

import Data.List sortwodup :: (Ord a) => [a] -> [a] sortwodup = concat . transpose . group . sort

Here’s the pipeline of functions applied to the sample input (2 9 1 5 1 4 9 7 2 1 4):

Sort converts the input list to (1 1 1 2 2 4 4 5 7 9 9).

Group converts the output of sort to a list of sub-lists: ((1 1 1) (2 2) (4 4) (5) (7) (9 9)).

Transpose swaps rows and columns, ignoring missing items, like this:

1 1 1 1 2 4 5 7 9 2 2 1 2 4 9 4 4 1 5 7 9 9

Thus, the output from transpose is ((1 2 4 5 7 9) (1 2 4 9) (1)). Finally, concatenate removes the sub-list structure, producing (1 2 4 5 7 9 1 2 4 9 1).

Your task is to write a Haskell-style program to solve the problem of sorting a list, moving duplicates to the end. 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.

]]>

Given an array of

nintegers, partition the array into sub-arrays, each in ascending order, and each without duplicates. For instance, given the array [2, 9, 1, 5, 1, 4, 9, 7, 2, 1, 4], the desired output is the array [1, 2, 4, 5, 7, 9, 1, 2, 4, 9, 1], where the intent is to have as many sub-arrays as the maximum frequency of any element, each sub-array as long as possible before starting the next sub-array of duplicates. If possible, perform the work in-place, in time either O(n) or O(nlogn).

Your task is to solve the sorting problem 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.

]]>

You are initially at the first cell of an array of cells containing non-negative integers; at each step you can jump ahead in the array as far as the integer at the current cell, or any smaller number of cells. You win if there is a path that allows you to jump from one cell to another, eventually jumping past the end of the array, otherwise you lose. For instance, if the array contains the integers [2, 0, 3, 5, 0, 0, 3, 0, 0, 3, 1, 0], you can win by jumping from 2, to 3, to 5, to 3, to 3, then past the end of the array.

Your task is to write a program that determines if a given game is winnable. 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.

]]>

`afoot`

passes because the three vowels, `a`

, `o`

and `o`

appear in non-decreasing order.
An easy way to solve this problem uses regular expressions:

$ grep '^[^aeiou]*a*[^aeiou]*e*[^aeiou]*i*[^aeiou]*o*[^aeiou]*u*[^aeiou]*$' /etc/dict/words

Since that is so easy, you must write a program that does *not* use regular expressions.

Your task is to write a program that finds words with ordered vowels. 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.

]]>

One simple line-breaking algorithm is the greedy algorithm: pack on to each line as many words as can fit, then go to the next line. For instance, given the text “aaa bb cc ddddd” and a line width of 6, the output would be as shown below left:

------ ------ aaa bb aaa cc bb cc ddddd ddddd ------ ------

The greedy algorithm minimizes the number of lines used, but most line-breaking algorithms prefer to minimize the amount of “raggedness.” One common measure of estheticness minimizes the slack at the end of the line; specifically, it seeks a minimum sum of the square of the number of spaces at the end of each line. The format shown above left has no space at the end of the first line, 4 spaces at the end of the second line, and 1 space at the end of the third line, for a total slack of 0 + 4^{2} + 1^{2} = 17. The purpose of squaring is to more heavily penalize large amounts of slack.

A better format is shown above right. That has 3 spaces at the end of the first line, 1 space at the end of the second line, and 1 space at the end of the third line, for total slack of 3^{2} + 1^{2} + 1^{2} = 11.

From an algorithmic point of view, this is a minimization problem that can be solved in quadratic time by dynamic programming: Walk down the list of words, computing after each word the minimum slack to that point, then add the next word and recompute. The primary data structure used in computing the minimization is an upper-triangular matrix, shown below left:

aaa bb cc ddddd aaa bb cc ddddd ----- ----- ----- ----- ----- ----- ----- ----- 0 3 0 -3 -9 0 3 0 1 4 1 -5 1 4 1 2 4 -2 2 4 3 1 3 1 ----- ----- ----- ----- ----- ----- ----- -----

The first row is computed as 3, which is the number of spaces remaining after placing `aaa`

on a line, 0, which is the number of spaces remaining after placing `aaa bb`

on a line, -3, which is the number of spaces remaining after placing `aaa bb cc`

on a line, and -9, which is the number of spaces remaining after placing `aaa bb cc ddddd`

on a line; obviously, the last two entries on the first row are infeasible, as the line width exceeds the available space. The second row is computed as 4, which is the number of spaces remaining after placing `bb`

on a line, 1, which is the number of spaces remaining after placing `bb cc`

on a line, and -5, which is the number of spaces remaining after placing `bb cc ddddd`

on a line; the last entry on the row is infeasible. Likewise the third and fourth rows. The feasible portion of the upper-triangular matrix is shown above right.

The next step is to take the minimum feasible value in each column: 3, 0, 1, and 1; if you square those and compute the sum, you get 3^{2} + 0^{2} + 1^{2} + 1^{2} = 11, which is the cost we computed above. More interesting is to take the index of the minimum feasible value in each column, which is 0, 0, 1, and 3 (the 3 in the `aaa`

column is at index 0, the 0 in the `bb`

column is at index 0, the 1 in the `cc`

column is at index 1, and the 1 in the `ddddd`

column is at index 3). Then we compute the line breaks using the index minimums pairwise as follows: the first pair 0, 0 is empty; the second pair 0, 1 defines the bounds of the first output line; the third pair 1, 3 defines the bounds of the second output line; and the implicit pair 3, 4 (4 is the end of the input) defines the bounds of the third output line.

And that’s the algorithm. Beware that reducing it to code can be tricky (I got it wrong more than once) because you have to be careful to keep the row and column indexes straight and you have to remember when to add and subtract 1 to point to the previous or next column or row. The algorithm obviously has quadratic time and space complexity to compute and manipulate the upper-triangular matrix.

Your task is to write a program to format paragraphs by the dynamic programming algorithm 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.

]]>

Given a huge file of words, print all the distinct words in it, in ascending order; the definition of “huge” is “too big to fit in memory.”

Your task is to write a program to print all the distinct words in a huge file. 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.

]]>