My Hobby: Solving XKCD puzzles on my lunch break
July 9, 2007 at 11:16 am | In Geek Humor, Python |I like geek comics. I especially like geek comics that have an embedded NP-Complete problem:

There are 2 solutions:
Solution #1:
<MenuItem Mixed Fruit 215>
<MenuItem Hot Wings 355>
<MenuItem Hot Wings 355>
<MenuItem Sampler Plate 580>
Solution #2:
<MenuItem Mixed Fruit 215>
<MenuItem Mixed Fruit 215>
<MenuItem Mixed Fruit 215>
<MenuItem Mixed Fruit 215>
<MenuItem Mixed Fruit 215>
<MenuItem Mixed Fruit 215>
<MenuItem Mixed Fruit 215>
This isn't "as fast as possible" to be sure, but it should be a general solution.
#!/usr/bin/env python
"""Attempt to solve XKCD from July 9 2007"""
#All monetary values are in pennies to avoid floating point errors
# (Yea, I could use decimal.Decimal but it's SLOW!)
import operator
class MenuItem:
def __init__(self, name, price):
self.name = name
self.price = price
def __add__(self, other):
if hasattr(other,"name") and hasattr(other,"price"):
#This is a MenuItem
return self.price + other.price
else:
return self.price + other
def __repr__(self):
return "
Update July 10: Visitor wac pointed out that my program is pretty inefficient. I agree - I did it really quick on my lunch break yesterday. For order values above $20 it becomes an intractable solution pretty quick. Here is a much more efficient solution that implements value caching (at the cost of requiring more memory than the previous solution):
#!/usr/bin/env python
"""Attempt to solve XKCD from July 9 2007
This is a new version that uses a cache for calculations
"""
#All monetary values are in pennies to avoid floating point errors
# (Yea, I could use decimal.Decimal but it's SLOW!)
import operator
import sys
class MenuItem:
def __init__(self, name, price):
self.name = name
self.price = price
def __add__(self, other):
if hasattr(other,"name") and hasattr(other,"price"):
#This is a MenuItem
return self.price + other.price
else:
return self.price + other
def __repr__(self):
return "
With the improved version I can calculate order values up to $75 in under a minute. That's interesting in and of itself really, because although the second algorithm is much more efficient it would still be practically impossible to calculate an order value of $1000. That's the nature of NP problems for you.
1 Comment »
RSS feed for comments on this post. TrackBack URI
Leave a comment
Powered by WordPress.
Entries and comments feeds.
Valid XHTML and CSS. ^Top^
XML Sitemap


Your solution appears to be O(2**n). There is a relevant paper with an O(n**2) solution at http://citeseer.ist.psu.edu/pearson94polynomialtime.html
I should probably follow up over on the xkcd forums as well if someone else hasn't already.
Comment by wac — July 10, 2007 #