Sum Of Two Integers

A couple of days ago, I wrote about upgrading to Clozure Lisp 1.7 and remarked that I should try it out with a miniproject, perhaps from Programming Praxis. I went over there and found the Sum of Two Integers problem, which looked interesting. The problem is given a list of integers and a target integer determine if there are two integers in the list that sum to the target.

I chose to interpret the rules strictly:

  • You can make no assumptions about the list of integers. They could be positive, negative, or zero. Numbers might be repeated multiple times. They are not sorted and you do not know the maximum or minimum number without checking the list.
  • Similarly, you can make no assumptions about the target number other than that it’s an integer
  • You must find exactly two integers that sum to the target number—you can’t reuse a number or just find the target in the list. Thus, if the target is 10 and 5 is in the list, there must be another 5 in the list for (5, 5) to be a solution. Similarly, if 10 is in the list, that’s not a solution unless 0 is also in the list.

Truth to tell, if this were a one-off most of us would just hack up the obvious n2 solution with two nested loops checking each pair of numbers in the list. Of course, none of us would admit to doing such a thing so the question is: can we find a better solution? My first thought was to use a bit array where the nth bit is set if n is in the list. That leads to a O(n) solution but there are some problems:

  • You need a second array to indicate whether a given number is repeated at least once in the list.
  • You really need to know the maximum number in the list to size the bit array properly.
  • It doesn’t handle negative numbers gracefully.

I did code up a solution like this under the assumption that there were no negative numbers but that doesn’t solve the problem so we need another solution.

We can use almost the same solution by substituting a hash table for the bit array. With this solution, each integer in the list is a key for the hash table and the value corresponding to the key is the count of the occurrences of the key in the list of integers. We need to go through the list twice1: once to build the hash table and once to check to see if a number in the list has the required number that sums to the target.

The code below implements this solution. The check routine on lines 9–19 does all the real work. For each number in the list (have) we calculate the number we need to sum to the target (need) and then check to see if need is in the hash table. If it is, we’ve found a solution (line 18), if it’s not we recursively call check with the cdr of the list (line 19). Lines 15–17 check for the special case of a number being exactly half of the target. In that case we’ve found the solution if the number is in the list at least twice.

 1:  (defun hash-numbers (numbers)
 2:    (let ((ht (make-hash-table :size (length numbers))))
 3:      (dolist (n numbers)
 4:        (setf (gethash n ht) (1+ (gethash n ht 0))))
 5:      ht))
 6:  
 7:  (defun check-sums (goal numbers)
 8:    (let ((ht (hash-numbers numbers)))
 9:      (labels ((check (numbers)
10:                 (if (null numbers)
11:                     nil
12:                     (let* ((have (car numbers))
13:                            (need (- goal have)))
14:                       (cond
15:                         ((= need have) (if (> (gethash need ht) 1)
16:                                            (list have have)
17:                                            (check (cdr numbers))))
18:                         ((gethash need ht) (list have need))
19:                         (t (check (cdr numbers))))))))
20:        (check numbers))))
21:  

This solution won’t be as fast as the bit array solution (given a decent implementation of bit arrays) but it’s still pretty efficient and it avoids all the problems with the bit array solution.

Can we do better than O(n)? What if we know the list is sorted?

Update: 2011-08-05 Fri
I looked through the solutions that other Programming Praxis readers submitted looking for something better than O(n). I didn’t find anything but Graham and some others noticed that you could combine the testing with the building of the hash table. Here’s my translation of Graham’s Python solution

(defun check-sums-2 (goal numbers)
  (let ((ht (make-hash-table :size (length numbers))))
    (dolist (n numbers)
      (if (gethash (- goal n) ht)
          (return (list n (- goal n)))
          (setf (gethash n ht) t)))))

It still O(n) but faster because it only goes through the list once. It’s also simpler.

Footnotes:

1 Actually, the solution goes through the list 3 times; calculating the size of the list also requires reading through the list.

Posted in Programming | Tagged | Leave a comment

Some More Emacs Tips

Gurmeet Manku shares some Emacs Tips n Tricks for Everybody on his homepage. A lot of these will be familiar to most Emacs users and some are things I wouldn’t want to do but it’s a nice list of things you can add to your .emacs file to make your development work easier and more enjoyable.

