~cadence/advent-of-code-2021-haskell

10d2567c4ffeae89e5b7c6ba231f6051e9153ae6 — Cadence Ember 2 years ago 1419757 main
days 1 to 3
3 files changed, 117 insertions(+), 0 deletions(-)

A day01.hs
A day02.hs
A day03.hs
A day01.hs => day01.hs +22 -0
@@ 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

A day02.hs => day02.hs +51 -0
@@ 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

A day03.hs => day03.hs +44 -0
@@ 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