-
For day 1, there's quite an elegant solution using
zipWith
. Note that you don't actually have to chunk things up, as pointed out, since the windows overlap you only ever have to care about the start and end points (which can be achieved by zipping together the input list and the input list offset by the window length):module Main where inp :: String -> IO [Int] inp path = do c <- readFile path return $ map read (lines c) solve :: Int -> [Int] -> Int solve n xs = length . filter id $ zipWith (<) xs (drop n xs) main :: IO () main = do vals <- inp "day01.input" print $ solve 1 vals print $ solve 3 vals
FWIW, an idiomatic way of chunking a list would be:
import Data.List (tails) chunk :: Int -> [a] -> [[a]] chunk n xs = foldr (zipWith (:)) (repeat []) (take n (tails xs))
Why does this work? Suppose you have two lists
[1, 2, 3, 4]
and[2, 3, 4]
. If you zip them together you get[(1, 2), (2, 3), (3, 4)]
which is chunking by two.tails
produces all tails of a listtails [1, 2, 3, 4] = [[1, 2, 3, 4], [2, 3, 4], [3, 4], [4], []]
. So if wetake n
we will get the right inputs for zipping together to produce a window of length n. We can't usezip
though, because that needs two lists. Sofoldr (zipWith (:)) (repeat [])
is generalisingzip
ton
inputs and producing a list of lists as outputs (rather than a list of tuples)...
decided to actually do it this year. doing it in haskell to brush up after 2 years of almost exclusively doing js/ts and python. posting results in https://github.com/ZooeyMiller/advent-of-code-2021
day1 code is messy as heck sadly...