Skip to content

Instantly share code, notes, and snippets.

@jonathanlking
Created July 5, 2017 23:26
Show Gist options
  • Save jonathanlking/07c4756b56421dfc89071a5a9c9b0c37 to your computer and use it in GitHub Desktop.
Save jonathanlking/07c4756b56421dfc89071a5a9c9b0c37 to your computer and use it in GitHub Desktop.
import Control.Monad (replicateM)
import Control.Applicative ((<$>))
import Data.List (sortBy)
import Data.Maybe (listToMaybe)
import Data.Ord (comparing)
data Token = Plus | Minus | None deriving (Show, Eq)
data Fragment a = Add a | Sub a deriving Show
newtype Solution = Solution { getSolution :: [Token] }
-- Example from the website: 1 + 2 + 34 - 5 + 67 - 8 + 9
example :: Solution
example = Solution [ Plus
, Plus
, None
, Minus
, Plus
, None
, Minus
, Plus
]
-- Pretty print the solution
instance Show Solution where
show = ('1' :) . foldr f "" . flip zip [2..] . getSolution
where
f (None, x) str = show x ++ str
f (Plus, x) str = " + " ++ show x ++ str
f (Minus, x) str = " - " ++ show x ++ str
-- Evaluate a solution to a number
eval = uncurry apply . foldl f (Add 1, 0) . flip zip [2..] . getSolution
where
f (fr, acc) (None, x) = (grow fr x , acc)
f (fr, acc) (Plus, x) = (Add x, apply fr acc)
f (fr, acc) (Minus, x) = (Sub x, apply fr acc)
-- We use 'fragments' to keep track of the sign
grow :: Num a => Fragment a -> a -> Fragment a
grow (Add x) y = Add (x * 10 + y)
grow (Sub x) y = Sub (x * 10 + y)
apply :: Num a => Fragment a -> a -> a
apply (Add x) = (+ x)
apply (Sub x) = subtract x
-- The search space for this puzzle, with 3^8 elements
space n = Solution <$> replicateM n [Plus, Minus, None]
-- The number of + and -'s
cost :: Solution -> Int
cost = length . filter (/= None) . getSolution
-- Search for the best solution (if it exists)
search :: [Solution] -> Maybe Solution
search = listToMaybe . sortBy (comparing cost) . filter ((== 100) . eval)
-- Calculate for the numbers 1..9
main :: IO ()
main = print $ search $ space 8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment