Day 6.
authorGrégory Burri <gregory.burri@matisa.ch>
Fri, 7 Dec 2018 08:42:05 +0000 (09:42 +0100)
committerGrégory Burri <gregory.burri@matisa.ch>
Fri, 7 Dec 2018 08:42:05 +0000 (09:42 +0100)
AdventOfCode2018.fsproj
Day06.fs [new file with mode: 0644]
Program.fs
Tests/Day06 tests.fs [new file with mode: 0644]
Tests/Tests.fsproj

index 4a31bd3..7026dc3 100644 (file)
@@ -4,12 +4,16 @@
     <TargetFramework>netcoreapp2.1</TargetFramework>\r
   </PropertyGroup>\r
   <ItemGroup>\r
+    <Compile Include="Day06.fs" />\r
     <Compile Include="Day05.fs" />\r
     <Compile Include="Day04.fs" />\r
     <Compile Include="Day03.fs" />\r
     <Compile Include="Day02.fs" />\r
     <Compile Include="Day01.fs" />\r
     <Compile Include="Program.fs" />\r
+    <Content Include="Data/day06.input">\r
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\r
+    </Content>\r
     <Content Include="Data/day05.input">\r
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\r
     </Content>\r
diff --git a/Day06.fs b/Day06.fs
new file mode 100644 (file)
index 0000000..683f373
--- /dev/null
+++ b/Day06.fs
@@ -0,0 +1,65 @@
+module AdventOfCode2018.Day06\r
+\r
+open System\r
+\r
+type Coords = { X : int; Y : int }\r
+    with\r
+        member this.Distance (coords : Coords) : int =\r
+            abs (coords.X - this.X) + abs (coords.Y - this.Y)\r
+\r
+        static member Parse (str : string) =\r
+            let coords = str.Split ','\r
+            { X = int coords.[0]; Y = int coords.[1] }\r
+\r
+let parseInput (str : string) : Coords array =\r
+    str.Split ([| '\r'; '\n'; |], StringSplitOptions.RemoveEmptyEntries)\r
+    |> Array.map Coords.Parse\r
+\r
+let getLargestArea (coords : Coords array) : int =\r
+    let coordsX = coords |> Array.map (fun coords -> coords.X)\r
+    let coordsY = coords |> Array.map (fun coords -> coords.Y)\r
+    let minX, minY, maxX, maxY = coordsX |> Array.min, coordsY |> Array.min, coordsX |> Array.max, coordsY |> Array.max\r
+\r
+    let areas = Array.zeroCreate coords.Length\r
+\r
+    for x = minX to maxX do\r
+        for y = minY to maxY do\r
+            let pos = { X = x; Y = y }\r
+            let mutable nearest = -1\r
+            let mutable distance = Int32.MaxValue\r
+            let mutable equalDistance = false\r
+\r
+            for i = 0 to coords.Length - 1 do\r
+                let distance' = pos.Distance coords.[i]\r
+                if distance' = distance then\r
+                    equalDistance <- true\r
+                if distance' < distance then\r
+                    nearest <- i\r
+                    distance <- distance'\r
+                    equalDistance <- false\r
+\r
+            if not equalDistance then\r
+                if x = minX || y = minY || x = maxX || y = maxY then\r
+                    areas.[nearest] <- -1\r
+                elif areas.[nearest] <> -1 then\r
+                    areas.[nearest] <- areas.[nearest] + 1\r
+\r
+    areas |> Array.max\r
+\r
+let getAreaWithTotalDistanceLessThan (total : int) (coords : Coords array) : int =\r
+    let coordsX = coords |> Array.map (fun coords -> coords.X)\r
+    let coordsY = coords |> Array.map (fun coords -> coords.Y)\r
+    let minX, minY, maxX, maxY = coordsX |> Array.min, coordsY |> Array.min, coordsX |> Array.max, coordsY |> Array.max\r
+\r
+    let mutable area = 0\r
+\r
+    for x = minX to maxX do\r
+        for y = minY to maxY do\r
+            let pos = { X = x; Y = y }\r
+            let mutable totalDistance = 0\r
+            for i = 0 to coords.Length - 1 do\r
+                totalDistance <- totalDistance + pos.Distance coords.[i]\r
+            if totalDistance < total then\r
+                area <- area + 1\r
+\r
+    area
\ No newline at end of file
index fb433b7..fcb5fc1 100644 (file)
@@ -25,6 +25,10 @@ let day05 () =
     let reduced = (File.ReadAllText "Data/day05.input").Trim () |> List.ofSeq |> Day05.reduce\r
     sprintf "part1 = %A, part2 = %A" reduced.Length (Day05.findShortestPolymer reduced).Length\r
 \r
+let day06 () =\r
+    let coords = File.ReadAllText "Data/day06.input" |> Day06.parseInput\r
+    sprintf "part1 = %A, part2 = %A" (Day06.getLargestArea coords) (Day06.getAreaWithTotalDistanceLessThan 10000 coords)\r
+\r
 let days : Map<int, unit -> string> =\r
     [\r
         1, day01\r
@@ -32,6 +36,7 @@ let days : Map<int, unit -> string> =
         3, day03\r
         4, day04\r
         5, day05\r
+        6, day06\r
     ] |> Map.ofList\r
 \r
 let doDay (n : int) =\r
diff --git a/Tests/Day06 tests.fs b/Tests/Day06 tests.fs
new file mode 100644 (file)
index 0000000..38e1df5
--- /dev/null
@@ -0,0 +1,29 @@
+namespace AdventOfCode2018.Tests\r
+\r
+open System\r
+\r
+open Xunit\r
+open Xunit.Abstractions\r
+open Swensen.Unquote\r
+\r
+open AdventOfCode2018\r
+\r
+type ``Day06 tests`` (output : ITestOutputHelper) =\r
+    let input =\r
+        """1, 1\r
+           1, 6\r
+           8, 3\r
+           3, 4\r
+           5, 5\r
+           8, 9"""\r
+\r
+    [<Fact>]\r
+    let ``(Part1) From web page`` () =\r
+        let coords = Day06.parseInput input\r
+        Day06.getLargestArea coords =! 17\r
+\r
+    [<Fact>]\r
+    let ``(Part2) From web page`` () =\r
+        let coords = Day06.parseInput input\r
+        Day06.getAreaWithTotalDistanceLessThan 32 coords =! 16\r
+\r
index a7712db..0042788 100644 (file)
@@ -6,6 +6,7 @@
     <ProjectReference Include="..\AdventOfCode2018.fsproj" />\r
   </ItemGroup>\r
   <ItemGroup>\r
+    <Compile Include="Day06 tests.fs" />\r
     <Compile Include="Day05 tests.fs" />\r
     <Compile Include="Day04 tests.fs" />\r
     <Compile Include="Day03 tests.fs" />\r