@@ 0,0 1,22 @@
+getNumbers :: IO [Int]
+getNumbers = do
+ contents <- readFile "01-input.txt"
+ return $ map read $ lines contents
+
+count :: [Int] -> Int
+count list = countRec 0 (head list) (tail list)
+
+countRec :: Int -> Int -> [Int] -> Int
+countRec total current [] = total
+countRec total current (next : rest) = countRec (total + if current < next then 1 else 0) next rest
+
+window :: Int -> ([Int] -> Int) -> [Int] -> [Int]
+window n f list
+ | length list < n = []
+ | otherwise = (f $ take n list) : window n f (tail list)
+
+main :: IO ()
+main = do
+ numbers <- getNumbers
+ putStrLn $ show $ count numbers
+ putStrLn $ show $ count $ window 3 sum numbers
@@ 0,0 1,51 @@
+data Direction = Up | Down | Forward
+ deriving Show
+
+type Position = (Int, Int, Int) -- horizontal position (+), depth (+), aim
+
+type Instruction = (Direction, Int)
+
+makeInstruction :: String -> Instruction
+makeInstruction line = (makeDirection d, read n)
+ where
+ [d, n] = words line
+ makeDirection :: String -> Direction
+ makeDirection "up" = Up
+ makeDirection "down" = Down
+ makeDirection "forward" = Forward
+
+readInstructions :: IO [Instruction]
+readInstructions = do
+ contents <- readFile "02-input.txt"
+ return $ map makeInstruction $ lines $ contents
+
+move1 :: Position -> Instruction -> Position
+move1 (h, d, a) (Up, n) = (h, d-n, a)
+move1 (h, d, a) (Down, n) = (h, d+n, a)
+move1 (h, d, a) (Forward, n) = (h+n, d, a)
+
+-- foldl :: (a -> b -> a) -> a -> [b] -> a
+moveAll1 :: Position -> [Instruction] -> Position
+moveAll1 = foldl move1
+
+move2 :: Position -> Instruction -> Position
+move2 (h, d, a) (Up, n) = (h, d, a-n)
+move2 (h, d, a) (Down, n) = (h, d, a+n)
+move2 (h, d, a) (Forward, n) = (h+n, d+n*a, a)
+
+moveAll2 :: Position -> [Instruction] -> Position
+moveAll2 = foldl move2
+
+main :: IO ()
+main = do
+ instructions <- readInstructions
+ let (h, d, a) = moveAll1 (0, 0, 0) instructions
+ putStrLn $ show $ h * d
+ let (h, d, a) = moveAll2 (0, 0, 0) instructions
+ putStrLn $ show $ h * d
+
+-- bind :: M a -> (a -> M b) -> M b
+-- Maybe 5 -> (number to string) -> Maybe "5"
+-- bind f (Just a) = f a
+-- bind f (Nothing) = Nothing
+-- return :: a -> M a
@@ 0,0 1,44 @@
+import Data.List
+
+makeNumberList :: String -> [Int]
+makeNumberList input = map (read . pure) input
+
+readNumbers :: IO [[Int]]
+readNumbers = do
+ contents <- readFile "03-input.txt"
+ return $ map makeNumberList $ lines $ contents
+
+mostCommon :: [Int] -> Int
+mostCommon ns = if (fromIntegral $ sum ns) >= ((fromIntegral $ length ns) / 2) then 1 else 0
+
+leastCommon :: [Int] -> Int
+leastCommon ns = 1 - mostCommon ns
+
+opposite :: [Int] -> [Int]
+opposite ns = map (1 -) ns
+
+bitsToNumber :: [Int] -> Int
+bitsToNumber [] = 0
+bitsToNumber bits = last bits + 2 * bitsToNumber (init bits)
+
+part1 :: [[Int]] -> Int
+part1 numbers = (bitsToNumber common) * (bitsToNumber $ opposite common)
+ where
+ common = map mostCommon $ transpose numbers
+
+filterDown :: ([Int] -> Int) -> Int -> [[Int]] -> [Int]
+filterDown _ _ [win] = win
+filterDown f index grid = filterDown f (index + 1) $ nextGrid
+ where
+ nextGrid = filter (\ row -> row !! index == common) grid
+ common = (f $ transpose grid !! index)
+
+part2 :: [[Int]] -> Int
+part2 grid = (bitsToNumber $ filterDown mostCommon 0 grid) * (bitsToNumber $ filterDown leastCommon 0 grid)
+
+main :: IO ()
+main = do
+ numbers <- readNumbers
+ putStrLn $ show $ part1 numbers
+ putStrLn $ show $ part2 numbers
+