summary refs log tree commit diff stats
path: root/day7.fsx
diff options
context:
space:
mode:
Diffstat (limited to 'day7.fsx')
-rw-r--r--day7.fsx69
1 files changed, 69 insertions, 0 deletions
diff --git a/day7.fsx b/day7.fsx
new file mode 100644
index 0000000..950d98d
--- /dev/null
+++ b/day7.fsx
@@ -0,0 +1,69 @@
+open System.IO
+open System.Text.RegularExpressions
+
+let (|Regex|_|) pattern input =
+    let m = Regex.Matches(input, pattern)
+    if m.Count > 0 then Some(m)
+    else None
+
+let lines = File.ReadLines "day7.txt"
+
+let getSegments inputStr = 
+    match inputStr with
+    | Regex "(?:[a-z]+)|(?:\[[a-z]+\])" matches -> matches |> Seq.map (fun x -> x.Value) |> Seq.toList
+    | _ -> []
+// part 1
+let containsABBA (segment: string): bool =
+    let isABBA (chars: char[]): bool = 
+        let a1, b1, b2, a2 = chars[0], chars[1], chars[2], chars[3]
+        a1 = a2 && b1 = b2 && a1 <> b1
+    segment 
+    |> Seq.windowed 4
+    |> Seq.map isABBA
+    |> Seq.fold (||) false
+
+let ABBASegment (segment: string): bool =
+    not ((containsABBA segment) && (segment[0] = '['))
+
+let TLSLine (line: string):bool=
+    let allValid = line
+                   |> getSegments
+                   |> Seq.map ABBASegment
+                   |> Seq.fold (&&) true
+    allValid && containsABBA line
+
+lines |> Seq.filter TLSLine |> Seq.length |> printfn "%d"
+
+// part 2
+let matchABA (pair: char[] * char[]): bool =
+    let aba, bab = pair
+    let a, b, c = aba[0], aba[1], aba[2]
+    let d, e, f = bab[0], bab[1], bab[2]
+    a = c && d = f && a = e && b = d
+
+let ABAPairs (segments: list<string>) : list<char[] * char[]> =
+    let windows (group: bool * list<string>) =
+        let _, segments = group
+        seq {
+            for segment in segments do
+                yield! seq {
+                    for window in Seq.windowed 3 (String.filter (fun x -> x <> '[' && x <> ']') segment) do 
+                        yield window
+                }
+        }
+    let cartesian xs ys =
+        xs |> List.collect (fun x -> ys |> List.map (fun y -> x, y))
+    
+    let separated = segments |> List.groupBy (fun x -> x[0] = '[') |> List.map windows |> List.map Seq.toList
+    cartesian separated[0] separated[1]
+
+let validABA =
+    getSegments
+    >> ABAPairs
+    >> Seq.map matchABA
+    >> Seq.fold (||) false
+
+let ABACount : seq<string> -> int=
+    Seq.filter validABA >> Seq.length
+
+ABACount lines |> printfn "%d"
\ No newline at end of file