Trapdoor Puzzles August 28th, 2009
Patrick Stein

With most logic or word puzzles, your goal is to find a solution. To make those puzzles interesting, the puzzle maker has to assure that there is a solution and that the solution is unique. This is true for crossword puzzles, sudoku puzzles, cryptograms, rebuses (rebi?), mazes, Lights Out games, and binary logic puzzles of this form: Alice is wearing red. John is older than Jimmy. The tallest person is not wearing green. Clue. Clue. Clue. Who is standing next to Alice? Rush Hour games and tanagrams are also usually crafted so that there is a unique solution.

Uniqueness

For some of these games, we mean a unique solution amongst all solutions without backtracking. For example, in solving a maze, we would not consider solutions that involve running down a corridor only to come back along the same corridor. For Lights Out games, the concept is simple but describing it takes work. Imagine that every square on the board, in addition to being lit or not, also has a letter ‘A’ on it at the start of the game. Whenever you press a button labelled ‘A’, it gets relabeled ‘B’. Every time you press a button labelled ‘B’, it gets relabeled ‘A’. Two solutions are identical if the board has the same configuration of ‘A’s and ‘B’s after both moves. Thus, hitting any button more than once was just a waste of time. However, the order that you hit the buttons makes no difference at all.

There is a notable crossword puzzle with two solutions. There are some notorious Sudoku puzzles with two solutions. I don’t know of any cryptograms with two solutions, but I am going to go asearchin’ some time.

Technically, a Sudoku puzzle with two solutions cannot be solved. You had to make a guess somewhere and it turned out you had twice the odds of being right that you should have. It is easy to accidentally take too many numbers out of the Sudoku grid and end up with an ambiguous puzzle. For a crossword puzzle, I doubt most people bother to check to see if the solution is unique. It probably is unique by sheer combinatorics. The same may be true cryptograms, as well. You’d have to specifically be trying to make them ambiguous to achieve it.

Trapdoors

Where are the trapdoors? Well, the puzzle creator has a much harder job than the puzzle solver for most games. It is easy to construct mazes and Lights Out games with unique solutions (in fact, it’s easy to show that if a Lights Out game is solvable, the solution is unique). It is not so easy to construct other puzzles that have provably unique solutions.

This brings us to the Discrete Logarithm Problem. Imagine that I told you that 3^x \equiv 16 \pmod{29} and asked you what x is modulo 28. There is no really easy way to solve this problem, yet it is easy to formulate such problems. I checked that 3^{14} \neq 1 \pmod{29}. Then, I picked x = 12 and plugged it in to see that 3^{12} \equiv 16 \pmod{29}. I started from the answer and was quickly able to generate a problem that I can guarantee has a unique solution.

This is called a trapdoor function. It is easy to calculate, but hard to invert the calculation. It’s also not a very fun problem to do. You will never open up the comics page of your newspaper and find five of these problems below the bridge column and above the horoscopes.

I can easily imagine a whole variety of Lights Out type games where lights have more than one state. It would be easy to prove, for a wide class of such games, that when a solution exists, it is unique. These would all be solvable by inverting a matrix whose coefficients come from a finite field.

What other puzzles could take advantage of trapdoor functions to make the game easier on the puzzle maker than on the puzzle solver?

UI Paradigm from Scratch August 28th, 2009
Patrick Stein

I’m not fond of MVC and yet I know of nothing better. What would I want in an alternative?

Most UI toolkits claim to follow the model-view-controller paradigm if they make any such claim at all. In my experience though, they either mush together the controller and view, or the model and view, or all three. As such, there isn’t an opportunity to have the same information represented in multiple places within the interface. Instead, you have repeated information that is synchronized through a complex scaffolding of change listeners. Yuck.

Target platform

First, I should mention why I want such a thing. I am planning to participate in a study group centered around this MIT OpenCourseWare course in Numeric Photography. I’ve done plenty of digital imaging in my day. The assignments for this course though seem to center on novel user interfaces to digital imaging and artistic value of the end results. The original course was all done as Java applets. I considered using Armed Bear Common Lisp to try to write Lisp code that interacted with the user through a Java applet. My initial tests on this went poorly since the ABCL code wants to read and write from your .abclrc and such. I toyed with code signing and permission granting on it, but wasn’t too satisfied with how easily someone else would be able to use it. Plus, I wasn’t too keen on doing so much Java.

So, I want to start with as few dependencies as possible for standalone Lisp applications. If I could keep the dependencies down to a GUI library of my own crafted atop cl-opengl and cl-png, that would be great. I suspect that I will have to throw in zpb-ttf at some point to get text into the UI, too.

Toolkit Structure

I am going to use the example of a simple checkbox. At its heart, a checkbox is simply a boolean value. The meat or logic of the code doesn’t have to care whether the checkbox is visible or enabled or being clicked or has recently changed. The meat of the code only has to know if it is checked or not. It would be nice if I could get away with just having a boolean anywhere in my code. However, some things will need to be triggered when the boolean changes. As such, I am going to need some setter/getter artifice around the boolean. So, let’s make a structure with a single boolean slot.

(defclass checkbox ()
  ((value :initarg :value :type (member nil t)))
  (:default-initargs :value nil))

Let’s call this the Checkbox Base.

This is all that most of my application will need to know. Somehow there is a checkbox. It is either checked or not.

How is the checkbox state presented in the interface? It could be drawn on the screen as a little box that either contains a check or not. It could be drawn as a menu item that either has a check beside it or not. It could be reflected in the state of some LED somewhere. It could be presented in hundreds of web browsers across the company as either a green box or a red box. Let’s call each of these a Checkbox Representation.

Somehow, each of these Checkbox Representations has to be notified when the value changes. If I am willing to also include a dependency on Cells (which hasn’t been touched since May of 2005), then I can get this kind of notification for free.

(defclass checkbox ()
  ((value :initform (c-in nil) :accessor checkbox-value)))

(defclass checkbox-as-colored-box ()
  ((checkbox :initarg :checkbox :type checkbox :reader checkbox)
   (color :cell t :initform (c? (if (checkbox-value (checkbox self))
                                    :green
                                    :red)))))

(def-c-output color ((self checkbox-as-colored-box))
  (redraw-checkbox-as-colored-box new-value))

Any time the value of the checkbox changes, the color of the checkbox-as-colored-box will change and the trigger to redraw-checkbox-as-colored-box will be invoked with the new color value.

If I don’t use Cells, then I have to create a layer around the checkbox that tracks who needs to be notified when the value changes. Let’s call this a Checkbox Monitor. It is very tempting to fold this right into the checkbox. After all, when the checkbox changes, the monitor has to know. For a slightly better division of functionality, one might make monitored-checkbox a subclass of checkbox:

(defclass monitored-checkbox (checkbox)
  ((listeners :initform nil)))

In this way, UI components can register with the monitored-checkbox, but the main application never has to notice that the checkbox has the weird methods for adding listeners and such. With an appropriate :around or :after method, the checkbox code doesn’t even have to know if it is part of a monitored-checkbox. It would be nice if the code didn’t have to know this at instantiation time, but I’m not seeing an obvious way around that without Cells.

With Cells, each representation could monitor the Checkbox Base. Without the Cells-type approach, there can really only be one Monitor per Base. (Technically, there could be more, but they could only be through a direct inheritance chain… you could wrap the Monitor with a Monitor2 and that with a Monitor3, etc. But, you wouldn’t want to try to instantiate a Monitor123 or anything like that.) For now, let’s explore the non-Cells case.

The idea so far is that you can create a Checkbox Monitor which is a subclass of Checkbox Base. Then, you can create some Checkbox Representations and register them with the monitor. The meat of your code can think of it as a Checkbox Base.

How is it toggled? There are a variety of ways that could happen. Someone could hit a global hot-key that toggles the checkbox. Someone could select a menu item that toggles the checkbox. Someone could mouse click on a representation of that checkbox. My application could receive an event from a remote source like a secondary display, a database, or a filesystem that toggles the checkbox. Someone could hit the space bar or the enter key while a representation of that checkbox has keyboard focus.

I am not sure we need to create a class hierarchy around changing the checkbox. We can simply call the setter on the checkbox. The monitor will catch it and notify everyone who needs to know. Further, the checkbox itself will be set for anyone who needs to passively query (rather than needing to track its every change).

The big question then is can we enable or disable the checkbox? This would have to either be a property of the Checkbox Base (which doesn’t seem right to me) or a joint effort spanning all places that wish to toggle the checkbox (which also doesn’t seem right). Fortunately, I think we can use multiple-inheritance and more :around methods to take care of this.

