Day 18 of the 30 Day Writing Challenge!
Hey everyone, it’s me again. I’m sober this time, don’t worry. Well actually I’m drunk on a crazy idea that I had last weekend. I’ve always been really into the NCAA Tournament. I once took up an entire wall in my kitchen with a giant bracket just so I could fill it in after every game. So rolling around in my head last weekend was an idea of combining the NCAA Tournament with my other love, code. I started to play around with a format to see how small (in terms of character length) I could make all my picks. This is what I came up with.
How To Get This Up and Running
git clone email@example.com:2028007.git gist-2028007
node app.js S18541137214112424W185463721532533E191213113102112111011111MW1854113728432828FFWMWW
The argument passed to
app.js is a string containing picks for the 63 games in the NCAA Tournament (after the play-in games). The example above can be looked at as divided into five parts:
Each of the first four parts are a region and the picks for that region. The last part is the picks for the Final Four. The Final Four identifier (
FF) and picks must come at the end of the string. The alpha characters that start each part are the identifier for that region. The region identifier must be a key in a valid region key (by valid I mean it must exist in the data file).
The numbers for the first four regions correspond to the picks being made for that region. Each number refers to a seed that you think will win their game. The picks must be made in a top-down, left-right order when viewing the games on a bracket. This means for the first round, the games must be picked in the order:
1 v 16, 8 v 9, 5 v 12, 4 v 13, 6 v 11, 3 v 14, 7 v 10, 2 v 15. So if you wanted to pick all the higher seeded teams for the first round, your numbers would be
18546372. To complete a region, keep picking winning seeds in this order. To finish our previous example of all the higher seeded teams winning, our numbers would be
185463721432121. This might be easier to visualize if we look at the picks divided into rounds:
18546372 (first round winners)
2143 (second round winners)
12 (Sweet Sixteen winners)
1 (Elite Eight winner). Pair that with the identifier for the region and you have
E185463721432121 which is a valid region.
Once we have put our four regions together we can add the Final Four. For the Final Four ‘region’, you will pick the winners not be their seed but by the identifier of the region that they originally came out of. Make sure you know which regions are playing each other as well. In the example of the 2012 NCAA tournament, the Final Four was
S v W and E v SW. So appropriate Final Four picks would be
WMWW since we are first picking the winners of the two Final Four matchups and the picking the winner of the final game. Pair that with the Final Four identifier to get
If your picks are valid, the output should display in an object contain all the regions, rounds and games.
If there are any errors, those will be displayed instead.
I wanted a codified format to fit all my picks for the NCAA Tournament into as little characters as possible. I believe that even if all region identifiers were two characters and you picked the higher seed in every game, you could fit your picks in 132 characters (enough to fit in a tweet!). Obviously this could be shortened further by adding additional conventions (such as region order, etc.) but I believe this to be a good mix of brevity and flexibility.
This logic is the basis of TweetYourBracket.com (GitHub repo). The idea is that there will be a Twitter watcher which will watch for a specific hashtag and then the bracket will be parsed from the tweet and saved.
Not But Seriously, Why?
Because it was fun. Not let’s show off a few code samples to prove my point.
Note: all the code here is pulled from the TweetYourBracket GitHub repo and slightly modified for example purposes. I also made the gist I referenced above as an easier way to play with the majority of the code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
I had fun writing to the code above. The purpose of is to take a string of picks and validate them with a regex to ensure that they meet the necessary requirements. It gets a little inception-y as you are looping through and created capture groups in the regex that are using back references to capture groups you just created in the iteration before.
Now For the Client Side
The code above is all used on the server-side in my application. I tried to leave as much up to server as I could, because I already had the code there and didn’t want to deal with bugs bringing it to the browser. So what I did on my client-side bracket was to save the status of each pick into the URL hash. That way, the entire state of the bracket is in the URL at all times. It’s not perfect, because I didn’t add a watcher for the hash that will change picks if you change the URL. But what it does, is if you load the page with a bracket in the url hash, it will send that hash to the server and return the HTML if the bracket was valid.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
Rendering It All
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
Check out the Handlebars template on GitHub to see how this was all rendered. Unfortunately I couldn’t figure out how to embed Handlebars code with Octopress.
In The End
I had a small dream of making this a production ready app in time for Selection Sunday (which was last Sunday). Obviously that didn’t work out but TweetYourBracket.com was an extremely fun exercise even if it didn’t get anywhere close to ready for prime time use. Some things I wanted to do with it:
- Make it not look like crap (using Bootstrap)
- Add some cooler interactions during the bracket (drag ‘n’ drop, keyboard shortcuts, auto scrolling)
- Mobile ready with some media queries
- Make the Postgres DB not break when a row doesn’t exist (sounds easy, so no idea why I couldn’t get it to work)
- Better hosting (for now it’s on a free Heroku instance)
- Make it actually do what was advertised and setup the Twitter Streaming API watcher
I encourage anyone who is interested in this to take a look at the GitHub repo. I just opened it up today and would never refuse a cool pull request or issue. Hopefully it will be ready by next year :)