import Data.Vect import Data.List import Data.Fin import System.File.ReadWrite -- Get windows of a specific size over the data windows : {n : Nat} -> List a -> List (Vect n a) windows [] = [] windows {n} xs = let (head, _) = splitAt n xs tail = drop 1 xs in case toVect n head of Nothing => [] (Just x) => x :: windows tail findStartOfPacket : List Char -> Maybe Nat findStartOfPacket cs = let segments = windows {n = 4} cs in case findIndex (\x => let ( p ** _ ) = nub x in p == 4) segments of Nothing => Nothing (Just x) => Just $ finToNat x + 4 testCases : List (String, Nat) testCases = [("mjqjpqmgbljsphdztnvjfqwrcgsmlb", 7), ("bvwbjplbgvbhsrlpgdmjqwftvncz",5), ("nppdvjthqldpwncqszvftbrmjlhg",6), ("nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg",10), ("zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw",11)] testCase : (String, Nat) -> IO Bool testCase (string, start) = do putStrLn $ "Test Case: " ++ string putStrLn $ "Expected Start: " ++ show start let result = findStartOfPacket (unpack string) putStrLn $ "Evaluated start: " ++ show result let result = not (result == Just start) if result then putStrLn "Test Failed!!!" else putStrLn "Test Passed" putStrLn "" pure result main : IO () main = do testsPart1 <- traverse testCase testCases if or . map (\x => Delay x) $ testsPart1 then putStrLn "Failed tests" else do file <- readFile "input" case file of Right contents => do putStr "Part 1: " putStrLn $ case findStartOfPacket (unpack contents) of Just start => show start Nothing => "Failed to find start" Left err => printLn err