Here's a Haskell translation of the C++ version. Runtume is around 10x of the original (probably vector vs list cache trashing and vector sort/unique vs list to set/set to list), code reduction is 3x.
import qualified Data.Set as S
data Forest = F Int Int Int
deriving (Eq, Ord, Show)
meal forests = (S.toList . S.fromList)
[nextForest |
forest <- forests,
meal <- possibleMeals,
let nextForest = forest <+> meal,
valid nextForest]
where
possibleMeals = [
F (-1) (-1) 1,
F (-1) 1 (-1),
F 1 (-1) (-1)]
F x y z <+> F x' y' z' = F (x+x') (y+y') (z+z')
valid (F x y z) = x >= 0 && y >= 0 && z >= 0
findStable forest = iter [forest]
where
iter forests | not (done forests) = iter (meal forests)
| otherwise = filter stable forests
done forests = null forests || any stable forests
stable (F _ 0 0) = True
stable (F 0 _ 0) = True
stable (F 0 0 _) = True
stable _ = False
main = print $ findStable (F 117 155 106)