(defclass checkbox ()
  ((value :initform nil :type (member nil t) :accessor checkbox-value)))

(defclass monitor ()
  ((listeners :initform nil)))

(defclass enabler ()
  ((enabled :initform t :type (member nil t) :accessor control-enabled)))

(defclass enabled-checkbox-monitor (enabler monitor checkbox)
  ())

(defmethod (setf checkbox-value) :around (new-value checkbox)
  (when (control-enabled checkbox)
    (call-next-method)))

Is this any better than the status quo? I’m not sure. I will have to write more code to find out.

Alternatives to MVC? August 26th, 2009
Patrick Stein

The model-view-controller paradigm dominates the UI toolkit world. I should say, it dominates the talk about the UI toolkit world. Most UI toolkits have very poor separation between the model, the view, and the controller. For most UI toolkits, a text input field can only have one controller and one view. Further, all of the aspects of the controller, the view, and the model are accessed through the text input field object.

I tried to google around for “model view controller” alternatives and “model view controller” rethinking. The only alternative that I saw was DDP (data driven presentation). Data driven presentation seems like someone took the model-view-controller paradigm and collapsed the view state into the model. This makes for a somewhat nicer entity-relationship diagram because then the controller never has to speak directly to the view, it can just twiddle the data.

I don’t think data driven presentation is a real alternative to model-view-controller. It is a slight repackaging of something that’s never been packaged right before, to my knowledge.

I don’t really like the model-view-controller paradigm very much. I would love to hear about alternative approaches to representing the same control in multiple places in an application. Alas, in the absence of an alternative, I have been trying to think about how to do model-view-controller right.

Let’s try a checkbox

What is the model for a checkbox? At its simplest, a checkbox is either checked or not. It is a simple boolean value. The checkbox doesn’t exist in a vacuum though. It probably needs a list of listeners that want to be notified when the checkbox is toggled. So, the checkbox model is two things: a simple state and an initiator of state-change events.

Does the model have a label? I say, No. If the model had a label, then I cannot display it in two different places with two different labels. If it is going to have any sort of label at all in the model, it should merely be a label indicator. Let’s imagine that I am making an interface that is English on the left side of the dialog box and Spanish on the right side. If I am truly separating model from view, then I should be able to use the same checkbox model on both halves of the screen. I cannot keep the text label in the model unless one of my views knows how to translate. If one of my views is going to know how to translate, then both of them should. Me, I don’t think that either should.

What is the view for a checkbox? A checkbox view at its simplest is just an indicator showing whether the box is checked or not. It might be a rendering of the box on your screen either empty or containing a checked mark of some sort. It might be a rendering of the box on a remote screen. It might be the little Caps Lock light on your keyboard. It might be a green table cell on a web page.

Does the view have a label? I don’t know. It makes more sense here than in the model, but does it belong here? Suppose there is some event elsewhere that makes me want to change the label. Suppose my label was include all images. Then, suppose someone adds a sound file into the document, and I want to change the label to include all images and sounds. I have to track down all of the views and update them. I would still have to do this if the label were a separate entity apart from the checkbox. So, the question is, should it be a separate entity?

What is the controller for a checkbox? For a checkbox rendered to the screen, the controller has to recognize mouse clicks in the same area that the view is in. Either the controller has to moved around lock-step with the view so that it has the same geometry, or the controller has to know enough about the view to tell whether a mouse event hit it. Similarly, if the checkbox has focus, pressing the space bar or the enter key should probably toggle the checkbox. The view has to know if it has focus so that it can render itself to appear focused. The controller has to know if it has focus to know whether to care about the key press.

It is tempting to combine the controller into the view. It definitely simplifies the geometry and focus questions. Those become shared information. There are other possible controllers for the checkbox, too, though. Maybe the checkbox has a global hot-key. Maybe there is some menu item that uses the same checkbox model (though a good menu item will also act as a view of the checkbox model, so it really is a combination view and controller again).

Is enabled a property of the model or the view or the controller? I say, not the model. Of course, this is thorny. Suppose that my checkbox isn’t relevant at this point in my application. I should disable it. However, I have to update all of the views attached to this model instead of just updating the model. Feh. Of course, I also have the option of disabling just some of the views. For example, if my application supported multiple users watching, but only a single one editing, then I would need to disable this checkbox in every window except the one on the editor’s desktop.

Is focus a property of the model or the view or the controller? It shouldn’t be part of the model. If I am displaying the same model to two different desktops, there is no reason that the two users should have to synchronize which control they are using. Heck, what’s to say that the second user even has all of the controls that the first user has?

Where we are

The controller and view definitely need to know about the model. The controller and view both need to know about focus. The controller and view both need to know about enabled. The model needs to be able to tell all of its views that they are stale. For items that are going to be taking mouse input, the controller definitely has to know where the view is being rendered.

The fact that the controller and view both need to share the focus and enabled information (as well as caret position and selection range and such for other types of controls) indicates that there should be another entity in this paradigm that both the controller and view can refer to. There is both a model of the item and a model of how that item is to be presented—a model and a presentation model, if you will. If there are two users sharing the same text input field, then the GUI should have the choice of sharing the presentation model across users so that they both have the same caret position and selection range or allowing them each their own presentation model so that they each have their own caret position and selection range. It is further complicated by the fact that you may want to share the caret position and selection range without sharing the focus or enabled settings.

I am afraid that I haven’t reached much conclusion here. I still don’t have answers or alternatives. Any references or suggestions would be greatly appreciated.

ScreenFlow: Review August 21st, 2009
Patrick Stein

I downloaded the trial version of ScreenFlow in early July. I performed a few simple tests with it, liked what I saw, and bought a license. Since purchasing the license, I have used it to record and publish six presentations. Overall, it is a wonderful program that more than lives up to the license price.

How I’ve Been Using It

I have a 2.4GHz MacBook Pro, a FireWire webcam, a stand-alone video camera, a tabletop tripod, and a BlueTooth headset. I brought all of this equipment to the TC Lispers meeting in July.

I failed to record the first presentation. The BlueTooth headset, of course, has a rather opaque user interface. It has an on-off switch. It is unclear which position is on and which is off. It has two buttons for volume control. It has one button that does everything else depending on the current state and whether you click, double-click, or triple-click. I did something wrong. This resulted in a recording failure that I didn’t notice until after the presentation. Most of this was the headset (and me). ScreenFlow could have done better at alerting me (more on that below).

For the other three presentations that evening, I recorded audio through the built-in microphone on the MacBook. This worked famously, and I used it to record the August presentations, too.

Because of the projector we are using, I record the screen at 1024×768. That resolution is plenty, in my opinion. For the July presentations, I recorded some video directly with ScreenFlow from the FireWire webcam. I recorded additional video with the stand-alone video camera. I used the video from the stand-alone camera in two of the final presentations in place of the webcam video because the contrast was better. I didn’t use the stand-alone camera video in the other presentations because I had to change tapes in the middle of one presentation and ran out of batteries in the other.

I forgot to bring my FireWire adapter to the August meeting, so I recorded all of that video with the stand-alone video camera.

After each presentation, I stopped recording and saved (more on this below). The next day, I prepared the final video. I resized the whole thing to 1024×640 to get a more dramatic aspect ratio and to give me a little room to put the screencast and video side-by-side. I added in a couple images (a TC Lispers logo and a Creative Commons logo) and a line of text.

For those presentations where I used the stand-alone video camera’s video, I imported that into ScreenFlow in the comfort of my own home. The audio from my stand-alone camera doesn’t import into ScreenFlow very well. As such, I ended up toying with the video until I got it synced with the audio I had recorded from the built-in microphone (more on this below). I think I’m going to use a clap board next time.

I positioned all of my pieces, added some shadows, added some reflections, and added some Video Actions to transition where the screencast and video sat in space.

Then, I exported the clips and uploaded them to Vimeo. I’m quite pleased with the results.

What It Does Wonderfully

If you can have ScreenFlow record your screen, audio, and video all at the same time, then most everything you’ll want out of this software is a dream.

You’ll have your screencast and video already there. You can add in text and stills. You can add in additional audio or video sources. You can position, scale, and tilt your visual elements. You can give them drop-shadows and reflections. You can adjust the volume of your audio or add audio effects to it.

You have a great deal of control over the text. You can change the font, the alignment, the fill color, the outline color, the background color, and the margin and corner-rounding on the text background. For those color adjustments, you can even adjust the opacity.

For shadows, you have control over the angle, color, offset, opacity, and blur-size. For reflections, you have control over the opacity.

