Play Wythoff's Nim perfectly
Haskell, 167 165 characters
c p=o p:c(o p:p)
o p=[(a,b)|a&lt;-[0..],b&lt;-[0..a],(a,b)?p==[]]!!0
(a,b)?p=[y|y@(c,d)&lt;-p,c==a||c==b||d==b||a+d==b+c]
f x@(a,b)|a&lt;b=f(b,a)|x?c[]!!0==x=(0,-1)|1&gt;0=x?c[]!!0

The algorithm is inefficient, but it still runs within a second (though not in the interactive console) for inputs &lt; 100.
Explanation:
c p=o p:c(o p:p)

The list of cold positions given a set of previous cold positions is one cold position followed by the list of cold positions given this position and the previous ones (Inefficiency: this position is generated twice)
o p=[(a,b)|a&lt;-[0..],b&lt;-[0..a],(a,b)?p==[]]!!0

One cold position is the first pair such that there are no cold positions reachable from that pair (Inefficiency: we should search from the previous pair instead)
(a,b)?p=[y|y@(c,d)&lt;-p,c==a||c==b||d==b||a+d==b+c]

Positions reachable from a pair are those such that their first elements match, their second elements match, their difference matches, or the smaller heap before removal is the larger heap after removal.
f x@(a,b)|a&lt;b=f(b,a)
         |x?c[]!!0==x=(0,-1)
         |1&gt;0=x?c[]!!0

(main method) If the heaps are in the wrong order, swap them. Else, if the first cold position reachable from a position is the position itself, indicate failure (ideally, one would return Maybe (Int,Int) instead). Else return that cold position (Inefficiency: said pair is looked up twice. Worse, the list of cold positions is generated twice)