From bab470906e1c61176c3002698e58980a8d5787e4 Mon Sep 17 00:00:00 2001 From: Felix Albrigtsen Date: Sun, 4 Dec 2022 13:29:07 +0100 Subject: [PATCH] Improve day04 --- day04/main.hs | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/day04/main.hs b/day04/main.hs index 2863145..3b073e0 100644 --- a/day04/main.hs +++ b/day04/main.hs @@ -4,23 +4,25 @@ main = do let list = [] file <- readFile "input.txt" let inputLines = lines file - let pairs = map (splitWhen (==',')) inputLines + let stringpairs = map (splitWhen (==',')) inputLines - -- Each pair is a set of two numbers separated by a dash - let limits = map (map parseRange) pairs + let listpairs = map (map parseRange) stringpairs + let pairs = map (\x -> (head x, last x)) listpairs - let containedWithin = map rangeListIsContained limits - + -- Each line of input has now gone from "1-2,3-4" to ((1,2),(3,4)) + + let containedWithin = map (uncurry rangeIsContained) pairs let containedCount = length $ filter (==True) containedWithin print "Part 1: " print containedCount - let overlap = map rangeListOverlap limits + let overlap = map (uncurry rangeOverlaps) pairs let overlapCount = length $ filter (==True) overlap print "Part 2: " print overlapCount +-- "1-3" -> (1,3) parseRange :: String -> (Int, Int) parseRange pair = do let numbers = splitWhen (=='-') pair @@ -28,7 +30,6 @@ parseRange pair = do let second = read (numbers !! 1) :: Int (first, second) - -- True if the first range is entirely contained in the second range, or vice versa rangeIsContained :: (Int, Int) -> (Int, Int) -> Bool rangeIsContained (lo1, hi1) (lo2, hi2) @@ -36,7 +37,7 @@ rangeIsContained (lo1, hi1) (lo2, hi2) | lo1 >= lo2 && hi1 <= hi2 = True | otherwise = False --- True if any endpoint of a range is within the other range +-- True if any part of the two ranges overlap rangeOverlaps :: (Int, Int) -> (Int, Int) -> Bool rangeOverlaps (lo1, hi1) (lo2, hi2) | rangeIsContained (lo1, lo1) (lo2, hi2) = True @@ -44,20 +45,6 @@ rangeOverlaps (lo1, hi1) (lo2, hi2) | hi2 >= lo1 && hi2 <= hi1 = True | otherwise = False - --- This is mega dirty, should probably be replaced with a smart map. -rangeListIsContained :: [(Int, Int)] -> Bool -rangeListIsContained ranges = do - let first = ranges !! 0 - let second = ranges !! 1 - rangeIsContained first second - -rangeListOverlap :: [(Int, Int)] -> Bool -rangeListOverlap ranges = do - let first = ranges !! 0 - let second = ranges !! 1 - rangeOverlaps first second - -- Modified from Prelude.words splitWhen :: (Char -> Bool) -> String -> [String] splitWhen p s = case dropWhile p s of