One interesting example is a pair of functions that swap the numeric keys with the shifted numeric keys (1 ↔ !, 2 ↔ @, 3 ↔ #, etc.). The idea is that this makes typing faster when editing C/C++ code. A companion function maps __ into -> and .. into [] for pointer notation and array indexing. I’m not sure I’d like this but if you do a lot of C/C++ and can deal with the schizophrenia it could be a time saver.

Another useful trick is to add

(modify-syntax-entry ?- "w")

to your emacs-lisp-mode-hook so that - is not considered a word delimiter. Similarly,

(modify-syntax-entry ?_ "w")

when added to c-mode-common-hook will prevent _ from being a word delimiter. I don’t know why this isn’t built into Emacs.

There are a lot of other ideas in the article and it’s well worth a look if you’re interested in ways of streamlining your Emacs work flow.

Posted in General | Tagged | Leave a comment

Clozure Lisp 1.7 Is Out

I haven’t been doing very much Common Lisp programming lately but I noticed that Clozure Common Lisp 1.7 has just been released so I upgraded. I always like to do a (rebuild-ccl :full t) when I install a new version but my recent upgrade to Lion meant that I didn’t have up-to-date build tools so I also downloaded the new Xcode.

I have one of the free developer accounts but this time I just used the App store. The download took forever, of course, and then it just left the installer in Launchpad so I didn’t realize it had finished. Once I got the new Xcode installed the rebuild-ccl completed normally.

Now I should try it out with some miniproject. Programming Praxis is always a good source of that type of thing so perhaps I’ll head over there and try one of their recent exercises out.

Posted in Programming | Tagged , | Leave a comment

Putting Shell Output In The Current Buffer

I’ve long used 【Meta+|】 to pipe a region to a shell command. I use it all the time to pipe troff input to groff and display the results with gxditview. Recently I learned that if you specify a prefix arg it will place the results in the current buffer. The easiest way to do that is simply to type 【Meta+1 Meta+|】. The same trick works with 【Meta+!】. For example, if I want to insert a directory listing into the current buffer I could type 【Meta+1 Meta+!ls.

Summary of Key Sequences

  • Meta+|
    Pipe the highlighted region to a shell command and place the output in a ∗Shell Command Output∗ buffer.
  • Meta+1 Meta+|
    Pipe the highlight region to a shell command and place the output in the current buffer.
  • Meta+!
    Run a shell command and place the output in a ∗Shell Command Output∗ buffer.
  • Meta+1 Meta+!
    Run a shell command and place the output in the current buffer.

Update: prefix tag → prefix arg

Posted in General | Tagged | 3 Comments

The New Luddites Redux

It’s been a long time since I’ve written about the New Luddites—the last time was early on in my old blog (1, 2, 3)—but sadly their silliness has surfaced again. I follow Shelly Palmer’s Digital Living blog, which is geared towards the non-technical user of consumer electronics but often has interesting posts. Yesterday he reported on a CNN article that discussed smartphone users obsessively checking their phones. That article, in turn, mentioned a study published in the Journal of Personal and Ubiquitous Computing.

Palmer begins by poking fun at the study for belaboring the obvious but then goes on to take its conclusions seriously and offer “solutions” for our addictive behavior. The study itself is not particularly compelling. Its methodology is ad hoc and its sample sizes are ludicrously small (the largest of the 3 studies had 36 participants, another 12, and the last studied 3 groups with single digit participants).

What are the study’s results that have so alarmed Palmer? The participants checked their smartphones an average of 34 times a day. Really? Assuming they were sleeping 8 hours a day that amounts to checking their phones every half hour. That’s addictive behavior?

First of all, it’s silly to use the word addictive with its overtones of alcoholism or hard drug use. Those habits clearly are harmful both physically and emotionally. The most harmful thing pointed to by the CNN article was that one man’s frequent checking of his smart phone annoyed his wife. Many people today choose to live a digital life: they read ebooks, get their bills as emails, keep electronic diaries, maintain friendships through social media, use Google as a sort of associative memory, and most of all stay connected all the time. The device that enables this lifestyle is the smartphone. Of course these people check their phones frequently.

To devise tactics to reduce smartphone use as Palmer suggests makes no sense except as a bizaro world yes-I-can type of experiment. Twenty years ago the equivalent exercise would have been to go without electricity and air conditioning for a week just to prove you could. Just as it was silly to worry about becoming habituated to electricity and A/C, it’s silly to forgo the advantages of smartphones on the grounds that using them twice an hour is addictive behavior. The New Luddites are always with us, of course, but I was surprised and saddened to see the author of Overcoming the Digital Divide: How to use Social Media and Digital Tools to reinvent yourself and your career give them aid and comfort.

Update: bizzaro → bizaro

Posted in General | Leave a comment

Scrolling With Lion

OS X 10.7 (Lion) has been out for about a week and although that’s probably not enough time for any subtle bugs to surface, it is, apparently, enough time for my natural paranoia to be overcome by my desire to give it a spin. So over the last couple of days I’ve updated my machines with Lion—the upgrades went extraordinarily smoothly; thanks for asking.

I’m still getting used to the OS so I don’t have much of substance to say right now but I can comment on one issue that’s getting mentioned a lot in the reviews that I’ve read: scrolling. If you’ve been paying any attention to Lion, you know by now that Apple has “reversed” the scrolling. Swiping down with two fingers used to scroll towards the bottom of the page; now it scrolls towards the top of the page. It’s easy to reinstate the old behavior with the System Preferences pane but that hasn’t stopped the howls of anguish—not to say outrage—from many of the commenters.

The idea is that the new behavior mimics what happens with iOS when you scroll: you’re grabbing the screen and pushing it up or down. Despite having a small problem with muscle memory, I like the change. The old behavior never made sense to me and only muscle memory and the fact that it had always been that way kept me from being totally confused. If I thought too hard about it I would do the “wrong” thing. After only a few hours the new scrolling already feels natural. Sometimes I start to move in the wrong direction but that is already starting to die out. If you’re having trouble with the change, just imagine that you are putting your fingers on the text and pushing it in the direction you want to go.

I’m sure there’ll be lots of kvetching and dark mumbling about Apple oppressing their users and upsetting the natural order of things but, really, all Apple has done is finally have scrolling make sense. And, you know, if you really, really don’t like it, it’s easy to change it back.

Posted in General | Tagged | Leave a comment

Using set-mark-command To Remember Locations

A couple of days ago I wrote a note to myself post to help me remember the align-regexp functionality. Today’s post is another note to myself. A recent post by Xah Lee reminded me of some Emacs functionality that I am always forgetting. Every time I see the set-mark-command function described I think, “Boy, that’s really useful, I need to remember it.” Then I promptly forget about it again.

The set-mark-command (bound to 【Ctrl+Space】) sets the mark at the point’s position. The normal way of invoking it to remember locations is to type 【Ctrl+Space Ctrl+Space】. The first 【Ctrl+Space】 sets the mark and the second deactivates it so that no region is highlighted. Emacs also pushes the mark onto the buffer’s mark ring and onto the global mark ring.

This is useful because we can use the marks recorded on the mark rings to return to a remembered location. If we want to return to a previous mark in the same buffer, we type 【Ctrl+u Ctrl+Space】 We can move back several locations by repeating the 【Ctrl+u Ctrl+Space】.

If we want to return to a mark which may be in another buffer we can type 【Ctrl+x Ctrl+Space】. This can also be repeated to move back several marks.

This may seem confusing but it boils down to just three key sequences

  • Ctrl+Space Ctrl+Space】 to push the current position onto the mark rings.
  • Ctrl+u Ctrl+Space】 to return to a previous position in the same buffer.
  • Ctrl+x Ctrl+Space】 to return to the previous position, which may or may not be in the same buffer.
Posted in General | Tagged | 6 Comments

More On Borders’ Closing

David Hill over at Singularity Hub has an interesting take on the closing of Borders. While agreeing that Borders’ downfall is a shame, Hill argues that it will actually be a huge win for authors and readers. It will benefit authors, he says, by accelerating the changes in the publishing industry that are putting the authors in control. Those same changes will hasten the move to digital books with all the advantages that brings to readers.

Hill’s post has a link to a post by Alan Rinzier, an industry insider, that is also interesting. Rinzier confirms the trend of greater author control and says, basically, that the publishing industry has no idea what it’s doing and is coming to realize that. As evidence for this, he reports that 80–90 percent of all published books lose money.

Rinzier says that while it’s as hard as ever to write a good book, authors who can now have the opportunity to self publish and control their own destiny. As I suggested in my Future of Books post, the publishing industry is undergoing great change but appears to remain in denial. If they wish to avoid Borders’ fate, they had better get a clue. They still provide a valuable service but they are no longer the gatekeepers that they once were. If their tactics to defend their business models become too annoying, authors and readers will simply route around them and they will learn first hand the meaning of disintermediation. As I also said in that post, I hope that doesn’t happen but I see little reason to be sanguine about their prospects.

Posted in General | Leave a comment

Aligning Text With Regular Expressions in Emacs

This is really a note to myself. A while ago I ran across this post over at RAW SYNTAX about the Emacs command align-regexp. I don’t require this functionality very often but when I do, align-regexp is just what I need. Unfortunately, I keep forgetting about it so I’m writing this post in the hopes that it will help me remember (or at least give me a place to find the name of the function)

The simplest, and probably most common, use case is to align on a particular character. The canonical example is a telephone number list. We just mark the region to align, type 【Meta+xalign-regexp, and then ( when prompted for the regular expression

# Original list

Joe (555) 111-2222
Mary  (555) 222-1212
Alexandra 123-4567
Francis (555) 333-2121

# After align-regexp

Joe     (555) 111-2222
Mary    (555) 222-1212
Alexandra 123-4567
Francis (555) 333-2121

That’s not quite what we want, though, because Alexandra’s number doesn’t have an area code so there is no open parenthesis to align on. To fix this, we have to use the more complicated version of align-regexp by giving the invocation a prefix arg: 【Ctrl+u Meta+xalign-regexp. This time we specify .+?\( +\).+ as the regular expression, choose 1 as the group to modify, 1 as the amount of spacing, and no as to whether we should repeat the rule throughout the line. The result is:

Joe       (555) 111-2222
Mary      (555) 222-1212
Alexandra 123-456
Francis   (555) 333-2121

That’s better but what we really want is to align on the -. If we do that directly using the simple case, we get

Joe (555) 111     -2222
Mary  (555) 222   -1212
Alexandra 123     -4567
Francis (555) 333 -2121

which is definitely not what we want. Instead we use the regular expression .+? +\(.*\) and specify -1 as the group to modify or justify. That gives us

Joe        (555) 111-2222
Mary       (555) 222-1212
Alexandra        123-4567
Francis    (555) 333-2121

which is just what we want.

Update: lower case the key sequences.

Update 2: prefix tag → prefix arg

Posted in General | Tagged | 2 Comments

Traveling Without A Computer

Heh heh. OK, that was a teaser title. Of course, I would never go anywhere without a computer; my days of being ABEND are long over. My normal routine is to take my MacBook Pro and associated equipment with me in a backpack. The MacBook essentially mirrors my main iMac machine so I can do anything on the road that I can do at home. Still, flying with the laptop is a hassle. I use the excellent SwissGear ScanSmart Backpack so at least I don’t have to take the computer out of the backpack but it’s still one more thing to deal with at the TSA checkpoints.

Last week, I was in New York visiting family. I decided to try leaving the MacBook at home and depending on my iPad instead. Naturally that precluded any development or serious writing but this was a family visit so, realistically, I wouldn’t be doing much of either. I could have tried depending on my iPhone and avoiding large computers altogether but I wanted to keep up with blogs and news and it’s just too painful to read that sort of thing on the iPhone’s small screen.

Traveling with the iPad is definitely easier. I have a small case for it and the only support equipment it requires is the charging cable. I always travel with the wonderful Scottevest Travel Vest which, with its 22 pockets, has plenty of room for the cable, my iPhone, keys, and all the other stuff I would normally throw in the backpack. When I got to the checkpoint, my shoes and iPad went into a bin and I put the travel vest on top. Just one bin and the iPad is effectively hidden from anyone tempted to get a free computer as they come out of the X-ray machine.

As I’ve mentioned before, I keep up with my feeds with Reeder, which has a very nice and easy to use iPad implementation so it was easy staying current with blogs and news. The iPad has a nice email client that I use for my main email inbox. Mail from mailing lists and things like that go to a gmail account and gmail on the iPad is so good that I prefer to read gmail on the iPad even when I’m home.

The only other thing I needed to do was to manage my blog. I queued up a couple of posts so I didn’t have to worry about writing any entries while I was on the road (I do all that in Emacs anyway so the iPad is not a place to write posts). I was able to moderate forum spam and respond to legitimate comments easily.

Touch typing just isn’t going to happen on the iPad, but I can do a bit better than hunt and peck on the virtual keyboard so responding to emails and blog comments was relatively painless. I suppose I could get a portable keyboard to use with the iPad but, honestly, I don’t feel the need. For the little amount of typing I do on it, the virtual keyboard is fine.

All in all the experiment was a success. Traveling with the iPad was easier than bringing along the MacBook. The few chores I needed to perform were easily handled on the iPad so I didn’t miss having the MacBook. And as a bonus, I didn’t have to carry a book to read on the plane—I just fired up iBooks and enjoyed an ebook.

Update: Over at IT World Brian Proffitt has a post on using (only) an iPad for 7 days.

Posted in General | Tagged | Leave a comment