I've been trying to do the second part of the December 1 Advent of Code Challenge in Haskell. I am fairly new at Haskell but I have a lot of experience in other languages (procedural). I struggled to meet the challenge for hours because the program was crashing and it was producing no output although I could not find a problem in my code. Eventually, it turned out that my program was working properly, but it took a very long time. To be exact, the program took 2 minutes and 40 seconds. According to Advent of Code, each challenge should be able to run within 15 seconds.
So what makes my code so slow?
You notice that the device is constantly repeating the same list of frequency changes. To calibrate the device, you must find the first frequency that it reaches twice.
For example, using the same list of changes above, the device
loop as follows:
Current frequency 0, +1 change; resulting frequency 1. Current frequency 1, change -2; resulting frequency -1. Current frequency -1, change of +3; resulting frequency 2. Current frequency 2, +1 change; resulting frequency 3. (At this point, the device continues from the beginning of the list.) Current frequency 3, +1 change; resulting frequency 4. Current frequency 4, change -2; the resulting frequency 2, which has already been seen.
In this example, the first frequency reached twice is 2. Note that
your device may need to repeat its list of many frequency changes
time before a doubling frequency is found, and that duplicates could
to be found while processing the list.
Here are some other examples:
+1, -1 the first reaches 0 twice. +3, +3, +4, -2, -4 reaches 10 twice. -6, +3, +8, +5, -6 reaches 5 twice. +7, +7, -2, -7, -4 reaches 14 twice.
What is the first frequency at which your device reaches twice?
DayOnePartTwo module where import System.IO Import Data.Maybe inputFileName = "input.txt" input :: String -> [Integer] input content = toNum (cleanNumbers (content of splitNumbers)) or cleanNumbers strs = map removeLeadingPlus strs splitNumbers string = string words toNum numbers = map numbers read removeLeadingPlus str = if str !! 0 == & # 39; + & # 39; then tail str otherwise str accumulate :: [Integer] -> [Integer] accumulate list = list of accumulators 0 or accumulator :: Num a => [a] -> a -> [a] accumulator (x: xs) state = (x + state): accumulator xs (x + state) accumulator  state =  duplicate :: [Integer] -> Maybe Integer duplicate list = dup list  or dup (x: xs) visited = if elem x has visited so just x otherwise dup xs (x: visited) dup  _ = Nothing firstCyclicDuplicate :: [Integer] -> Maybe Integer firstCyclicDuplicate list = duplicate (accumulate cycledList) or cycledList = cycle list main :: IO () main = do contents <- readFile inputFileName case (firstCyclicDuplicate (input contents)) of Just a -> print (show a) Nothing -> print "There is no first duplicate"
This seems to be related to the slow advent of the 2018 code solution, day 1, part 2 in haskell, although my algorithm is different.