Still too slow

This commit is contained in:
Martin Potier 2020-12-18 14:36:58 +02:00
parent f41863a68b
commit 7c8cb639cb
No known key found for this signature in database
GPG key ID: D4DD957DBA4AD89E

View file

@ -1,4 +1,4 @@
#! /usr/bin/env -S"ANSWER=42" nix-shell #! /usr/bin/env -S"GHCRTS=-N4" nix-shell
#! nix-shell -p ghcid #! nix-shell -p ghcid
#! nix-shell -p "haskellPackages.ghcWithPackages (p: with p; [pretty-simple attoparsec arithmoi containers])" #! nix-shell -p "haskellPackages.ghcWithPackages (p: with p; [pretty-simple attoparsec arithmoi containers])"
#! nix-shell -i "ghcid -c 'ghci' -T main" #! nix-shell -i "ghcid -c 'ghci' -T main"
@ -92,40 +92,27 @@ modList = fmap f
findAllEq :: [[Int]] -> Maybe [Int] findAllEq :: [[Int]] -> Maybe [Int]
findAllEq = find (\xs -> notElem (head xs) xs) findAllEq = find (\xs -> notElem (head xs) xs)
isT :: Integer -> Int -> [(Int,Int)] -> Integer -- Can you feel how much fun I'm not having anymore?
isT :: Int -> Int -> [(Int,Int)] -> Int
isT tpx x xs = head $ catMaybes $ map go allTs isT tpx x xs = head $ catMaybes $ map go allTs
where where
allTs = [158478605388*tpx,158478605388*2*tpx..] allTs = [158478605388*tpx,158478605389*tpx..]
go :: Integer -> Maybe Integer go :: Int -> Maybe Int
go tpx0 = case and (map (go' tpx0) xs) of go tpx0 = case and (map (go' tpx0) xs) of
True -> Just (tpx0 - (fromIntegral x)) True -> Just (tpx0 - x)
_ -> Nothing _ -> Nothing
go' tpx0' (shift,fact) = go' tpx0' (shift,fact) =
-- trace ("tpx:"<>show tpx0'<>",shift:"<>show shift<>",x:"<>show x<>",fact:"<>show fact) $ -- trace ("tpx:"<>show tpx0'<>",shift:"<>show shift<>",x:"<>show x<>",fact:"<>show fact) $
-- traceShowId $ (tpx0' - x + shift) `mod` fact == 0
(tpx0' - (fromIntegral x) + (fromIntegral shift)) `mod` (fromIntegral fact) == 0
-- Solving part 2 solvePart2 :: String -> Either String Int
--
-- Simple example with [(0,3),(1,5)], we're looking for a t, such that
-- t + 0 = 3 * i, t+0 is divisible by 3 and
-- t + 1 = 5 * j, t+1 is divisible by 5
--
-- Surely there must be some relation between i and j? There should be a number
-- such that 3 * i_0 = 5 * j_0 = n_0. n is here the least common multiple (lcm)
-- of 3 and 5, in our case lcm(3,5) = 15 (because both numbers are prime)
--
-- 3 * i_0 = 15 & 5 * j_0 = 15 -> i_0 = 5 & j_0 = 3
--
-- Now what?
solvePart2 :: String -> Either String Integer
solvePart2 str = do solvePart2 str = do
(_,xs) <- parseInput2 str (_,xs) <- parseInput2 str
let startAndIds = catMaybes $ sequence <$> zip [0..] xs let startAndIds = catMaybes $ sequence <$> zip [0..] xs
let sortedStartAndIds = reverse $ sortOn snd $ startAndIds let sortedStartAndIds = traceShowId $ reverse $ sortOn snd $ startAndIds
-- pure $ sortedStartAndIds -- pure $ sortedStartAndIds
let (x,t) = head sortedStartAndIds let (x,t) = head sortedStartAndIds
pure $ isT (fromIntegral t) x sortedStartAndIds pure $ isT t x sortedStartAndIds
main :: IO () main :: IO ()
main = do main = do