You can add video or audio actions to any clip. You can select multiple clips at once to add an action to so that all of the actions happen at the same time. The actions aren’t so much actions as transitions. You can set the parameters: (opacity, scale, position, orientation, reflection, shadow, etc.) before and after the action. The action will transition from one to the other.

The actions take a little getting used to. When I first started, I had a tendency to try to set the position of a clip before and after an action. The tricky bit is that when you set a parameter before the action, that parameter has effect the whole way back to the last action (or the beginning when there are no prior actions). I surprised myself accidentally several times forgetting to put in an action at the place I want to transition. My workflow now is to get everything in its starting state, go through to where I want the first action, put in the action, and only change the parameters after the action. ScreenFlow inserts the action to finish at your current position in the timeline so this method is the natural way they envisioned, I believe.

Once I have all of my video imported and synced, it only takes me about fifteen minutes to place the logos, other text, get all of the parameters set the way I like (shadows on everything, reflections on screencast and video), add all of the actions that I want, and start exporting. Exporting at high quality takes hours and hours, but that it mostly a function of the multipass compression, not of ScreenFlow itself. You can export at low quality a good deal faster. My big concern though is to be sure you can read the slides and live-typing even after it comes through Vimeo though. As such, I let it export overnight.

What I Wish It Did Better

When you start a recording with ScreenFlow, it gives you a countdown to start recording. I put my Keynote presentation in Fullscreen mode before the countdown completed. It wasn’t until I closed my Keynote presentation that I saw that ScreenFlow had bailed because it could not get input from the microphone. Maybe ScreenFlow can’t bring up a dialog in front of a Fullscreen application, I don’t know. But, it could have told me audibly that it was having issues.

When I did test recordings, I didn’t do anything over five minutes. When I (successfully) recorded the first hour-long presentation, I hit Save. I got the spinning beach ball for a very long time. I was concerned that the application was hung. I am thinking that it was just recoding the video it had pulled in from the webcam. For the August meeting, I wasn’t recording video with ScreenCast during the presentation. Saving at the end of the presentation took no time at all. While I was watching the beach ball spin, I was starting to worry that I had paid a whole bunch for a license that wasn’t going to work for my purposes. The beach ball finished after about eight or nine minutes… just in time for the next presentation. Everything saved perfectly. I could have used a progress bar instead of a beach ball though.

ScreenFlow does not do well importing the audio from my stand-alone video camera. I can pull this audio into iMovie just fine. I might be able to pull it in with iMovie and add it into my ScreenFlow presentation. I don’t know. When I pull it directly into ScreenFlow though, the audio has terrible digital distortion like they made the wrong guess about signed or unsigned samples. You can still follow along enough to help synchronize it with the audio recorded from the built-in microphone, but you’d never want it in your final movie.

Synchronizing an independent video or audio source that wasn’t being pulled into ScreenFlow during the presentation is annoying. I think I can mitigate most of it by using a clap board before things get underway. Trying to do this retroactively was annoying. I had to move the screencast and the built-in audio clips away from time zero. Then, I had to find an area where there was a distinctive sound. I then had to play with moving the newly imported video clip back and forth in time until things were close enough. Fortunately, the human brain is very forgiving about badly synchronized audio and video.

Once I got the clips aligned, I had to move the scrubber back to the beginning of the built-in microphone recording, trim all of the clips from the front to the scrubber, and then move all of the clips back to time zero.

I tried using the markers feature to help me synchronize clips. Unfortunately, the markers are locked to the timeline and I couldn’t see a way to clamp a particular part of a clip to the marker.

I used the Show Audio Waveforms feature to help me synchronize the audio. This was a bit awkward because of the digital distortion in the video camera import. It was also a pain because the timeline is impossible to work with when it is trying to display the waveforms. You can’t have an hour long clip with a waveform and use the magnification slider on the timeline. You end up getting a beach ball part way through your drag. You have no idea where it will think you let go of things when the beach ball finally pops. You can’t move around the timeline or move things within the timeline with the waveforms displayed either for these lengthy clips. I turn off the waveforms as soon as I can. They don’t add much to my process, and they really get in the way.

The program has a feature to add Callouts. These can either highlight the mouse position or the foreground window. In my case, I wanted to retroactively add in Callouts. During the presentation, the presenter was pointing at the projected image with his hand. The callouts were locked to where the mouse was. It would have been fabulous if it would have let me position a callout during edit time instead of being stuck with where the mouse was during the presentation.

