commit 15b9d4b793ca200db92fa49cd0aabb33d5a498e6 Author: toast Date: Thu Dec 4 02:43:18 2025 +0000 initialise repo; add days 1-3 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b4a0e67 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +**/input.txt +**/input2.txt diff --git a/01/solution.hs b/01/solution.hs new file mode 100644 index 0000000..34f9fb6 --- /dev/null +++ b/01/solution.hs @@ -0,0 +1,56 @@ +import Debug.Trace +import Data.Maybe + +traceOut :: Show a => a -> a +traceOut x = traceShow x x + +data Shift = Shift Int + +instance Show Shift where + show (Shift x) = show x + +addFirst :: [[a]] -> a -> [[a]] +addFirst [] x = [[x]] +addFirst (y:ys) x = ([x] ++ y) : ys + +split :: [Char] -> [Char] -> [[Char]] +split _ [] = [] +split delims (x:xs) + | elem x delims = [[]] ++ split delims xs + | otherwise = addFirst (split delims xs) x + +iterateFrom :: [a -> a] -> a -> [a] +iterateFrom [] x = [x] +iterateFrom (f:fs) x = x : (iterateFrom fs (f x)) + +iterateWith :: (a -> b -> b) -> [a] -> b -> [b] +iterateWith f [] b = [b] +iterateWith f (a:as) b = b : iterateWith f as (f a b) + +parseShift :: String -> Maybe Shift +parseShift ('L':xs) = Just $ Shift (-(read xs)) +parseShift ('R':xs) = Just $ Shift (read xs) +parseShift _ = Nothing + +parseFile :: String -> Maybe [Shift] +parseFile = sequence . map parseShift . split ['\n'] + +toFunc :: Shift -> (Int -> Int) +toFunc (Shift x) = (+x) + +solve1 :: [Shift] -> Int +solve1 shifts = length $ filter (==0) $ map (`mod` 100) $ iterateFrom (map toFunc shifts) 50 + +expandShift :: Shift -> [Shift] +expandShift (Shift x) = take (abs x) $ repeat (Shift (signum x)) + +solve2 :: [Shift] -> Int +solve2 = solve1 . foldl (++) [] . map expandShift + +main = do + fileinp <- readFile "input.txt" + let shifts = fromJust $ parseFile fileinp + let solved1 = solve1 shifts + let solved2 = solve2 shifts + print solved1 + print solved2 diff --git a/02/solution.hs b/02/solution.hs new file mode 100644 index 0000000..78d3eb2 --- /dev/null +++ b/02/solution.hs @@ -0,0 +1,55 @@ +import Debug.Trace + +traceOut :: Show a => a -> a +traceOut x = traceShow x x + +addFirst :: [[a]] -> a -> [[a]] +addFirst [] x = [[x]] +addFirst (y:ys) x = ([x] ++ y) : ys + +split :: Eq a => [a] -> [a] -> [[a]] +split _ [] = [] +split delims (x:xs) + | elem x delims = [[]] ++ split delims xs + | otherwise = addFirst (split delims xs) x + + +parseFile :: String -> [(Int, Int)] +parseFile = map ((\(x,y) -> (read x, read (drop 1 y))) . break (=='-')) . split [','] + +factors :: Int -> [Int] +factors 1 = [] +factors 2 = [1] +factors 3 = [1] +factors 4 = [1,2] +factors 5 = [1] +factors 6 = [1,2,3] +factors 7 = [1] +factors 8 = [1,2,4] +factors 9 = [1,3] +factors 10 = [1,2,5] +factors 11 = [1] +factors 12 = [1,2,3,4,6] + +isRepeatN :: Int -> Int -> Bool +isRepeatN n x = (pow10 x > 0) && ((x `mod` divisor) == 0) && (x `div` divisor < 10^n) + where pow10 = (`div` n) . digits + divisor = sum $ take (pow10 x) $ iterate (* 10^n) 1 + +digits = (+1) . floor . logBase 10 . fromInteger . toInteger +isRepeat2 x = ((digits x) `mod` 2 == 0) && (isRepeatN ((digits x) `div` 2) x) +isRepeat x = foldl (||) False $ map (`isRepeatN` x) (factors $ digits x) + +solve1 :: [(Int, Int)] -> Int +solve1 = sum . map (sum) . map (filter isRepeat2) . map (\(a, b) -> [a..b]) + +solve2 :: [(Int, Int)] -> Int +solve2 = sum . map (sum) . map (filter isRepeat) . map (\(a, b) -> [a..b]) + +main = do + fileinp <- readFile "input.txt" + let input = parseFile fileinp + let solved1 = solve1 input + let solved2 = solve2 input + print solved1 + print solved2 diff --git a/03/solution.hs b/03/solution.hs new file mode 100644 index 0000000..e50750e --- /dev/null +++ b/03/solution.hs @@ -0,0 +1,57 @@ +import Debug.Trace +import Data.Maybe +import Control.Applicative + +instance (Applicative m, Num a) => Num (m a) where + (+) = liftA2 (+) + (-) = liftA2 (-) + (*) = liftA2 (*) + abs = fmap abs + signum = fmap signum + negate = fmap negate + fromInteger = pure . fromInteger + +traceOut :: Show a => a -> a +traceOut x = traceShow x x + +addFirst :: [[a]] -> a -> [[a]] +addFirst [] x = [[x]] +addFirst (y:ys) x = ([x] ++ y) : ys + +split :: Eq a => [a] -> [a] -> [[a]] +split _ [] = [] +split delims (x:xs) + | elem x delims = [[]] ++ split delims xs + | otherwise = addFirst (split delims xs) x + +parseFile :: String -> [[Int]] +parseFile = map (map (read . (:[]))) . split ['\n'] + +dropLast :: Int -> [a] -> [a] +dropLast n = reverse . drop n . reverse + +takeAfter :: (a -> Bool) -> [a] -> [a] +takeAfter f [] = [] +takeAfter f (x:xs) = if f x then xs else takeAfter f xs + +listMax :: Ord a => [a] -> Maybe a +listMax [] = Nothing +listMax (x:xs) = Just $ foldl max x xs + +bestJoltage :: Int -> [Int] -> Maybe Int +bestJoltage n xs + | n <= 0 = 0 + | null (drop (n-1) xs) = 0 + | otherwise = case maximum of Nothing -> Nothing; Just maximum' -> 10^(n-1) * maximum + (bestJoltage (n-1) (takeAfter (>= maximum') xs)) + where maximum = listMax $ dropLast (n-1) xs + +solve :: Int -> [[Int]] -> Maybe Int +solve n = fmap sum . sequence . map (bestJoltage n) + +main = do + fileinp <- readFile "input.txt" + let input = parseFile fileinp + let solved1 = fromJust $ solve 2 input + let solved2 = fromJust $ solve 12 input + print solved1 + print solved2