public
Last active

Gardner's canceling digits puzzle, also related to Project Euler problem #33

  • Download Gist
gardner.hs
Haskell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
-- turn an Integer into a list of digits
digits = map (read . (:[])) . show
 
-- is a given fraction special?
special :: Integer -> Integer -> Bool
special n d
| (n_rf / d_rf) == ((realToFrac (head ns)) / (realToFrac (head ds))) = True
| otherwise = False
where n_rf = realToFrac n
d_rf = realToFrac d
(ns, ds) = (cancel_digits (digits n) (digits d))
 
cancel_digits :: (Integral t) => [t] -> [t] -> ([t], [t])
cancel_digits num_digs den_digs
| (null ns) && (null ds) = ([1],[1])
| (null ns) && not (null ds) = ([1],ds)
| not (null ns) && (null ds) = (ns, [1])
| otherwise = (ns,ds)
where ns = [n | n <- num_digs, not (n `elem` den_digs)]
ds = [d | d <- den_digs, not (d `elem` num_digs)]
 
 
allCombosUnder100 :: [(Integer, Integer)]
allCombosUnder100 = [(x,y) | x <- [1..100], y <- [1..100]]
 
specialCombos :: [(Integer, Integer)]
specialCombos = filter (\t -> (special (fromIntegral (fst t))
(fromIntegral (snd t))))
allCombosUnder100
 
specialNonTrivial :: [(Integer, Integer)]
specialNonTrivial =
filter (\t -> (nonTrivial (orig t) (cancelled t))) specialCombos
where orig t = ((digits (fst t)), (digits (snd t)))
cancelled t = cancel_digits (digits (fst t)) (digits (snd t))
 
nonTrivial orig cancelled =
not_same && did_cancel && no_zeros
where not_same = (fst cancelled) /= (snd cancelled)
did_cancel = (length (fst orig)) > (length (fst cancelled))
no_zeros = not $ foldl (&&) True (map (elem 0) [(fst orig),(snd orig)])

haha I cant figure out anything to code in haskell to play around with it. good call :p

Lol yeah, I've been lookin around for stuff to do in Haskell too

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.