The Upshot

It has some frustrations, but it does most things very smoothly. Turn off the Show Audio Waveforms, use a clap board, and enjoy. The output is unmatched, and the interface is very easy to fall into.

Taking the Long Way Home August 14th, 2009
Patrick Stein

I was pondering non-deterministic, shareware nagging. Suppose that every time you performed a particular function, I wanted to randomly decide whether to nag you this time or not. Suppose further that I’d prefer not to have to keep track of how long it’s been since I last nagged you, but I’d still like you to be nagged about once every n times. Naïvely, one would expect that if I just chose a random number uniformly from the range zero to one and nag if the number is less than \frac{1}{n}, this would do the trick. You would expect that if you rolled an n-sided die each time, that you’d roll a one about every n-th time.

Me, I’ve learned to never trust my naïve intuition when it comes to probability questions. Well, it turns out that the naïve answer is perfectly correct in this case. Here is the epic journey I took to get there though.

Here’s what I wanted. I wanted to know the probability p needed so the expected number of trials until the first success is some number n given that each trial is independent and is successful p proportion of the time. Suppose for a moment that I decided I am going to roll a six-sided die until I get a one. What is the expected number of times that I need to roll that die to get my first one? What I want here is the inverse problem. How many sides should my die be if I want it to take n tries (on average) to get my first one?

tree In the picture at the right, each circle represents a trial. Each square represents a success. What I am looking for is what value should I pick for p so that if you go left p proportion of the time and go right the other (1-p) proportion of the time, you will expect to hit n circles along your descent. You could, if very unlucky (or lucky in this case since I’m going to nag you) go forever to the right and never get to a rectangle. So, already, we’re expecting an infinite sum.

Indeed, the expected number of circles you cross in a random descent of this tree is E(p) = \sum_{k=1}^{\infty} k \cdot p \cdot (1 - p)^{k-1}. Massaging this a little, we can get it into a simpler form: E(p) = \frac{p}{1-p} \sum_{k=1}^{\infty} k \cdot (1 - p)^k.

That infinite series is pretty nasty looking though. So, we whip out a handy table of infinite series and see that:

\sum_{k=1}^{\infty} k^m q^k = \frac{1}{(1-q)^{m+1}} \sum_{k=0}^m \left[ \sum_{j=0}^{k+1} (-1)^j { {m+1} \choose j } (k - j + 1)^m \right] q^{m-k}

Fortunately, in our case, m = 1. As such, we can reduce this significantly:
\frac{1}{(1-q)^2} \sum_{k=0}^1 \left[ \sum_{j=0}^{k+1} (-1)^j { 2 \choose j } (k - j + 1) \right] q^{1-k}

\frac{1}{(1-q)^2} \left\{ \left[ \sum_{j=0}^1 (-1)^j { 2 \choose j } (1 - j) \right] q + \left[ \sum_{j=0}^2 (-1)^j { 2 \choose j } (2 - j) \right] \right\}

Now, we note that when j = 2, the last summand is zero. So, \sum_{j=0}^2 (-1)^j { 2 \choose j } (2 - j) = \sum_{j=0}^1 (-1)^j {2 \choose j } (2 - j). As such, we can combine our two summations into one:
\frac{1}{(1-q)^2} \sum_{j=0}^1 (-1)^j { 2 \choose j } \left[ (1 - j) q + (2 - j) \right]

And, since j is only going from zero to one, it’s easy enough to write out both terms of the summation:
\frac{1}{(1-q)^2} \left\{ { 2 \choose 0 } \left[ q + 2 \right] - { 2 \choose 1 } \right\}

\frac{1}{(1-q)^2} \left\{ q + 2 - 2 \right\}

\sum_{k=1}^{\infty} k q^k = \frac{q}{(1-q)^2}

Whew! Big sigh. We’re through the ugly parts. Now, in our case, q = (1-p), and the equation we were interested in was E(p) = \frac{p}{1-p} \sum_{k=1}^{\infty} k \cdot (1 - p)^k. Plugging in (1-p) for the q in our infinite series solution, we find that

E(p) = \frac{p}{1-p} \cdot \frac{1-p}{p^2} = \frac{1}{p}

Two pages of ugly, ugly algebra bears out the simple guess. Wheee! If we want E(p) = n, then we have to pick p = \frac{1}{n}. Hooray!

l