import Data.List splitStrOnce :: String -> String -> (String, String) splitStrOnce separator "" = ("", "") splitStrOnce "" subject = (subject, "") splitStrOnce separator subject = do let sepLen = length separator if (take sepLen subject) == separator then ("", (drop sepLen subject)) else do let res = splitStrOnce separator (tail subject) (((head subject):(fst res)), (snd res)) splitStr :: String -> String -> [String] splitStr separator "" = [] splitStr separator subject = do let res = splitStrOnce separator subject (fst res):(splitStr separator (snd res)) intOfString :: String -> Int intOfString x = read x :: Int minimumsSnd :: Ord b => [(a, b)] -> [(a, b)] minimumsSnd [] = [] minimumsSnd xs = filter ((==) minsnd . snd) xs where minsnd = minimum (map snd xs) sumK n = ((n+1)*n) `div` 2 main :: IO () main = do input <- getContents let crabs = do { map (\x -> read x :: Int) $ map (filter (\x -> x /= '\n')) $ splitStr "," input } let cases = do { map (\x -> (x, sum (map (\y -> sumK (abs (y-x))) crabs))) [(minimum crabs)..(maximum crabs)] } let min = minimumsSnd putStrLn $ show $ snd $ head $ min cases -- ans to part 2 -- Gross, but it works