Added solution to rubyquiz 60

This commit is contained in:
Abhinav Sarkar 2012-10-25 17:51:06 +05:30
parent 11c234c4ac
commit 8a9bdfeb6c
3 changed files with 54 additions and 0 deletions

View File

@ -1,3 +1,5 @@
{- Copyright 2012 Abhinav Sarkar <abhinav@abhinavsarkar.net> -}
{-# LANGUAGE MultiParamTypeClasses #-}
module AStar where

44
NumericMaze.hs Normal file
View File

@ -0,0 +1,44 @@
{-
A Solution to rubyquiz 60 (http://rubyquiz.com/quiz60.html)
You have a starting point and a target. You have a set of three operations:
double
halve (Odd numbers cannot be halved)
add_two
Problem: Move from the starting point to the target, minimizing the number of operations.
This solution finds the shortest path using A* search with cost of each operation
as one and the heuristic as the absolute of log of the ratio of the target
and start numbers.
Usage: bin/NumericMaze 2 9
Copyright 2012 Abhinav Sarkar <abhinav@abhinavsarkar.net>
-}
module Main (main) where
import AStar
import Control.Monad (when)
import System.Environment (getArgs)
data Op = Double | Halve | AddTwo
execute :: Integral a => a -> Op -> a
execute n Double = 2 * n
execute n Halve = let (q, r) = n `divMod` 2 in if r == 0 then q else n
execute n AddTwo = n + 2
solve start end =
astar start end
(\n -> zip (map (execute n) [Double, Halve, AddTwo]) (repeat 1))
(\a b -> abs $ logBase 2 (fromIntegral b / fromIntegral a))
main = do
(start : end : _) <- fmap (map read) getArgs
when (start <= 0 || end <= 0) (error "Error: The numbers must be positive")
case solve start end of
Nothing -> putStrLn "No solution"
Just (_, solution) -> putStrLn . unwords . map show $ solution

View File

@ -88,4 +88,12 @@ executable SudokuSolver
unordered-containers == 0.2.1.*
main-is : SudokuSolver.hs
ghc-options : -threaded -rtsopts
default-language : Haskell2010
executable NumericMaze
build-depends : base == 4.*,
containers == 0.4.*,
mtl == 2.1.*,
pqueue == 1.2.*
main-is : NumericMaze.hs
default-language : Haskell2010