Track-Best Library Released May 9th, 2013
Patrick Stein

In doing a problem set from the Internet a few weeks ago, I found myself writing awkward constructions with REDUCE and LOOP to try to find the best one (or two or three) things in a big bag of things based on various criteria: similarity to English, hamming distance from their neighbor, etc.

I wrote a macro that encapsulated the pattern. I’ve reworked that macro into a library for public use.

Acquiring

Using

There are a variety of examples in the README and the tests directory.

Here is one example to pique your interest. Suppose you have some data about the elevations of various cities in various states and you (being a Moxy Fruvous fan) want to know What Is the Lowest Highest Point? Here’s how you might tackle that with the TRACK-BEST library:

(let ((data '(("Alabama"  ("Birmingham" 664)
                          ("Mobile" 218)
                          ("Montegomery" 221))
              ("Alaska"   ("Anchorage" 144)
                          ("Fairbanks" 531))
              ("Arizona"  ("Grand Canyon" 6606)
                          ("Phoenix" 1132)
                          ("Tuscon"  2641)))))
  (with-track-best (:order-by-fn #'<)
    (dolist (state-info data)
      (multiple-value-bind (city altitude)
          (with-track-best ()
            (dolist (city-info (rest state-info))
              (track (first city-info) (second city-info))))
        (track (list (first state-info) city) altitude)))))

With this limited dataset, the end result would be (VALUES '("Alaska" "Fairbanks") 531). The inner WITH-TRACK-BEST finds the highest city in each state. The outer WITH-TRACK-BEST finds the lowest of these.

4 Responses to “Track-Best Library Released”

  1. Stanislav K.
    2013-05-10 @ 8:52 AM

    The idea is very elegant!

    The :single keyword argument mentioned in the README seems not to be implemented (contrary to :always-return-list). Have you abandoned :single?

    • pat
      2013-05-10 @ 9:28 AM

      You are correct, I got rid of ‘:single’ replacing it with ‘:always-return-list’ and failed to update the information in all places.

      I will correct the documentation. Thanks.

  2. Stanislav K.
    2013-05-12 @ 11:16 AM

    Do you plan to add the feature `collect all the best items’? To tell the truth I couldn’t hepl hacking TRACK by adding corresponding branch to the body of COND (and replacing = with EQL on line 35 of track-best.lisp). For personal use only. :$ http://pastebin.com/0tF4ReEJ If you find the code helpful, you can use it verbatim or modified without credits. 🙂

    Very nice job!

    • pat
      2013-05-12 @ 10:13 PM

      Indeed, I have been pondering adding a ‘collect all of the best’ option. I’m not settled yet on how I wanted to deal with someone asking for ‘keep 5’ and there being one first place, one second place, and ten third places yet. I’ll ponder it.

      Thanks for the pastebin snippet. I’ll look it over.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <br> <cite> <code> <dd> <del datetime=""> <dl> <dt> <em> <i> <img alt="" height="" longdesc="" src="" width=""> <ins datetime="" cite=""> <li> <ol> <p> <q cite=""> <s> <strike> <strong> <sub> <sup> <u> <ul>

l