Studio711.com – Ben Martens

Key Lime Pie

I’ve had key lime pie on my mind for quite a while, and, while standing in the grocery store last weekend, I decided it was time to give it a shot. I pulled up a recipe on my phone and was shocked at how simple it was. Key lime juice, egg  yolk, and sweetened condensed milk. But what is a key lime? Can I use regular lime juice? I ended up finding a bottle that said it was key lime juice so I went for it. It turns out that key limes are a lime variety thought to have originated in the Florida Keys.

It was ridiculously simple to put the pie together. I didn’t do any whipped topping, but it came out delicious. This recipe comes from the Nellie and Joe’s Key West Lime Juice bottle.

Ingredients

  • 14oz can sweetened condensed milk
  • 3 egg yolks
  • 1/2 cup key lime juice
  • 9”graham cracker pie crust

Mix all the ingredients together and pour it into the pie crust. Bake for 15 minutes at 400 degrees. Let sit for 10 minutes before refrigerating. Serve cold.

DAWG Part 2

This post assumes that you’ve read at least the radix tree portion of the post from two days ago. Given that tree built from my dictionary of 100,000 words, what word would require the most nodes to be touched? One key is that the children of every node are sorted alphabetically.

So thinking logically about this, it’s probably going to be a long word. It’s probably going to contain a good number of letters that are towards the end of the alphabet. “aadvark” for example, is not going to work because right away we find the string “aa” after looking at only two nods. “zoo” on the other hand takes 26 nodes just to find the z.

I solved this by pumping all 100,000 words through the radix tree and counting how many nodes I touched for each word. The winner was “superstructures". Here are the nodes I touched at each level:

a b c d e f g h i j k l m n o p q r s
a c e f g h i k l m n o p q s t u
a b c d e f g i k l m n p
e
r
a b c e f g h i l m n o p r s
a c e i m o p t
a i o r
a e o u
c
t
u
r
a e
s

Now you have learned your random piece of trivia for the day. I can’t imagine the situation where this would be useful knowledge. Also, this answer would vary depending on the dictionary you use.

PS. I haven’t had a ton to write about so you get stuck with whatever thoughts fly through my brain. Scary, eh? I wonder what normal people think about.

Lulu

Two years ago, I raved about Lulu.com as I finished publishing a hardcover book for each year of my blog going back to 2002. It’s time to give them another plug.

As you saw in the moblog, I just published volumes 2008 and 2009 of my blog book series. 2008 was by far the longest book yet (over 700 pages) and for 2009 I included all my Twitter updates in the appendix. Ridiculous? Why yes, it is. No I don’t expect anyone to buy any of these, but I love seeing them up on my shelf and I dream that some day I’ll have offspring that will enjoy flipping through them. If you want to look inside the books, check out my Lulu storefront. The PDFs are free.

I also used Lulu to create the guestbook for our wedding. It’s a 9”x7” hardcover photo book. There are photos spread throughout the book with lots of white space. We’re hoping that people will write comments/thoughts instead of simply signing their name. Or maybe it will just end up looking like a high school yearbook “Friends 4 EVA!”

Directed Acyclic Word Graph

If that title wasn’t warning enough, you should know that this is going to be a pretty geeky post. I thought I’d do a little writeup of the project I’ve been toying with for the last couple weeks and I think a handful of you will enjoy it.

It all began when I started thinking about how you would write a program to find all the words on a 5×5 grid of letters (like Boggle.) There are many apps that do this already, but how do they work? How do you take a dictionary of 100,000 words and quickly apply to it to a bazillion possible letter combinations on a 5×5 grid and find all the valid words?

Radix Tree

I started off by reading in all the words and storing them in a radix tree. There is one root node and then the children of that root node are the distinct first letters in your word list. For a full dictionary you’ll probably end up with that first level of the tree having 26 nodes, one for each letter. This pattern continues down the tree so if you grab any node in the tree, the nodes above it correspond to the prefix of a words and all possible routes down through the children correspond to valid suffixes. Take any path from top to bottom and you have a word in the dictionary.

