Created
July 12, 2015 04:21
-
-
Save bradclawsie/d6a94f3a31e8ee8cc3a3 to your computer and use it in GitHub Desktop.
number puzzle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main where | |
import Prelude as P | |
import Control.Monad as M | |
import Data.Text as T | |
import Data.Text.Read as TR | |
import Data.Either as E | |
import Data.List as L | |
import Data.Maybe as MB | |
-- http://programmingpraxis.com/2015/06/26/find-the-missing-number/ | |
divTest :: T.Text -> Maybe [Int] | |
divTest s = divTestRecurse s 2 | |
-- divTestRecurse will split a string into n chunks, and convert those n chunks into | |
-- numbers to see if sequenceGap is satisfied by the chunks. If so, the gap data | |
-- is returned. Otherwise, this is called recursively with n+1 as the divisor...until | |
-- n is the same length as s (in which case it is split into single digits). | |
divTestRecurse :: T.Text -> Int -> Maybe [Int] | |
divTestRecurse s n = let l = T.length s in | |
if n > l | |
then Nothing | |
else if (l `mod` n) /= 0 | |
then divTestRecurse s (n + 1) | |
else | |
let mds = mapM (TR.decimal) $ T.chunksOf (l `div` n) $ s | |
in | |
case mds of | |
Left _ -> Nothing | |
_ -> let gotGap = sequenceGap $ P.map fst $ P.head $ E.rights [mds] in | |
case gotGap of | |
Nothing -> divTestRecurse s (n + 1) | |
_ -> gotGap | |
-- sequenceGap will determine if a list of Ints is a sequence of numbers with potential | |
-- gaps in the sequence no greater than one (where a missing value would fit). | |
-- If this criteria is not satisfied, Nothing is returned. Otherwise, Just [missing values] | |
-- is returned. | |
sequenceGap :: [Int] -> Maybe [Int] | |
sequenceGap i = let pairs = L.zip i (L.tail i) | |
pairGaps = L.map pairGap pairs in | |
if not (L.all (MB.isJust) pairGaps) | |
then Nothing | |
else Just (L.filter (/= 0) $ MB.catMaybes pairGaps) | |
where | |
pairGap pair = let a = fst pair | |
b = snd pair | |
difference = b - a | |
isSequenceOrSingleGap = difference == 1 || difference == 2 | |
in | |
if not isSequenceOrSingleGap | |
then Nothing | |
else if difference == 1 | |
then Just 0 | |
else Just (a + 1) | |
main = do | |
let s = T.pack "596597598600601602" | |
print $ show $ divTest s | |
return () |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment