Searching for close matches in C#

Posted by jeff on Aug 14th, 2007

Ever have trouble finding things?

This is just a quick code snippet to quickly find the nearest item from a generic list.  It leverages the .NET BinarySearch function, and it also uses the new Extension methods functionality of .NET 3.5.

Here's the extension in its entirety:

public static class BinarySearchExtension
{
    // Computes a distance between the query and a given object.
    public delegate double DistanceFunction<T>(T item);

    // Finds the nearest item to the query item in a sorted list.
    public static int BinarySearchNearest<T>
        this List<T> list, T query, 
        DistanceFunction<T> distFunc) {

        int n = list.Count,
            i = ~list.BinarySearch(query); /* O(log(n)) */

        return 
            (i < 0) ? ~i : /* query (q) was in the list */
            (i < 1) ?  0 : /* q < [0] */
            (i == n) ? n - 1 : /* q > [n-1] */ 
            Math.Abs(distFunc(list[i])) < /* [i] < q < [i-1] */
            Math.Abs(distFunc(list[i - 1])) ?
                i : i - 1; /* return the closest  */
    }
}

Here's an example of using it to search a list of dates:

List<DateTime> times = new List<DateTime>();
times.Add(DateTime.Parse("8/16/2007"));
times.Add(DateTime.Parse("7/7/2007"));

times.Sort(); /* Must be sorted before BinarySearch */

int i = times.BinarySearchNearest(DateTime.Now,
        /* distance: hours between now and t */
        t => t.Subtract(DateTime.Now).TotalHours);

DateTime nearest = times[i]; /* nearest is 8/16/2007 */

I have mixed feelings about extensions. They are clean and messy at the same time -- clean because you can, with very little code, add new functionality to old classes (even those that you didn't write). Unfortunately, because the extensions are separated from the classes they concern, it could easily set up a messy dependency situation. For many projects, I think a good practice is to keep all of your extensions localized together in one assembly.

Twiistup 2: Three unanswered questions

Posted by jeff on Aug 9th, 2007

Tonight we headed to the Twiistup 2 event in Venice, held at the "Air Conditioned Supper Club."  On the inside, it's a two-room bar with padded walls and a small stage.  AOL, apparently a main sponsor, had a primary spot on stage and was giving out T-shirts, which were catchy but unfortunately made significantly less cool by the non-subtle AOL branding.

We met some interesting people at the event.  There were a number of "showoffs," or companies with small demo booths set up.  One of the attending companies just created this realtime-social-product-browsing-map-thing, and I definitely took the opportunity to ask one of their employees what the feature was all about.  I still don't actually know how it's useful, but apparently it's addictive.  See if you can figure it out.

We saw Heather again, geek dinner organizer and twiistup 2 host.

The event left us with three questions:

  1. What's with the padded walls?
  2. Was I the only person there without an iPhone?
  3. Did we just hang out with Bono, lead-singer of U2?




My entrance interview Two minutes after we stepped in, I was interviewed by Bonny (of NoodleScar fame) while Adam ran away and took this photo.  The inverview touched on the conundrum of the padded walls, whether the microphone actually worked, and whether Adam and I had made it out of the 'garage' at all during the past few weeks.  I was a less than exciting subject, so we'll see if they squeeze anything out of it.

Update: Lan just informed us that the NoodleScar episode is up.  A brief clip of me did make the cut.  Does this mean I can join the SAG?

So, Bono? You be the judge.  We scoured the event's website, and noticed a reference to "surprise guests."  Hmm.  The best evidence we have is the following photo snapped with Adam's camera:

Bono, ono? I'm fairly certain this is fake Bono.  Seriously, the earlobes are off and this guy's chin is a little too dimply.  Adam thinks he's the real deal.  Or at least he was certain until we zoomed in on the ears a little more.  In any case, the host knows, so maybe she'll tell us tomorrow.

We also just noticed that our blog's sweet header somehow scored prime placement on the Twiistup homepage: 

Our logo: bigger than Microsoft and Yahoo combined!

Month 1: Breaking in the garage

Posted by adamjh on Aug 5th, 2007

A wise man once said:

Keep on going and the chances are you will stumble on something, perhaps when you are least expecting it. I have never heard of anyone stumbling on something sitting down.

And so has been the theme of month one. After roughly 9 months of sporadic brainstorming sessions about what our company might do should Jeff someday decide to stop pursuing his Ph.D. and I to leave my job, we chose on day 1 to table any further planning discussions and start hacking.

This continued for roughly 25 days (or 32,000 lines of code), at which point we were able to take a step back with a greater understanding than ever before of the beast we're attempting to tame -- what's easy? what's hard? what's been done before and what never has? how long should it take? what kind of people should we attempt to hire first and how soon? and so on...

We then decided to invest some time over roughly 3 days to revisit some of the "businessy" stuff. We jotted down all the company/product names that had been thrown out over time on our beat up whiteboard and evaluated them according to the nine dimensions suggested in the Igor Naming Guide, then discarded them all in favor of something else we came up with on a whim and decided we liked better.

We threw together 3 slides of the 10/10/15 that Guy, David, and Brad recommend, as a sanity check as to whether we could clearly and concisely articulate our vision/value. We explained what we were were building to a handful of friends in no more than 2-3 sentences, and listened to whether the response was a "What?" or a "Wow!", refining our vision down to a simple 5 words until the "What"s were no more.

As the weekend progresses and month 1 comes to an end, we're continuing to wrap up our first stretch of coding -- getting various disjointed pieces to fit together, grepping for BUGBUGs/TODOs, and ensuring we have something that works end-to-end however small in scope. Then it's on to another month of code, with a new set of goals.

In closing, I'll pose a question that's been on my mind lately to anyone out there who follows our journey:

Ambient OrbHow would you convey the value proposition of one of our favorite products, the Ambient Orb?

What kind of ROI can its customer expect by buying it?

What kind of pain does it eliminate?

Is it a vitamin, aspirin, or antibiotic (i.e. a luxury, nice-to-have, or need-to-have)?