1
+ // Learn more about F# at http://fsharp.org
2
+
3
+ open System
4
+ open System.IO
5
+ open System.Text .RegularExpressions ;
6
+
7
+ let readLines fname = File.ReadLines( fname) |> List.ofSeq
8
+
9
+ // ==== Day 1 ==== //
10
+ let rec getFirstCumulativeRepeat ' vs acc idx seenFreq =
11
+ match Set.contains acc seenFreq with
12
+ | true -> acc
13
+ | false ->
14
+ let newAcc = acc + ( Array.item idx vs)
15
+ let newIdx = ( idx + 1 ) % Array.length vs
16
+ getFirstCumulativeRepeat' vs newAcc newIdx ( Set.add acc seenFreq)
17
+
18
+ let getFirstCumulativeRepeat vs = getFirstCumulativeRepeat' vs 0 0 Set.empty
19
+ let day1 () =
20
+ printfn " Day 1:"
21
+ let vs = readLines " day1.input" |> List.map Int32.Parse
22
+ printfn " %d " ( List.sum vs)
23
+ printfn " %d " ( getFirstCumulativeRepeat ( Array.ofList vs))
24
+
25
+ // ==== Day 2 ==== //
26
+ let numOfCharInString c s = Seq.length ( Seq.filter ( fun c' -> c' = c) s)
27
+ let hasRepeat n s = Seq.exists ( fun c -> numOfCharInString c s = n) ( Set.ofSeq s)
28
+ let numWithN n ss = Seq.filter ( hasRepeat n) ss |> Seq.length
29
+
30
+ let hasOneLetterDifferent ( a , b ) =
31
+ Seq.zip a b
32
+ |> Seq.filter ( fun ( x , y ) -> x <> y)
33
+ |> Seq.length = 1
34
+
35
+ let commonLetters ( a , b ) =
36
+ Seq.zip a b
37
+ |> Seq.filter ( fun ( x , y ) -> x = y)
38
+ |> Seq.map ( fun ( x , _ ) -> x)
39
+
40
+ let day2 () =
41
+ printfn " Day 2:"
42
+ let vs = readLines " day2.input"
43
+ let numWith2 = numWithN 2 vs
44
+ let numWith3 = numWithN 3 vs
45
+ printfn " %d * %d = %d " numWith2 numWith3 ( numWith2 * numWith3)
46
+ let product = seq { for a in vs do for b in vs do yield a, b }
47
+ let result =
48
+ Seq.find hasOneLetterDifferent product
49
+ |> commonLetters
50
+ |> String.Concat
51
+ printfn " %s " result
52
+
53
+ // ==== Day 3 ==== //
54
+
55
+ type Region = { id: string ; left: int ; top: int ; width: int ; height: int }
56
+ let parseLine line =
57
+ let m = Regex.Match( line, @" ^#([^ ]+) @ (\d+),(\d+): (\d+)x(\d+)$" )
58
+ let g = m.Groups
59
+ {
60
+ id = g.[ 1 ]. Value
61
+ left = Int32.Parse g.[ 2 ]. Value
62
+ top = Int32.Parse g.[ 3 ]. Value
63
+ width = Int32.Parse g.[ 4 ]. Value
64
+ height = Int32.Parse g.[ 5 ]. Value
65
+ }
66
+
67
+ let iterRegion size { left= l ; top= t ; width= w ; height= h } = seq {
68
+ for i in { l .. l + w - 1 } do
69
+ for j in { t .. t + h - 1 } do
70
+ yield j * size + i
71
+ }
72
+
73
+ let createFabric size regions =
74
+ let fabric : int [] = Array.zeroCreate ( size * size)
75
+ for region in regions do
76
+ iterRegion size region |> Seq.iter
77
+ ( fun i -> fabric.[ i] <- fabric.[ i] + 1 )
78
+ fabric
79
+
80
+ let countOverlapping fabric =
81
+ Array.fold ( fun count x -> count + ( if x > 1 then 1 else 0 )) 0 fabric
82
+
83
+ let regionWithOverlap size ( fabric : int []) region =
84
+ iterRegion size region |> Seq.forall ( fun i -> fabric.[ i] = 1 )
85
+
86
+ let day3 () =
87
+ printfn " Day 3:"
88
+ let size = 1000
89
+ let vs = readLines " day3.input" |> List.map parseLine
90
+ let fabric = createFabric size vs
91
+ let numOverlap = countOverlapping fabric
92
+ printfn " %A " numOverlap
93
+ let region = List.find ( regionWithOverlap size fabric) vs
94
+ printfn " #%s " region.id
95
+
96
+
97
+ [<EntryPoint>]
98
+ let main argv =
99
+ printfn " Executing main"
100
+ day1 ()
101
+ day2 ()
102
+ day3 ()
103
+ 0
0 commit comments