Initial day04
This commit is contained in:
parent
6fb292f850
commit
c8bfd92a39
|
@ -7,7 +7,7 @@ These are my attempts on [AoC 2022](https://adventofcode.com/2022/)
|
||||||
| [01](day01) | ⭐ | ⭐ | Python |
|
| [01](day01) | ⭐ | ⭐ | Python |
|
||||||
| [02](day02) | ⭐ | ⭐ | C |
|
| [02](day02) | ⭐ | ⭐ | C |
|
||||||
| [03](day03) | ⭐ | ⭐ | Rust |
|
| [03](day03) | ⭐ | ⭐ | Rust |
|
||||||
| 04 | | | |
|
| [04](day04) | ⭐ | ⭐ | Haskell |
|
||||||
| 05 | | | |
|
| 05 | | | |
|
||||||
| 06 | | | |
|
| 06 | | | |
|
||||||
| 07 | | | |
|
| 07 | | | |
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,6 @@
|
||||||
|
2-4,6-8
|
||||||
|
2-3,4-5
|
||||||
|
5-7,7-9
|
||||||
|
2-8,3-7
|
||||||
|
6-6,4-6
|
||||||
|
2-6,4-8
|
|
@ -0,0 +1,67 @@
|
||||||
|
import Data.Char
|
||||||
|
|
||||||
|
main = do
|
||||||
|
let list = []
|
||||||
|
file <- readFile "input.txt"
|
||||||
|
let inputLines = lines file
|
||||||
|
let pairs = map (splitWhen (==',')) inputLines
|
||||||
|
|
||||||
|
-- Each pair is a set of two numbers separated by a dash
|
||||||
|
let limits = map (map parseRange) pairs
|
||||||
|
|
||||||
|
let containedWithin = map rangeListIsContained limits
|
||||||
|
|
||||||
|
let containedCount = length $ filter (==True) containedWithin
|
||||||
|
print "Part 1: "
|
||||||
|
print containedCount
|
||||||
|
|
||||||
|
let overlap = map rangeListOverlap limits
|
||||||
|
let overlapCount = length $ filter (==True) overlap
|
||||||
|
print "Part 2: "
|
||||||
|
print overlapCount
|
||||||
|
|
||||||
|
|
||||||
|
parseRange :: String -> (Int, Int)
|
||||||
|
parseRange pair = do
|
||||||
|
let numbers = splitWhen (=='-') pair
|
||||||
|
let first = read (numbers !! 0) :: Int
|
||||||
|
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)
|
||||||
|
| lo1 <= lo2 && hi1 >= hi2 = True
|
||||||
|
| lo1 >= lo2 && hi1 <= hi2 = True
|
||||||
|
| otherwise = False
|
||||||
|
|
||||||
|
-- True if any endpoint of a range is within the other range
|
||||||
|
rangeOverlaps :: (Int, Int) -> (Int, Int) -> Bool
|
||||||
|
rangeOverlaps (lo1, hi1) (lo2, hi2)
|
||||||
|
| rangeIsContained (lo1, lo1) (lo2, hi2) = True
|
||||||
|
| lo2 >= lo1 && lo2 <= hi1 = True
|
||||||
|
| 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
|
||||||
|
"" -> []
|
||||||
|
s' -> w : splitWhen p s''
|
||||||
|
where (w, s'') = break p s'
|
||||||
|
|
Loading…
Reference in New Issue