Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Ch4 largestSmallest to improve code readability #390

Merged
merged 1 commit into from
Oct 3, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 10 additions & 19 deletions exercises/chapter4/test/no-peeking/Solutions.purs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@ module Test.NoPeeking.Solutions where

import Prelude
import Control.MonadZero (guard)
import Data.Array (catMaybes, cons, filter, find, head, last, length, nub, null, tail, (..))
import Data.Array (cons, filter, head, length, null, tail, (..), (:))
import Data.Foldable (foldl)
import Data.Int (rem, quot)
import Data.Maybe (Maybe(..), fromMaybe, maybe)
import Data.Maybe (Maybe(..), fromMaybe)
import Data.Path (Path, filename, isDirectory, ls, size)
import Data.String.Common (split)
import Data.String.Pattern (Pattern(..))
import Data.Tuple (Tuple(..))
import Test.Examples

Expand Down Expand Up @@ -111,17 +108,11 @@ whereIs path fileName = head $ do
pure path'

largestSmallest :: Path -> Array Path
largestSmallest path =
let files = onlyFiles path
maybeSizes = map size files
maybeMax = foldl (outlier (>)) Nothing maybeSizes
maybeMin = foldl (outlier (<)) Nothing maybeSizes
in catMaybes $ map (findFileBySize files) $ nub $ [maybeMax, maybeMin]
where
outlier :: (Int -> Int -> Boolean) -> Maybe Int -> Maybe Int -> Maybe Int
outlier criteria Nothing Nothing = Nothing
outlier criteria (Just x) Nothing = Just x
outlier criteria Nothing (Just x) = Just x
outlier criteria (Just x1) (Just x2) = if criteria x1 x2 then Just x1 else Just x2
findFileBySize :: Array Path -> Maybe Int -> Maybe Path
findFileBySize files maybeSize = find (\file -> size file == maybeSize) files
largestSmallest path = foldl loop [] (onlyFiles path) where
loop :: Array Path -> Path -> Array Path
loop [largest, smallest] current | size current < size smallest = [largest, current]
| size current > size largest = [current, smallest]
| otherwise = [largest, smallest]
loop [last] current | size current < size last = [current, last]
| otherwise = [last, current]
loop arr current = current : arr