aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Chojnacki <tomaszchojnacki2001@gmail.com>2022-12-15 21:55:28 +0100
committerTomasz Chojnacki <tomaszchojnacki2001@gmail.com>2022-12-15 21:55:28 +0100
commit7ce938ea4d40e9a631bfe11795f3d9f74855ceb5 (patch)
tree2ce00c913332b378ebc1b7a5a8d9d3504a4a8734
parent6fc820cd0cb61a4bacda5f5b40c98dda850d75da (diff)
downloadgleam_aoc2020-7ce938ea4d40e9a631bfe11795f3d9f74855ceb5.tar.gz
gleam_aoc2020-7ce938ea4d40e9a631bfe11795f3d9f74855ceb5.zip
Finish day 14
-rw-r--r--README.md2
-rw-r--r--aoc-2022-dotnet/Common/Vec2.fs17
-rw-r--r--aoc-2022-dotnet/Day12/Program.fs7
-rw-r--r--aoc-2022-dotnet/Day14/Day14.fsproj26
-rw-r--r--aoc-2022-dotnet/Day14/Program.fs80
-rw-r--r--aoc-2022-dotnet/README.md4
-rw-r--r--aoc-2022-dotnet/aoc-2022-dotnet.sln8
7 files changed, 135 insertions, 9 deletions
diff --git a/README.md b/README.md
index e1f1f9d..ea58a4b 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ Repository storing my solutions to Advent of Code. See other people's solutions
### [2022](aoc-2022-dotnet)
![.NET](https://img.shields.io/badge/.NET-grey?logo=.NET)
-![Stars](https://img.shields.io/badge/🌟%20stars-26/50-orange)
+![Stars](https://img.shields.io/badge/🌟%20stars-28/50-orange)
[awesome]: https://github.com/Bogdanp/awesome-advent-of-code
[aoc]: https://adventofcode.com
diff --git a/aoc-2022-dotnet/Common/Vec2.fs b/aoc-2022-dotnet/Common/Vec2.fs
index 11c94aa..8835a5a 100644
--- a/aoc-2022-dotnet/Common/Vec2.fs
+++ b/aoc-2022-dotnet/Common/Vec2.fs
@@ -1,14 +1,21 @@
ο»Ώnamespace Common
+[<StructuralEquality; StructuralComparison>]
type Vec2 =
| Vec2 of int * int
+ static member x(Vec2 (x, _)) = x
+ static member y(Vec2 (_, y)) = y
+
static member zero = Vec2(0, 0)
static member up = Vec2(0, 1)
static member right = Vec2(1, 0)
static member down = Vec2(0, -1)
static member left = Vec2(-1, 0)
+ static member downLeft = Vec2(-1, -1)
+ static member downRight = Vec2(1, -1)
+
static member directions4 =
[ Vec2.up
Vec2.right
@@ -28,6 +35,16 @@ type Vec2 =
static member chebyshevDist (Vec2 (x1, y1)) (Vec2 (x2, y2)) = max (abs <| x2 - x1) (abs <| y2 - y1)
static member neighbours4 v = List.map ((+) v) Vec2.directions4
+ static member lineBetween(Vec2 (x1, y1), Vec2 (x2, y2)) =
+ if x1 = x2 then
+ seq { min y1 y2 .. max y1 y2 }
+ |> Seq.map (fun y -> Vec2(x1, y))
+ elif y1 = y2 then
+ seq { min x1 x2 .. max x1 x2 }
+ |> Seq.map (fun x -> Vec2(x, y1))
+ else
+ failwith "Points must be in a vertical or horizontal line!"
+
static member inMatrix matrix (Vec2 (col, row)) =
col >= 0
&& col < Array2D.length2 matrix
diff --git a/aoc-2022-dotnet/Day12/Program.fs b/aoc-2022-dotnet/Day12/Program.fs
index 0ccaab7..ca827ba 100644
--- a/aoc-2022-dotnet/Day12/Program.fs
+++ b/aoc-2022-dotnet/Day12/Program.fs
@@ -57,11 +57,8 @@ type Graph<'T> =
Some(depth)
else
bfsExplore
- (neighbours
- |> Seq.choose (fun n ->
- match Set.contains n explored with
- | true -> None
- | false -> Some(n, depth + 1))
+ (neighbours - explored
+ |> Seq.map (fun n -> (n, depth + 1))
|> Seq.append qt
|> List.ofSeq)
(explored + neighbours))
diff --git a/aoc-2022-dotnet/Day14/Day14.fsproj b/aoc-2022-dotnet/Day14/Day14.fsproj
new file mode 100644
index 0000000..358ef88
--- /dev/null
+++ b/aoc-2022-dotnet/Day14/Day14.fsproj
@@ -0,0 +1,26 @@
+ο»Ώ<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>
+ <PackageReference Include="FParsec" Version="1.1.1" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Common\Common.fsproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/aoc-2022-dotnet/Day14/Program.fs b/aoc-2022-dotnet/Day14/Program.fs
new file mode 100644
index 0000000..02e028c
--- /dev/null
+++ b/aoc-2022-dotnet/Day14/Program.fs
@@ -0,0 +1,80 @@
+ο»Ώmodule Day14
+
+open System.IO
+open FParsec
+open Common
+
+let sandSpawnPos = Vec2(500, 0)
+
+let sandMoveOffsets =
+ [ Vec2.down
+ Vec2.downLeft
+ Vec2.downRight ]
+
+let notIn set element = not <| Set.contains element set
+
+let buildCaveScan =
+ let parsePath =
+ let py = pint32 |>> (~-) // mirror Y coordinate
+ let ppoint = pint32 .>> (pchar ',') .>>. py |>> Vec2
+ let ppath = sepBy ppoint (pstring " -> ")
+ Util.parse ppath
+
+ let pathToPositions =
+ Seq.pairwise
+ >> Seq.collect Vec2.lineBetween
+ >> Set
+
+ Seq.map (parsePath >> pathToPositions)
+ >> Seq.reduce (+)
+
+let solution1 input =
+ let initialCaveScan = buildCaveScan input
+ let voidY = initialCaveScan |> Seq.map Vec2.y |> Seq.min
+
+ let settleNewUnit caveScan =
+ let rec fall pos =
+ if Vec2.y pos <= voidY then
+ None
+ else
+ sandMoveOffsets
+ |> Seq.map ((+) pos)
+ |> Seq.tryFind (notIn caveScan)
+ |> function
+ | Some (nextPos) -> fall nextPos
+ | None -> Some(pos)
+
+ caveScan
+ |> match fall sandSpawnPos with
+ | Some (settledPos) -> Set.add settledPos
+ | None -> id
+
+ initialCaveScan
+ |> Seq.unfold (fun caveScan -> Some(caveScan, settleNewUnit caveScan))
+ |> Seq.pairwise
+ |> Seq.takeWhile (fun (a, b) -> a <> b)
+ |> Seq.length
+
+let solution2 input =
+ let caveScan = buildCaveScan input
+ let floorY = caveScan |> Seq.map Vec2.y |> Seq.min |> (+) -2
+
+ let neighbours pos =
+ sandMoveOffsets
+ |> List.map ((+) pos)
+ |> List.filter (fun pos -> notIn caveScan pos && Vec2.y pos <> floorY)
+
+ let rec dfs stack visited =
+ match stack with
+ | h :: t -> dfs (List.filter (notIn visited) (neighbours h) @ t) (Set.add h visited)
+ | [] -> Set.count visited
+
+ dfs [ sandSpawnPos ] Set.empty
+
+let test = File.ReadLines("test.txt")
+assert (solution1 test = 24)
+assert (solution2 test = 93)
+
+let input = File.ReadLines("input.txt")
+printfn "%d" <| solution1 input
+printfn "%d" <| solution2 input
diff --git a/aoc-2022-dotnet/README.md b/aoc-2022-dotnet/README.md
index dbcb833..84a39ce 100644
--- a/aoc-2022-dotnet/README.md
+++ b/aoc-2022-dotnet/README.md
@@ -1,6 +1,6 @@
# Advent of Code 2022 in .NET
![.NET](https://img.shields.io/badge/.NET-grey?logo=.NET)
-![Stars](https://img.shields.io/badge/🌟%20stars-26/50-orange)
+![Stars](https://img.shields.io/badge/🌟%20stars-28/50-orange)
## Progress
| Day | Part 1 | Part 2 |
@@ -18,7 +18,7 @@
| Day 11: Monkey in the Middle | 🌟 | 🌟 |
| Day 12: Hill Climbing Algorithm | 🌟 | 🌟 |
| Day 13: Distress Signal | 🌟 | 🌟 |
-| Day 14: ??? | | |
+| Day 14: Regolith Reservoir | 🌟 | 🌟 |
| Day 15: ??? | | |
| Day 16: ??? | | |
| Day 17: ??? | | |
diff --git a/aoc-2022-dotnet/aoc-2022-dotnet.sln b/aoc-2022-dotnet/aoc-2022-dotnet.sln
index cf90abd..fb017eb 100644
--- a/aoc-2022-dotnet/aoc-2022-dotnet.sln
+++ b/aoc-2022-dotnet/aoc-2022-dotnet.sln
@@ -38,7 +38,9 @@ Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Day11", "Day11\Day11.fsproj
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Day12", "Day12\Day12.fsproj", "{3A931587-D31B-4ED7-8AB4-D663175AA7B0}"
EndProject
-Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Day13", "Day13\Day13.fsproj", "{60CC1225-2988-48A1-BA37-477053E3CE98}"
+Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Day13", "Day13\Day13.fsproj", "{60CC1225-2988-48A1-BA37-477053E3CE98}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Day14", "Day14\Day14.fsproj", "{3241E7B6-B58B-4032-9746-DF87B1F0D666}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -106,6 +108,10 @@ Global
{60CC1225-2988-48A1-BA37-477053E3CE98}.Debug|Any CPU.Build.0 = Debug|Any CPU
{60CC1225-2988-48A1-BA37-477053E3CE98}.Release|Any CPU.ActiveCfg = Release|Any CPU
{60CC1225-2988-48A1-BA37-477053E3CE98}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3241E7B6-B58B-4032-9746-DF87B1F0D666}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3241E7B6-B58B-4032-9746-DF87B1F0D666}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3241E7B6-B58B-4032-9746-DF87B1F0D666}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3241E7B6-B58B-4032-9746-DF87B1F0D666}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE