I love superhero movies. Specifically, Marvel superhero movies. Specifically specifically, Marvel Cinematic Universe movies — Iron Man, Captain America, Thor, and so on. Never thought I'd be that guy, but somehow I've seen every single MCU movie — 22 in total.
Why? Because they're super good! There's a reason they have an average Rotten Tomatoes score of 84%.
But which ones are the best? This is a constant debate among my friends. And with the latest phase of the MCU coming to a close with Avengers: Endgame, it's been a good time to take stock and make best-of lists.
A few problems, though:
All of these problems mean tools that let you drag around movie names probably aren't helping you come up with a definitive list. They're just confusing you!
My take: It's easier to pick your favorite movie when you just have two options in front of you. If you run through enough pairings, eventually you'll get an ordered list.
That's the idea behind mcu.ninja, a ranking tool I put out last week. 🎉
In this post, I'm going to explain the logic behind the ordering algorithm powering mcu.ninja and the command-line utility I built to demonstrate it. Next week, I'll discuss the UI and why I thought Tinder-style swiping was the right decision.
If you need to order a list of 22 items, it's simplest to go one by one and compare every movie to every other.
Let's say I start with Captain Marvel. I'd compare it to Iron Man, the first film in the MCU.
OK, that's easy — I like Iron Man better. But that's only the beginning. I still have to compare Captain Marvel to every other MCU movie — 21 comparisons in all.
Once we're done with Captain Marvel, we move on to the next film: Avengers: Endgame. Since we already compared it to Captain Marvel, we don't have to match them again. But we still have 20 other movies to compare.
So far, we've made 41 comparisons. If we add just two more movies, we're up to 78:
Taking this to its mathematical conclusion, we'd have to make comparisons equal to 21 + 20 + 19 + 18... + 1, or (n^2 + n) / 2. That's 231 match-ups — only marginally better than watching 14,000,605 alternative futures.
Let's line up all the movies by date released — the order doesn't matter — and randomly pick Captain Marvel to start:
Captain Marvel is the pivot. Our job is to re-order the list so every movie that's worse goes on the left, and every movie that's better goes on the right.
It doesn't matter what order we put them in — only that they're better or worse than the pivot.
Ater sorting (your choices might be different!), we now know Captain Marvel is No. 16 on list. To do this, we had to make 21 comparisons — same as we did before. But the next step is different. We consider the better-than and worse-than movies as their own sets, and run the method again.
So in the "worse-than-Captain Marvel" set, we randomly choose Thor: The Dark World as our pivot. In the "better-than-Captain Marvel" set, we choose Captain America: Civil War. For each of these sets, we again sort the movies by whether or not they're worse than the pivot.
Now we have three movies properly ordered — with only 40 comparisons, instead of 60 with our previous method. That's a huge improvement.
That kind of efficiency isn't guaranteed. Quicksort works best when the pivots land in the middle of a given set — in this case, the movie that's chosen is average, not terrible or spectacular. But unless you're really unlucky, Quicksort will work far better than brute force.
Before I built out the full mcu.ninja app, I wanted to make sure this method actually made sense. In practice, would it work to present people with pairs of movies and having Quicksort figure out which to show next?
So to test, I built mcu-rankings-cli, a command line interface script written in Node.
Pretty simple — it gives you two options, and you pick one. On the back end, I wrote a
MovieList class that handled making match-ups and accepting votes from the user. On the front end, the inquirer makes the CLI magic happen.
The method seemed to work pretty well. Sometimes the pivot movies weren't great — it's annoying to get a stinker like The Incredible Hulk and have to vote against it 20-something times. Later on, I decided to use Rotten Tomatoes data to choose the most "average" movie in a set as the pivot.
But otherwise, success. Next week, I'll talk about how the final swipe-y UI came to be!