DEV Community

Discussion on: Advent of Code 2020 Solution Megathread - Day 5: Binary Boarding

Collapse
 
bgaster profile image
Benedict Gaster • Edited

Wanting to continue with the Haskell approach of using just lists, which looks back at one of my favourite books from collage Brid and Wadler's Introduction to Functional Programming, I decided to allow my self one function, from the lens package, that is not in Haskell's standard of functions. At some point I guess it might get much of a performance issue to remain with just lists, but for now we continue.

That being said I could not face working with binary date in Haskell, directly at least, and so took a slightly lazy approach with calulating mid points, rather than going for swapping letters for 0 and 1.

-- we need to accumulate, rather than simply fold
foldl' f z []     = z
foldl' f z (x:xs) = let z' = z `f` x 
                    in seq z' $ foldl' f z' xs

-- calculate our half way range
half = (\ranges m ->  if m == 'F' || m == 'L'
                       then fst ranges 
                       else snd ranges) . ranges
    where
        ranges (min, max) = let mp = (min + max) `div` 2
                            in ((min, mp), (mp+1, max))

-- calculate a seat number
seat is = let (rs, cs) = splitAt 7 is
              (r,_) = foldl' half (0,127) rs
              (c,_) = foldl' half (0,7) cs
          in (r*8+c) 

main = do xs <- readFile "day5_input" <&> lines
          let seats = map seat xs
          print (maximum seats)
          print $ fst $ head $ dropWhile snd 
                             $ dropWhile (not . snd)  
                             $ zip [0..] (foldr update emptySeats seats)
    where
        emptySeats = map (const False) [0..1023]
        update s = element s .~ True
Enter fullscreen mode Exit fullscreen mode