Compare commits
4 Commits
b8b6249707
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
56f6951415
|
|||
|
e3e8334758
|
|||
|
6fb7a8489b
|
|||
|
b89219e387
|
30
Lib.hs
Normal file
30
Lib.hs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
module Lib (readFile', tRead, buildGrid, split, count) where
|
||||||
|
|
||||||
|
import Data.ByteString qualified as B (readFile)
|
||||||
|
import Data.Map qualified as M
|
||||||
|
import Data.Text (Text)
|
||||||
|
import Data.Text.Encoding qualified as T (decodeUtf8)
|
||||||
|
import Data.Text.Read qualified as TR
|
||||||
|
|
||||||
|
-- IO --
|
||||||
|
readFile' :: FilePath -> IO Text
|
||||||
|
readFile' f = T.decodeUtf8 <$> B.readFile f
|
||||||
|
|
||||||
|
-- Data.Text --
|
||||||
|
tRead :: Text -> Int
|
||||||
|
tRead = (\(Right (n, _)) -> n) . TR.signed TR.decimal
|
||||||
|
|
||||||
|
-- Data.Map --
|
||||||
|
buildGrid :: [[a]] -> M.Map (Int, Int) a
|
||||||
|
buildGrid xs = M.fromList [((x, y), a) | (row, x) <- zip xs [0 ..], (a, y) <- zip row [0 ..]]
|
||||||
|
|
||||||
|
-- Utility --
|
||||||
|
split :: (Eq a) => a -> [a] -> [[a]]
|
||||||
|
split delimiter list =
|
||||||
|
let (before, after) = break (== delimiter) list
|
||||||
|
in before : case after of
|
||||||
|
[] -> []
|
||||||
|
(_ : xs) -> split delimiter xs
|
||||||
|
|
||||||
|
count :: (Eq a) => [a] -> a -> Int
|
||||||
|
count xs x = length $ filter (x ==) xs
|
||||||
8
day09.hs
8
day09.hs
@@ -1,17 +1,13 @@
|
|||||||
import Data.Either (rights)
|
|
||||||
import Data.Map qualified as M
|
|
||||||
import Data.Text qualified as T
|
import Data.Text qualified as T
|
||||||
import Data.Text.Read qualified as TR
|
|
||||||
import Lib (readFile', tRead)
|
import Lib (readFile', tRead)
|
||||||
import Text.Parsec
|
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
input <- map (map tRead . T.words) . T.lines <$> readFile' "day09.in"
|
input <- map (map tRead . T.words) . T.lines <$> readFile' "day09.in"
|
||||||
|
|
||||||
putStr "Q1: "
|
putStr "Q1: "
|
||||||
print . sum $ map (sum . map last . extrap) input
|
print . sum $ map (sum . map last . extrap) input
|
||||||
|
|
||||||
putStr "Q2: "
|
putStr "Q2: "
|
||||||
print . sum $ map (sum . map last . extrap . reverse) input
|
print . sum $ map (sum . map last . extrap . reverse) input
|
||||||
|
|
||||||
|
|||||||
48
day10.hs
Normal file
48
day10.hs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import Data.List (find)
|
||||||
|
import Data.Map qualified as M
|
||||||
|
import Data.Maybe (catMaybes, isNothing, mapMaybe)
|
||||||
|
import Data.Set qualified as S
|
||||||
|
import Lib (buildGrid, readFile')
|
||||||
|
|
||||||
|
data Direction = East | West | North | South deriving (Show, Eq)
|
||||||
|
|
||||||
|
type Coord = (Int, Int)
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = do
|
||||||
|
grid <- buildGrid . lines <$> readFile "day10.in"
|
||||||
|
let [((sx, sy), _)] = M.toList $ M.filter (== 'S') grid
|
||||||
|
let path =
|
||||||
|
head $
|
||||||
|
mapMaybe
|
||||||
|
(uncurry $ travel grid [])
|
||||||
|
[ ((sx - 1, sy), North),
|
||||||
|
((sx, sy + 1), East)
|
||||||
|
]
|
||||||
|
|
||||||
|
putStr "Q1: "
|
||||||
|
print $ div (length path) 2
|
||||||
|
|
||||||
|
putStr "Q2: "
|
||||||
|
print $ pick (shoelace path) (length path)
|
||||||
|
|
||||||
|
travel :: M.Map Coord Char -> [Coord] -> Coord -> Direction -> Maybe [Coord]
|
||||||
|
travel grid a c@(x, y) d
|
||||||
|
| isNothing (M.lookup c grid) || cur == '.' = Nothing
|
||||||
|
| cur == 'S' = Just $ c : a
|
||||||
|
| (cur, d) `elem` [('L', West), ('|', North), ('J', East)] = travel grid (c : a) (x - 1, y) North
|
||||||
|
| (cur, d) `elem` [('F', West), ('|', South), ('7', East)] = travel grid (c : a) (x + 1, y) South
|
||||||
|
| (cur, d) `elem` [('L', South), ('-', East), ('F', North)] = travel grid (c : a) (x, y + 1) East
|
||||||
|
| (cur, d) `elem` [('J', South), ('-', West), ('7', North)] = travel grid (c : a) (x, y - 1) West
|
||||||
|
where
|
||||||
|
cur = grid M.! c
|
||||||
|
|
||||||
|
-- https://en.wikipedia.org/wiki/Shoelace_formula
|
||||||
|
-- this just uses trapezoids/triangles from consecutive points
|
||||||
|
shoelace :: [Coord] -> Int
|
||||||
|
shoelace xs = flip div 2 . abs . sum $ zipWith (\(x1, y1) (x2, y2) -> (x1 * y2) - (x2 * y1)) xs (tail $ cycle xs)
|
||||||
|
|
||||||
|
-- https://en.wikipedia.org/wiki/Pick%27s_theorem
|
||||||
|
-- area -> path length -> integers inside
|
||||||
|
pick :: Int -> Int -> Int
|
||||||
|
pick a b = (a + 1) - div b 2
|
||||||
31
day11.hs
Normal file
31
day11.hs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import Data.List (tails)
|
||||||
|
|
||||||
|
type Coord = (Int, Int)
|
||||||
|
|
||||||
|
-- slow but dont care
|
||||||
|
main :: IO ()
|
||||||
|
main = do
|
||||||
|
input <- lines <$> readFile "day11.in"
|
||||||
|
|
||||||
|
let galaxies = [(x, y) | (row, x) <- zip input [0 ..], ('#', y) <- zip row [0 ..]]
|
||||||
|
|
||||||
|
let emptyRows = [r | r <- [0 .. length input], r `notElem` map fst galaxies]
|
||||||
|
let emptyCols = [c | c <- [0 .. length $ head input], c `notElem` map snd galaxies]
|
||||||
|
|
||||||
|
let galaxyPairs = [(x, y) | (x : xs) <- tails galaxies, y <- xs]
|
||||||
|
|
||||||
|
putStr "Q1: "
|
||||||
|
print . sum $ map (uncurry $ distance emptyRows emptyCols 2) galaxyPairs
|
||||||
|
|
||||||
|
putStr "Q2: "
|
||||||
|
print . sum $ map (uncurry $ distance emptyRows emptyCols 1000000) galaxyPairs
|
||||||
|
|
||||||
|
distance :: [Int] -> [Int] -> Int -> Coord -> Coord -> Int
|
||||||
|
distance rs cs f (x1, y1) (x2, y2) =
|
||||||
|
abs (x1 - x2)
|
||||||
|
+ abs (y1 - y2)
|
||||||
|
+ (f - 1) * length (filter (between x1 x2) rs)
|
||||||
|
+ (f - 1) * length (filter (between y1 y2) cs)
|
||||||
|
|
||||||
|
between :: Int -> Int -> Int -> Bool
|
||||||
|
between a b x = x > min a b && x < max a b
|
||||||
Reference in New Issue
Block a user