Solve a Hidato puzzle: Difference between revisions
Content added Content deleted
m (added more related tasks.) |
(→{{header|Haskell}}: Made an edit to avoid a Wiki formatting problem (+ hindent)) |
||
Line 1,355: | Line 1,355: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
<lang haskell>{-# LANGUAGE TupleSections #-} |
<lang haskell>{-# LANGUAGE TupleSections #-} |
||
{-# LANGUAGE Rank2Types #-} |
{-# LANGUAGE Rank2Types #-} |
||
import qualified Data.IntMap as I |
import qualified Data.IntMap as I |
||
import Data.IntMap (IntMap) |
import Data.IntMap (IntMap) |
||
Line 1,364: | Line 1,364: | ||
import Data.Time.Clock |
import Data.Time.Clock |
||
data BoardProblem = Board |
data BoardProblem = Board |
||
{ cells :: IntMap (IntMap Int) |
|||
⚫ | |||
, endVal :: Int |
|||
, onePos :: (Int, Int) |
|||
, givens :: [Int] |
|||
} deriving (Show, Eq) |
|||
tupIns x y v m = I.insert x (I.insert y v (I.findWithDefault I.empty x m)) m |
tupIns x y v m = I.insert x (I.insert y v (I.findWithDefault I.empty x m)) m |
||
tupLookup x y m = I.lookup x m >>= I.lookup y |
tupLookup x y m = I.lookup x m >>= I.lookup y |
||
makeBoard = |
|||
makeBoard = (\x -> x{givens = dropWhile (<=1) $ sort $ givens x}) |
|||
(\x -> |
|||
. foldl' f (Board I.empty 0 (0,0) []) . concatMap (zip [0..]) |
|||
x |
|||
⚫ | |||
{ givens = dropWhile (<= 1) $ sort $ givens x |
|||
}) . |
|||
⚫ | |||
foldl' --' |
|||
⚫ | |||
f |
|||
⚫ | |||
(Board I.empty 0 (0, 0) []) . |
|||
⚫ | |||
where |
|||
f bd (x, (y, v)) = |
|||
if v == "." |
|||
then bd |
|||
else Board |
|||
⚫ | |||
⚫ | |||
then read v |
|||
⚫ | |||
(if v == "1" |
|||
then (x, y) |
|||
⚫ | |||
(read v : givens bd) |
|||
hidato brd = listToMaybe $ h 2 (cells brd) (onePos brd) (givens brd) |
hidato brd = listToMaybe $ h 2 (cells brd) (onePos brd) (givens brd) |
||
where |
|||
⚫ | |||
h nval pmap (x, y) gs |
|||
| nval == head gs = if null nvalAdj then [] |
|||
⚫ | |||
⚫ | |||
| nval == head gs = |
|||
if null nvalAdj |
|||
then [] |
|||
⚫ | |||
⚫ | |||
where around = [(x-1,y-1),(x,y-1),(x+1,y-1), (x-1,y),(x+1,y) |
|||
| not $ null nvalAdj = h (nval + 1) pmap (fst $ head nvalAdj) gs |
|||
⚫ | |||
⚫ | |||
where |
|||
⚫ | |||
around = |
|||
hEmptyAdj = concatMap (\((nx,ny),_) -> h (nval+1) |
|||
[ (x - 1, y - 1) |
|||
, (x, y - 1) |
|||
, (x + 1, y - 1) |
|||
, (x - 1, y) |
|||
, (x + 1, y) |
|||
, (x - 1, y + 1) |
|||
, (x, y + 1) |
|||
, (x + 1, y + 1) |
|||
] |
|||
⚫ | |||
⚫ | |||
hEmptyAdj = |
|||
concatMap |
|||
(\((nx, ny), _) -> h (nval + 1) (tupIns nx ny nval pmap) (nx, ny) gs) $ |
|||
filter ((== Just 0) . snd) lkdUp |
|||
printCellMap cellmap = putStrLn $ concat strings |
printCellMap cellmap = putStrLn $ concat strings |
||
where |
|||
where maxPos = xyBy I.findMax maximum |
|||
maxPos = xyBy I.findMax maximum |
|||
minPos = xyBy I.findMin minimum |
|||
xyBy :: (forall a. IntMap a -> (Int,a)) -> ([Int] -> Int) -> (Int, Int) |
|||
xyBy :: (forall a. IntMap a -> (Int, a)) -> ([Int] -> Int) -> (Int, Int) |
|||
xyBy a b = (fst (a cellmap), b $ map (fst . a . snd) $ I.toList cellmap) |
|||
strings = |
|||
map |
|||
⚫ | |||
f |
|||
⚫ | |||
[ (x, y) |
|||
| y <- [snd minPos .. snd maxPos] |
|||
⚫ | |||
⚫ | |||
f (x, y) = |
|||
let z = |
|||
⚫ | |||
then "\n" |
|||
else " " |
|||
in case tupLookup x y cellmap of |
|||
Nothing -> " " ++ z |
|||
Just n -> |
|||
(if n < 10 |
|||
⚫ | |||
else show n) ++ |
|||
z |
|||
main = do |
main = do |
||
let sampleBoard = makeBoard sample |
|||
printCellMap $ cells sampleBoard |
|||
printCellMap $ fromJust $ hidato sampleBoard |
|||
sample = |
sample = |
||
[ " 0 33 35 0 0" |
|||
, " 0 0 24 22 0" |
|||
, " 0 0 0 21 0 0" |
|||
, " 0 26 0 13 40 11" |
|||
, "27 0 0 0 9 0 1" |
|||
, ". . 0 0 18 0 0" |
|||
, ". . . . 0 7 0 0" |
|||
, ". . . . . . 5 0" |
|||
</lang> |
]</lang> |
||
Output: |
|||
{{Out}} |
|||
<pre> 0 33 35 0 0 |
<pre> 0 33 35 0 0 |
||
0 0 24 22 0 |
0 0 24 22 0 |