Each node also contains a flag that we’ll call Terminal which is true if that node can end a word and false if it cannot. So in the example on the right, the “n” in “one” would have Terminal = true because “on” is a valid word.

This turns out to be a very quick way to determine if a string of letters is a valid word. But there is a lot of extra data in the tree. For example, in the diagram on the right, the ending letters in “one” and “three” are identical nodes. There’s room for improvement.

Directed Acyclic Word Graph

As I was thinking about ways to compress this tree a little bit, DaveM pointed me to DAWGs (Directed Acyclic Word Graphs.) To create the DAWG, I create an array of pointers to all the nodes in the tree sorted by their depth in the tree. Starting at the leaf nodes (depth = 0) and moving up to the root, I apply the following algorithm

For each pair of nodes at depth x, if the two nodes have the same character and the two nodes have the same terminal flag and the two nodes have identical subtrees then remove node2 from its parent and add node1 to the childlist of the parent of node2.

Done correctly in a large word list, you can throw away a half to two thirds of the nodes in you tree!

Storing the Graph

It takes a while to build and compress the graph so it makes sense to serialize the tree so that I can just read it in from disc and be ready to go. I encoded each node as a 32-bit number. The first 5 bits represent the character (enough to store the 26 letters in the alphabet), 1 bit represents the terminal flag on/off value, and the last 26 bits represent the array index of the list of the node’s children. I flatten the tree into a jagged array where each node has a slot in the array and the value of that slot is a series of 32-bit numbers which represent it’s children with the above encoding scheme. The algorithm looks like this:

Get a list of the nodes in breadth first order.

Foreach each node in the BFS list look at each of the node’s children. If the child does not have a slot in the array, create an array slot and store that index in the child node. Encode the child node into the 32-bit number and append it to the list of the parent node’s children.

So for any array index N, the list of 32 bit numbers in that array slot represent the children of that node.

Writing this out to disc is pretty straightforward. The only special steps I took were to start the file with the length of the array and then when I write each array slot, I start with the number of children at that position. This speeds things up when I read in the file because I can allocate the right sized array.

Putting It to Use

Now it’s time to put the DAWG to use. I begin by generating a random 5×5 board. I use a weighting scheme to favor the more common letters and produce boards with more words. I then start at look at each node and follow this algorithm:

If this spot hasn’t been visited and the current string plus the letter on this spot is a valid substring in the DAWG, mark this spot as visited and search again looking in all 7 directions. If the current string is a valid word in the DAWG, add it to the list of found words.

Once that’s done I sort the found word list for quicker lookup. Now the player can start the game. When they punch in a word, it’s a simple lookup in that sorted list to determine if it’s a valid word. Since I know what all the valid words are, I can tell the user they have found X% of the words and then show the full word list at the end of the game.

Performance

The speed of the DAWG generation and serialization doesn’t really matter since it only happens once, but I can plow through 100K words in roughly 30 seconds. I’m writing this game for my phone which has a 528MHz processor in it. I can read in the DAWG from disc and load the array into memory in about 9 tenths of a second. Generating the random board and finding all the words happens in only 1 tenth of a second!

The next step is to give this game a little nicer GUI and add a timer, but I always get sidetracked playing the game instead of trying to improve it. This might be as good as it gets before I move on to the next hobby project.

Buyer’s Remorse?

I bought my black 2009 Kawasaki Concours 14 ABS one year ago this week. In honor of that event, I decided to check out the 2010 model and see what they changed. It’s the third year of the Concours 14 and they made quite a few significant improvements.

  • Traction control
  • Coactive-braking technology which links front and rear brakes (can be turned off)
  • Fuel economy assistance mode to improve mileage by about 25% when cruising on the highway.
  • Blue color (they still offer black too)
  • Redesigned side fairings to redirect exhaust and keep the rider cooler
  • Heated handgrips
  • Tank bag hooks
  • Side mirrors were raised
  • Larger, redesigned windscreen which is supposed to reduce turbulence around the helmet

