October 15, 2013
We have today another exercise from our limitless supply of interview questions:
You are given two arrays of integers, where the integers do not repeat, the two arrays have no common integers, and both arrays are sorted in ascending order.
Let x be any integer in the first array and y be any integer in the second array. Find min(abs(x − y)); i.e., find the smallest difference between any integers in the two arrays.
Your task is to write a program to find the smallest difference. 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.
October 11, 2013
In the previous exercise we implemented some basic operations on functional-style linked lists; their distinguishing feature is that the pairs that make up the lists are immutable. In today’s exercise we will implement imperative-style linked lists in which the pairs that make up the lists are mutable.
Your task is to write the same library of functions —
reverse — for imperative-style mutable linked lists as you wrote in the previous exercise for functional-style immutable linked lists. 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.
October 8, 2013
We frequently use linked lists in our programs, but Scheme makes that easy because it provides linked lists as a native data type, along with a rich set of operations on them. In today’s exercise we will implement lists in the functional style that Scheme provides natively.
In Scheme, a list is really nothing more than an array with two slots, known as the car and cdr of a pair; a list with no elements is called the null list. We frequently think of lists as a sequence of elements, but in fact a list is no more than a chain of pairs, of which the cdr of each pair is another list, the chain terminating in a null list. Depending on the version of Scheme that you use, the car and cdr of the pair may or may not be mutable; traditionally, they have been mutable, but the most recent approved standard R6RS makes pairs immutable (that is controversial, and many implementations of Scheme ignore it and leave pairs mutable). Still, immutable pairs are more closely aligned with the spirit of functional languages, and your implementation today should provide immutable pairs.
Your task is to implement a small library of list operators; you should include at least nil and a predicate to recognize it, a procedure to build pairs and two procedures to extract the pieces of a pair, functions to extract the nth item of a list and to determine its length, and functions to reverse the elements of a list and append two lists; you are welcome to provide more operators if you wish. 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.
October 4, 2013
In today’s exercise we will do somebody’s homework:
Read a file containing integers, one integer per line. At the end of the file, write the number of integers in the file, their sum, and the mean, median, mode, minimum and maximum of the integers in the file.
October 1, 2013
We studied Fibonacci numbers in a previous exercise. In today’s exercise, we will look at a generalization of Fibonacci numbers called Lucas numbers, which were studied by Edouard Lucas in the late 1800s.
Recall that each Fibonacci number is the sum of the two previous Fibonacci numbers, with the first two being 1 and 1; thus, the Fibonacci numbers begin 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, …. The definition of the Lucas numbers is similar, but the first two Lucas numbers are 1 and 3; thus, the Lucas numbers begin 1, 3, 4, 7, 11, 18, 29, 47, 76, …, and they grow faster than the Fibonacci numbers.
Lucas went on to generalize the Fibonacci numbers even further. He define two sequences Un(P, Q) and Vn(P, Q) as follows: Start with integer P and Q satisfying D = P2 − 4Q > 0. Then, by the quadratic formula, the roots of x2 − P x + Q = 0 are a = (P + sqrt(D)) / 2 and b = (P − sqrt(D)) / 2. Then Un(p, q) = (an − an) / (a − b) and Vn(P, Q) = an + an.
Now the Fibonacci and Lucas numbers are just special cases of the U and V sequences: the Fibonacci numbers are Un(1, -1) and the Lucas numbers are Vn(1, -1).
It is easy to compute a particularU or V sequence. The formulas are similar to the method of computing the Fibonacci sequence: Um(P,Q) = P Um−1(P,Q) − Q Um−2(P,Q) and Vm(P,Q) = P Vm−1(P,Q) − Q Vm−2(P,Q).
It is also easy to calculate a particular U or V in the sequence using a chain that takes only logarithmic time based on the following identities: U2n = Un Un, U2n+1 = Un+1 Vn − Qn, V2n = Vn2 − 2 Qn, and V2n+1 = Vn+1 Vn − P Qn.
You can see all of these formulas at MathWorld. Our interest in Lucas sequences isn’t merely academic; we’ll see an application of Lucas sequences in a future exercise.
Your task is to write programs that compute the U and V sequences and that compute any given element of either of the two sequences. 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.
September 27, 2013
We have seen priority queues on several different occasions in the past, including this implementation using imperative heaps; such priority queues allow items to be inserted in any order and retrieved in order of priority. In today’s exercise we will look at a similar data structure called an interval heap that permits access at both ends, to either the minimum or maximum item in the heap. The permitted operations are:
isEmpty — is the priority queue empty?
insert item — insert a new item in the priority queue
getMin — get the smallest item in the priority queue
getMax — get the largest item in the priority queue
deleteMin — delete the smallest item from the priority queue
deleteMax — delete the margest item from the priority queue
Operation of an interval heap is similar to operation of an imperative heap, with a tree embedded in an array and the children if the ith node at 2i and 2i+1, except that each array element stores two items instead of one; all children of the array element are greater than or equal to the “lo” item of the array element and less than or equal to the “hi” item of the array element, at every node of the tree. The lo items from each element form a min-heap, in which each item is less than its children, and the hi items from each element form a max-heap, in which each item is greater than its children. New items are inserted at the end of the tree; if the new item is less then the lo item in the last element, it is sifted up to its proper position in the min-heap of lo items, if the new item is greater than the hi item in the last element, it is sifted up to its proper position in the max-heap of hi items, otherwise the new item is in its proper position. The minimum or maximum item in the interval heap can be deleted by removing it, replacing it with the corresponding minimum or maximum item from the last array element of the heap, then sifting down through the corresponding min-heap or max-heap.
Your task is to write functions that implement a double-ended priority queue using an interval heap as 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.
September 24, 2013
[ I told you in a previous exercise that I was having internet connectivity issues at home. It took three weeks, but a repairman from the local telephone company finally found that, during repairs on the soffit underneath my roof overhang, the roofer nailed through a board with a nail that was too long, so it penetrated the board and the telephone cable that was nailed to the other side of the board. As the temperature and humidity changed during the day, sometimes the nail made contact with two ends of the same conductor, and everything worked properly, but sometimes the nail made contact with two different conductors, causing a short circuit and preventing the telephone from working. At the same time, my wifi router developed some kind of internal problem, also intermittent. I have now replaced both the wire and the router and everything seems to be working. The problems were hard to solve because both of them were intermittent. ]
Today’s problem comes from one or another of the competitive programming sites, I’m not sure which:
Search every power of two below 210000 and return the index of the first power of two in which a target string appears. For instance, if the target is 42, the correct answer is 19 because 219 = 524288, in which the target 42 appears as the third and fourth digits, and no smaller power of two contains the string 42.
Your task is to write the search program 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.
September 20, 2013
John McCarthy’s 91 function is a recursive function designed as a test case for formal verification of computer programs. It is defined as follows:
M(n) = n - 10, if n > 100
= M(M(n+11)), if n <= 100
For instance, when n = 87:
Your task is to write a program that shows the call history of a call to the 91 function in a manner similar to that shown for M(87) 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.
September 17, 2013
I found this problem on a discussion board for beginning programmers. It feels like a Project Euler problem, but I looked and didn’t find it there:
The smallest pair of consecutive natural numbers that each have two distinct prime factors are 14 = 2 * 7 and 15 = 3 * 5. The smallest triplet of consecutive natural numbers that each have three distinct prime factors are 644 = 2^2 * 7 * 23, 645 = 3 * 5 * 43 and 646 = 2 * 17 * 19. What is the smallest set of four consecutive natural numbers that each have four distinct prime factors?
Your task is to write a program that finds the set of four natural numbers. 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.
September 12, 2013
[ I apologize for not posting an exercise on Tuesday. I have had intermittent internet access at home since last week that has prevented me from working on the blog. And now I published it immediately instead of scheduling it for Friday morning. Oh my! ]
Diffie-Hellman key exchange is a method for two people, traditionally named Alice and Bob, to agree on a secret key known only to the two of them using an insecure communications channel; Wikipedia gives an explanation, complete with a cheesy diagram.
The key exchange begins when Alice and Bob agree on parameters p, which should be at least a few hundred decimal digits in a real-life application, and g, which is typically small, say 2 or 3 or 5; we will follow Wikipedia’s illustration and choose p = 23 and g = 5. Then Alice chooses a secret number a, computes ga (mod p), and sends it to Bob; in a real application, a will be of similar magnitude to p, but for illustration we choose a = 6, so Alice sends the number 56 (mod 23) = 8 to Bob. Bob follows the same procedure, choosing b, computing gb (mod p), and sending it to Alice; in a real application, b will be of similar magnitude to p, but for illustration we choose b = 15, so Bob sends the number 515 (mod 23) = 19 to Alice. All of these exchanges can be conducted over an insecure channel, as long as Alice keeps a secret and Bob keeps b secret.
Once those exchanges have been made, Alice and Bob can both compute the same secret key s; Alice computes s = 196 (mod 23) = 2, using Bob’s public number 19 and her secret number a = 6, and Bob computes s = 815 (mod 23) = 2, using Alice’s public number 8 and his secret number b = 15. At this point, both a and b can be discarded. Using the shared secret number s = 2 as a key, Alice and Bob can encrypt and decrypt messages using any symmetric cipher, such as DES or AES, and send encrypted messages over insecure channels, confident that no one else knows their secret key. In practice, p is generally taken to be 2q+1, where q is a Sophie Germain prime of at least 512 bits, and g is generally taken to be a primitive root modulo p; these rules guarantee some desirable properties of the security of the secret key. The only way for someone with knowledge of g, p, ga (mod p) and gb (mod p) to determine the secret key s is to solve for a and b, but that involves computing the discreet logarithm and is intractable with current algorithms.
Your task is to write programs that perform Diffie-Hellman key exchange as 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.