Yesterday, Tozier and I met at the BAR1. Rather than work on his issue for the day, we decided to take his mind partly off it and work on the ants. We had read the “solution” from Winkler’s2 book, which goes, in part, like this:

One simple way to catch the ant is to use each of two spiders to “control” an edge. To control an edge PQ, the spider chases the ant off the edge if necessary, then patrols the edge making sure he is at all times at most one third the distance from P (respectively Q) that the ant is.

You can think of this as removing two edges from the ant’s available map, because he can’t cross the end points of the “controlled” edges: when he gets to the end point, the controlling spider also gets there. When you remove two edges from a cube, the remaining edges are divided into one or more acyclic graphs: there are no cycles left. This means that the third spider can simply drive the ant to a dead end and chow down.

Tozier and I thought it would be interesting to code up the spider’s strategy. One interest we have is in whether there can somehow be a single spider strategy, not two. Might it be possible to get the edge-controlling behavior operating in two of them, and the hunting in the remaining one somehow? We thought that would be more elegant, and more like what we think insects3 know. We feel the two strategies are an interesting mathematical existence proof but a bit inelegant.

Not a digression …

Long ago Abby Fichtner started a bit of a Twitterstorm with an innocent tweet about going fast. For some reason that thread reappeared last week, and caught my eye. It’s neither the first nor the last time this notion has come up:

A number of the old guard chimed in on this:

Jim Coplien: Speed kills. “Fast” doesn’t appear in the Agile Manifesto.

Abby: Validate 1st, then you can worry about the software.

Bob Martin: Don’t validate with crappy software.

Abby: Disagree. Validate with the crappiest thing you can get away with to learn quickly.

Ron Jeffries: I think advising today’s programmers to do the crappiest work they can is wrong. And redundant.

Clearly there’s a valid need to go fast to get valid feedback. Clearly there’s a need for “quality” to have a viable product. That’s not a disagreement that will be settled on Twitter. Nor will it likely be solved anywhere. Maybe you can find the thread to see some of the other ideas that were tossed out along the way. Maybe you can find a new thread on the same basic topic: can we go faster by lowering quality?

What does this have to do with spiders and ants? Let’s find out.

Back to the bugs …

After a bit of chatter, we decided to write some code to allow a spider to control an edge. It seems easy enough from the description. Take the edge length PQ to be one. Since the ant cannot be on that edge, his shortest path between P and Q is three. So if the spider is at least 1/3 as fast, she can move from one end to the other in time to block the ant (or eat him if he is foolish enough). To do this, she has to keep her proportional distance between P and Q the same as the ant’s proportional distance: when the ant is 1 unit from P, the spider must be 1/3 unit from P, and so on.4

No problem. We decided to start bottom up and compute the distance of a bug from a point. We have the cube represented this way, with points and edges:

corners = { 
    vec2(-400, -400), vec2(-400,400 ), vec2(400, 400), vec2(400, -400),
    vec2(-200, -200), vec2(-200,200 ), vec2(200, 200), vec2(200, -200)

cube = { {2,4,5}, {1,3,6}, {2,4,7}, {1,3,8}, {1,6,8}, {2,5,7}, {3,6,8}, {4,5,7} }

The corners are the coordinates of, well, the corners. The cube structure says that if you are at corner number 1, the corners you can reach are numbers 2, 4, and 5. And so on.

A bug has a start corner, a stop corner, and is a fraction of the way from start to stop. The fraction always goes from zero to one:

ant = {}
ant.start = 1
ant.stop = 2
ant.frac = math.random()
ant.speed = speed*3
ant.nextGoal = nextAntGoal

s1 = {}
s1.start = 2
s1.stop = 6
s1.frac = math.random()
s1.frac = 0
s1.speed = speed
s1.nextGoal = nextGoal

So, um, the distance from a corner #n to a bug who is 0 < frac < 1 between corner #p and #q is, um, …

I guess we need to get the distance in units between two points. It’s easy(!) to see that if you are at corner #n, going to #m then when you look at cube[n], if m is in there, the distance is one. If not but cube[n] is {p,q,r} then if m is in cube[p], or cube[q] or cube[r], then the distance is two, otherwise it is three.

Then to get the distance to the bug you just consider frac or 1 - frac, depending which way the bug is going, and there you are, the distance between a point and a bug.

But that’s not quite what we want. Our spiders move at a constant speed, as does our ant. So what we want to do is assess what proportion of the way along the path between our end points the ant is, and move toward that proportion of our edge. We figured that would do it.

Note that if the ant is on one of the two 3-step paths between our spider’s controlled edge’s end points, p and q, then he’ll be a proportion frac from one of our ends and 1 - frac from the other. The spider will have a specific place she needs to be to protect her edge.

But if the ant is on one of the edges that isn’t a path between p and q, our spider has some flexibility. The sum of the ant’s distances between the controlled points exceeds 3, the sum of the spider’s fractions exceeds one, and the spider has some room to maneuver without losing control. We drew some pictures and considered whether that meant she could move to some other edge, while staying in range of her controlled edge, and whether that would let her help in driving the ant, and whether she could even switch allegiance and control a different edge, and whether that would help corral the ant even more quickly.

MAP OF CUBE is just data, magic numbers, has no brains. Bugs have no real methods, are mostly data. Abstractions limited. No tests. Difficult to refactor.

Frankly, Tozier and I are stuck. We can’t go forward. And we’re only about five hours in!

Where’s your rapid release now?

Whether Abby’s tweet is three years old or three hours, we have managed to build a really cute little app whose code cannot accept the next feature we need in order to solve the problem. Now, sure, in another five hours we could do it over again, this time with tests and a better design. And that would hardly show up as a bump on the graph.

In the real world, this might have happened after five days. That would be an entire Sprint wasted. Or five weeks. That could be a disaster for getting rapidly to market to test ideas.

Does crufty code scale? I suspect that it does: if anything, it’s far worse at scale, if only because time costs money.

Yes, sure, it’s entirely possible to do too much polishing of the code: we could spend days improving each variable name, and that would be bad. It is entirely possible to do too much testing: we could test all the edges, all the distances, all the corners. We could test forever.

I have never encountered a project whose code was too clean. I’ve encountered many whose code was so bad they couldn’t afford to build features they needed. I’ve never encountered a project with too many tests. I’ve encountered many who had so many bugs their customers literally refused new releases because they feared more damage.

You have no idea how much crap we programmers can generate when you tell us we can.

Three years ago, or three minutes, “Validate with the crappiest thing you can get away with” is bad advice. Oh, yes, you shouldn’t have the slightest bit more quality than you need in order to go as far as you need to go. But you don’t know how far you need to go … and you have no idea how much “crap” we programmers can generate when you tell us we can.

  1. The “Brighton Agile Roundtable”, our putatively amusing name for the table we generally sit at at the Barnes & Noble coffee shop in Brighton Michigan. Stop by and see us sometime if you’re in the area. Do contact me first to be sure we’ll be there.

  2. Winkler, Peter. Mathematical Mind Benders, CRC Press, 2007.

  3. OK, arachnids. Bugs, OK? Nopes. Just be grateful I didn’t destroy them with fire; then we’d have no articles at all.

  4. Confused? That may be the point …