A lot of these things would be nice to have, but if I had to pick two I’d pick the new side fairings and the fuel economy mode. I might stop by the dealer to see if the fairings are compatible with the 2009 bike.

But do I really have buyer’s remorse? Nope. You know what the 2010 model doesn’t come with? The 5000 miles of good memories I put on my bike in the last year.

Grammar Be Hard

I’m finishing up the editing for blog volumes 2008 and 2009. The technical process is pretty quick because I have a tool that does the following:

  • Connect to the database behind the blog.
  • Pull down each post and figure out which categories it belongs to.
  • Append the post to an HTML file.
  • Load the single HTML file for the whole year into Word.
  • Apply a custom style to do 90% of the formatting.
  • Do a similar process for the moblog pictures and Twitter posts.

From there, it’s a lot of manual steps:

  • Convert all the pictures to grayscale (done with a macro I wrote)
  • Make sure pictures are the right size. Sometimes this means making the page-wide images just a bit smaller to fit more than one on a page.
  • All hyperlinks get a footnote on the page listing out the URL, but sometimes I’ll print the full URL as the text for the hyperlink in the post. I go through and manually remove the footnotes in those situations.
  • Check page breaks and reformat where possible to give a better layout.
  • Spelling and grammar check.

I debated for quite a while about the spelling and grammar check. This isn’t meant to be a literary work but rather a view of my life as I saw it at that time, and if I wrote with errors, shouldn’t I include them? I decided to fix everything except the Twitter updates. I hate seeing all those mistakes and seeing them in print is even worse. It’s amazing how many errors you guys let slide without making fun of me. Thank you.

Most of the time, the errors are just typos, but I do make on grammatical error fairly often: “more ____” vs adding “-er.” For example, which is correct: “riskier” or “more risky”? There are many pages on the web to cover this topic, but I have yet to find a quick answer. Maybe there isn’t one. Or maybe you teachers can help me out. For now, I take solace in the fact that many mistakes I thought I was making turn out to be correct after all.

I’m still very happy with lulu.com for publishing. 2008 is going to be about 700 pages long and it will cost me less than $30 to get a hardcover printed copy of it. I find that amazing!

Chili

I love chili, and when I make chili, I generally say the spicier the better. I made it last week and I think I finally made it too spicy even for me. I won’t go into details. You should just be thankful you don’t live with me. Here is the basic recipe I use and I’ll point out where you can adjust the heat.

Ingredients

  • 2  tsp  Each – Salt, Pepper
  • 2  tbsp  Each – Chili Powder , Sugar
  • 1  lb(s)  Lean Ground Beef or Turkey
  • 1  can(s)  Tomato Soup, 10 3/4 oz
  • 3  can(s)  Red kidney beans (Undrained) 15 oz cans. I’ve also used “chili beans.”
  • 2  can(s)  Stewed Tomatoes, Italian/Mexican style, 14 1/2oz
  • Cheddar cheese and sour cream to top the chili when you serve it

Brown ground beef, drain, put in 4 quart pot. Add all other ingredients. I drain off a bit of the juice in the beans but leave most of it. Adjust spices to your liking. Sugar reduces the acidity of tomatoes. Bring mixture to a boil, stirring constantly! Once boiling, reduce heat to simmer, and cover pot. Simmer for 2 hours, stirring every 15 minutes to prevent burning on bottom. After 2 hours, remove cover and continue to simmer until desired thickness.

Tips:

  • This works better on the stove than in the crock pot. Don’t forget to stir every 15 minutes though. It will burn if you don’t.
  • Taste it about an hour in and see how the spices are doing. Add sugar if it’s too spicy and add pepper and chili powder if it’s not hot enough.
  • If you know you like it hot, chop a jalapeno and throw it in at the beginning. I used two jalapenos last time and that was too much for me.
  • I put the stewed tomatoes through a food processor before I start to get them chopped up into smaller pieces. I don’t like big chunks of tomato in the finished product.

I’ve tried a lot of chilis over the years and this is my favorite. I don’t make it very often because it takes a lot of attention, but when I do, I like to eat leftovers on the bed of rice.

Tyla isn’t a big fan of beans so I’m going to start experimenting with beanless chili. If you have a favorite recipe, please let me know! Apparently the chili gurus in Texas consider beans in chili to be blasphemy so I’m sure there are plenty of good beanless recipes around.

Fireplace Shelves

I’ve had the last 1.5 weeks off from work, and other than a three day trip for Christmas, I spent most of it at home. My project over the break was some new shelves to go above the fireplace. I was no longer happy with the look of the old ones, and with Tyla living here starting in April, I wanted something more versatile.

The project, of course, required about four trips to Home Depot, but all in all, I’m pretty happy with how it turned out. It’s a basic box design with a divider down the middle. The shelves are held up with adjustable pegs and there is molding around the edge of the box to make it look like the shelves are really built in. The end result looks nice, but when I look at it, I see a bunch of mistakes. I debated whether or not I should share them with you, but why not? By this point you know I have nothing to hide. Plus, it’s a good reminder for the next time I do a similar project.

  • I used plywood and then faced it with solid wood trim. I faced everything on the front side of the shelves, even the edges that are covered up with the molding. That last part turned out to be a mistake. I thought it would be simpler, but putting molding on top of the facing on top of the plywood wasn’t the best choice.
  • Trying to make a picture frame effect out of molding is TOUGH.
  • I forgot to glue some of the pieces. They are only held in with nails.
  • I used 1/2” plywood. Putting 1.5” finishing nails into plywood that thin was difficult for me. Too many times the end of the nail would pop out the side of the plywood. I know that’s a lack of skill on my part, but maybe I can use it as an excuse to buy a compressor and nail gun.
  • If I was doing it again, I wouldn’t put the divider down the middle. It meant twice as many peg holes and there are one or two holes that are off by a fraction of an inch. The end result is that the shelves on each side of the divider don’t always line up perfectly.
  • For some reason, the polyurethane on the back wall of the shelves never dried completely. It’s still a tiny bit tacky as I write this. I only put one coat on because I was afraid if I sanded the rest, I’d get dust drying into the back wall.
  • I missed some spots of glue when I was wiping it off. When you stain, those areas don’t take the stain as well and it really shows up.

I could probably continue, but you get the idea. As I sit across the room looking at the shelves, I really can’t see any of these problems so I’m still happy that I built them. I look forward to doing more projects like this and shortening my list of mistakes.

2009 Year In Review

I prepared to write this post by looking back through the photos I’ve taken and reading last year’s Year in Review post. The mere fact that Tyla appears prominently in it should have been a big clue to anyone who has followed my blog that this was something pretty serious. I finished with “What lies ahead? I’ve never been more excited to find out!” Now I know the answer to that, so let’s start from the beginning.

The year started off with a bang as we celebrated the marriage of Tim and Chelsea. The wedding was a blast and the happy couple has just moved into their first house! That wasn’t our only wedding of the year though. In March, Tyla and I took our first big trip together out to beautiful Syracuse, NY for Andy and Lauren’s wedding where I participated in, and won, my first dance off.

Andy, Jay, Mike and I had planned a big ski trip to Big Sky, MT, but that took a very sad turn. I woke up in Spokane on the morning I was supposed to pick everyone up at the airport in Missoula to find out that Mr. A had passed away. It hit everyone hard. Andy and Jay cancelled their plans, but Mike and I went on with the trip. While the trip did not turn out exactly as we hoped Mike and I made the best of it and saw some amazing sights. I hope that the four of us can meet up again soon for another trip.

