|
| 1 | +{-# LANGUAGE DeriveGeneric #-} |
| 2 | +{-# LANGUAGE TypeApplications #-} |
| 3 | +{-# LANGUAGE ScopedTypeVariables #-} |
| 4 | +import Lib |
| 5 | +import Debug.Trace |
| 6 | +import Control.Monad (guard) |
| 7 | +import Data.List (intercalate) |
| 8 | + |
| 9 | +data Input = Input { numbers :: [Int] |
| 10 | + , preSz :: Int } deriving (Show) |
| 11 | + |
| 12 | +dummyNums = [ 35 |
| 13 | + , 20 |
| 14 | + , 15 |
| 15 | + , 25 |
| 16 | + , 47 |
| 17 | + , 40 |
| 18 | + , 62 |
| 19 | + , 55 |
| 20 | + , 65 |
| 21 | + , 95 |
| 22 | + , 102 |
| 23 | + , 117 |
| 24 | + , 150 |
| 25 | + , 182 |
| 26 | + , 127 |
| 27 | + , 219 |
| 28 | + , 299 |
| 29 | + , 277 |
| 30 | + , 309 |
| 31 | + , 576] |
| 32 | + |
| 33 | +dummyInput = Input dummyNums 5 |
| 34 | + |
| 35 | +main = do |
| 36 | + let dummyResult = head $ getWrongNumbers dummyInput |
| 37 | + print $ dummyResult |
| 38 | + |
| 39 | + contents <- readFile "9.input" |
| 40 | + let input = Input (map (read @Int) $ lines contents) 25 |
| 41 | + result = head $ getWrongNumbers input |
| 42 | + print $ result |
| 43 | + |
| 44 | + let dummySum = continuousSum dummyNums $ snd dummyResult |
| 45 | + dummyMinMax = (snd <$> dummySum) >>= minMax |
| 46 | + print dummySum |
| 47 | + print dummyMinMax |
| 48 | + print $ (uncurry (+)) <$> dummyMinMax |
| 49 | + |
| 50 | + let sum' = continuousSum (numbers input) $ snd result |
| 51 | + minMax' = (snd <$> sum') >>= minMax |
| 52 | + print sum' |
| 53 | + print minMax' |
| 54 | + print $ (uncurry (+)) <$> minMax' |
| 55 | + |
| 56 | + |
| 57 | +newtype Index = Idx Int deriving Show |
| 58 | +newtype Window = Win Int deriving Show |
| 59 | + |
| 60 | + |
| 61 | +minMax :: (Ord a) => [a] -> Maybe (a,a) |
| 62 | +minMax [] = Nothing |
| 63 | +minMax (a:[]) = Just (a,a) |
| 64 | +minMax l = Just (minimum l, maximum l) |
| 65 | + |
| 66 | +continuousSum :: (Eq a, Num a) => [a] -> a -> Maybe (a, [a]) |
| 67 | +continuousSum l i = safeHead |
| 68 | + $ filter (\(s,l') -> s == i) |
| 69 | + $ map (\l' -> (sum l', l')) |
| 70 | + $ substrings l |
| 71 | + |
| 72 | +substrings :: [a] -> [[a]] |
| 73 | +substrings [] = [] |
| 74 | +substrings l = filter ((>0) . length) |
| 75 | + $ intercalate [] |
| 76 | + $ map (\i -> |
| 77 | + let sublist = drop i l |
| 78 | + in map (\j -> take j sublist) [0..length sublist]) [0..length l] |
| 79 | + |
| 80 | +getWrongNumbers :: Input -> [(Index, Int)] |
| 81 | +getWrongNumbers (Input [] _) = [] |
| 82 | +getWrongNumbers (Input _ a) | a <= 0 = [] |
| 83 | +getWrongNumbers (Input nums d) = map (\(i,n,b) -> (i,n)) |
| 84 | + $ filter (\(i,n,b) -> not b) |
| 85 | + $ map (\x -> (Idx x, nums!!x, validate nums (Win d) (Idx x))) |
| 86 | + [d..(length nums)-1] |
| 87 | + |
| 88 | + |
| 89 | +validate :: [Int] -> Window -> Index -> Bool |
| 90 | +validate nums win@(Win w) idx@(Idx i) = |
| 91 | + or $ map (\(a,b) -> a+b == nums!!i) $ getPairs $ window nums win idx |
| 92 | + |
| 93 | +window :: [Int] -> Window -> Index -> [Int] |
| 94 | +window _ _ (Idx 0) = [] |
| 95 | +window nums (Win w) (Idx i) = let start = drop (i-w) nums |
| 96 | + in if w >= i |
| 97 | + then init $ take i start |
| 98 | + else take w start |
| 99 | + |
| 100 | +getPairs :: (Eq a) => [a] -> [(a,a)] |
| 101 | +getPairs l = do |
| 102 | + xs <- l |
| 103 | + ys <- l |
| 104 | + guard (xs /= ys) |
| 105 | + return (xs,ys) |
| 106 | + |
| 107 | + |
0 commit comments