aboutsummaryrefslogtreecommitdiff
path: root/aoc-2022-dotnet/Day18
diff options
context:
space:
mode:
authorTomasz Chojnacki <tomaszchojnacki2001@gmail.com>2022-12-22 13:43:09 +0100
committerTomasz Chojnacki <tomaszchojnacki2001@gmail.com>2022-12-22 13:43:09 +0100
commitc8a6d6010bddc3789f4770e66da3766fc4f470ad (patch)
tree1448ef78036248b46343d7e981e31d96ebc88966 /aoc-2022-dotnet/Day18
parent9e378a9f80260c2f729daaf83d8e74f7bad70b16 (diff)
downloadgleam_aoc2020-c8a6d6010bddc3789f4770e66da3766fc4f470ad.tar.gz
gleam_aoc2020-c8a6d6010bddc3789f4770e66da3766fc4f470ad.zip
Finish day 18
Diffstat (limited to 'aoc-2022-dotnet/Day18')
-rw-r--r--aoc-2022-dotnet/Day18/Day18.fsproj22
-rw-r--r--aoc-2022-dotnet/Day18/Program.fs51
2 files changed, 73 insertions, 0 deletions
diff --git a/aoc-2022-dotnet/Day18/Day18.fsproj b/aoc-2022-dotnet/Day18/Day18.fsproj
new file mode 100644
index 0000000..b9a3919
--- /dev/null
+++ b/aoc-2022-dotnet/Day18/Day18.fsproj
@@ -0,0 +1,22 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ <TargetFramework>net7.0</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <Content Include="test.txt">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="input.txt">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Compile Include="Program.fs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Common\Common.fsproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/aoc-2022-dotnet/Day18/Program.fs b/aoc-2022-dotnet/Day18/Program.fs
new file mode 100644
index 0000000..3784d0d
--- /dev/null
+++ b/aoc-2022-dotnet/Day18/Program.fs
@@ -0,0 +1,51 @@
+module Day18
+
+open System.IO
+open FParsec
+open Common
+
+let parsePos =
+ Util.parse (
+ tuple3 (pint32 .>> pchar ',') (pint32 .>> pchar ',') pint32
+ |>> Vec3
+ )
+
+let fullSurface cubes =
+ cubes
+ |> Seq.collect Vec3.neighbours6
+ |> Seq.filter (Util.notIn cubes)
+ |> Seq.length
+
+let externalSurface cubes =
+ let hasLava pos = Set.contains pos cubes
+
+ let minBound = Seq.reduce (Vec3.combine min) cubes - Vec3.ones
+ let maxBound = Seq.reduce (Vec3.combine max) cubes + Vec3.ones
+
+ let neighbours pos =
+ match hasLava pos with
+ | true -> []
+ | false -> List.filter (Vec3.boundedBy minBound maxBound) (Vec3.neighbours6 pos)
+
+ let rec dfs visited count =
+ function
+ | pos :: stackTail ->
+ let count' = count + if hasLava pos then 1 else 0
+
+ match Set.contains pos visited with
+ | true -> dfs visited count' stackTail
+ | false -> dfs (Set.add pos visited) count' (neighbours pos @ stackTail)
+ | [] -> count
+
+ dfs Set.empty 0 [ minBound ]
+
+let solution surface =
+ Seq.map parsePos >> Set.ofSeq >> surface
+
+let test = File.ReadLines("test.txt")
+assert (solution fullSurface test = 64)
+assert (solution externalSurface test = 2540)
+
+let input = File.ReadLines("input.txt")
+printfn "%d" <| solution fullSurface input
+printfn "%d" <| solution externalSurface input