While I was in Big Sky, I got a tearful call from Tyla letting me know that she had been laid off from her job as a gymnastics teacher. It was a complete shock to her, and given the job market at the time, the future looked rough. It took over a month of hard work and countless emails, phone calls, and interviews to break through the mass of applicants and land a new job. I told her that when it was all done, I knew I would be impressed with the way she handled the situation, and that came true. When unemployment doesn’t even cover your rent, it’s more than a little scary but she showed a ton of determination and got through it.

Early in the year, I bought a new vehicle: a 2009 Kawasaki Concours 14 ABS. After four years of riding, it was time to upgrade to a bigger bike, and what an upgrade this one is! In a normal year, I average 2000 miles of riding. I already have over 5000 miles on this new bike from trips to Bremerton, the Tulip Festival, the Cascade Loop, Mt. Rainier, Mt. Baker, and many others. Tyla was sitting right behind me for many of those miles and it’s a blast being able to share one of my hobbies with her!

Speaking of sharing hobbies, Tyla and I went skiing twice together. She had skied a few times before in Minnesota but still labeled herself as a beginner. I was impressed with her first day on the slopes at Snoqualmie and even more so when we headed up to Crystal. I hope that once we get married we can get her a full set of gear and go even more often.

This was also the year of concerts. We saw the Lion King, Wicked, Little Big Town, Kenny Chesney, Lady Antebellum, Miranda Lambert, Montgomery Gentry, and Sugarland. I think the Lion King was my favorite of that whole list. If you get a chance to see it, don’t pass it up!

In June, Tyla and I flew back to Indiana for a quick three day weekend. In addition to giving her more time to talk to my family, it was great to show her where I grew up. Tyla and David became best friends, Tyla got to play with frogs, we swam in the pool, and we even got out in the canoe on the lake for a while.

My exploration of Washington continued with camping trips to Lake Easton State Park and Moran State Park. I think it will be the last time I visit Lake Easton. While it’s a nice mountain park close to home, it’s also VERY close to the interstate which ruins the feel of camping. But those aren’t the only local trips I took. When Mom and Dad came to visit over Labor Day, Tyla and I took them on a tour of the Olympic Peninsula. We visited Hurricane Ridge, the Hoh Rainforest, and Ocean Shores.

Tyla and I had agreed early on that we wouldn’t even talk about the possibility of marriage until after we had been dating for a year. After that milestone was passed in late July and after I had chatted with both of our parents, I didn’t waste much time getting her into jewelry stores to figure out what she liked. And though she didn’t know it at the time, I kicked off my birthday weekend by purchasing the perfect ring for her. I ended up waiting almost a full month to give it to her. Finally it was time to pop the question, so Tim, Chelsea, Tyla and I headed up to Whistler for a weekend in October. You can reread the proposal story if you want, but the short version is that she made my lifelong dreams come true by saying yes. We quickly switched gears into wedding planning mode. That’s still in progress, but it’s coming along nicely.

If I thought waiting for a month to give her the ring was hard, waiting another 6 months to actually marry her is even harder! I can’t wait to start the rest of my life with her. There is no doubt that God meant for the two of us to be together for the rest of our lives. I’m proud to call her my fiancée, and I know she’ll make a fantastic wife and (God-willing) mother.

As we entered December, cancer’s lightning blow struck closer to me than ever before as Mom was diagnosed with kidney cancer. While the surgery changed our Christmases a bit, so far it appears to have done the trick. She’s on the road to recovery and we’ll find out how successful the surgery was in a few months when they run more tests.

So while there were some bumps along the road, as I look back on the year, I see a long list of memories with Tyla. Last year I finished with “What lies ahead?” When I wrote that, I knew what I hoped would happen and my silent wishes did come true. In just a few more months, there will be another Mrs. Martens in this world.

Previous Year In Review Posts: 2003, 2004, 2005, 2006, 2007, 2008