I am using the coding puzzels of https://adventofcode.com for improving my F# skills.
Problem:
Day 1 Part 2:
Starting with frequency 0, a list of numbers should be added successive generating new frequencies. Searched is the first frequency which occurs twice. If the end of the list has been reached without success; the list should be processed again.
Example Input: [+1, -2, +3, +1]
- Current frequency 0, change of +1; resulting frequency 1.
- Current frequency 1, change of -2; resulting frequency -1. C* urrent frequency -1, change of +3; resulting frequency 2.
- Current frequency 2, change of +1; resulting frequency 3. (At this point, we continue from the start of the list.)
- Current frequency 3, change of +1; resulting frequency 4.
- Current frequency 4, change of -2; resulting frequency 2, which has already been seen.
In this example, the first frequency reached twice is 2.
Solution
let input = [1;-2;3;1]
type State =
| FinalState of int
| IntermediateState of int * int Set
type State with
static member Zero = IntermediateState(0, Set.empty.Add(0))
let foldIntermediateState (freqHistory: int Set, freq : int) : State =
let isFinal = freqHistory |> Set.contains freq
if isFinal then
FinalState (freq)
else
IntermediateState (freq, freqHistory.Add(freq))
let foldState state value =
match state with
| FinalState _ -> state
| IntermediateState (lastFreq, freqHistory) -> foldIntermediateState (freqHistory, lastFreq + value)
let rec processListRec state lst =
let result = lst |> Seq.fold foldState state
match result with
| FinalState result -> printfn "The result is: %i" result
| IntermediateState _ -> lst |> processListRec result
input |> Seq.map int |> processListRec State.Zero
Questions
In fact, I am proud to have found a solution without mutable states that looks (at least for me) functional! :D. So any feeback that helps improving the solution or even alternative function approches for solving that problem are welcome :).