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