aboutsummaryrefslogtreecommitdiff
path: root/aoc-2022-dotnet
diff options
context:
space:
mode:
Diffstat (limited to 'aoc-2022-dotnet')
-rw-r--r--aoc-2022-dotnet/Common/Vec2.fs4
-rw-r--r--aoc-2022-dotnet/Day22/Day22.fsproj19
-rw-r--r--aoc-2022-dotnet/Day22/Program.fs94
-rw-r--r--aoc-2022-dotnet/README.md6
-rw-r--r--aoc-2022-dotnet/aoc-2022-dotnet.sln10
5 files changed, 128 insertions, 5 deletions
diff --git a/aoc-2022-dotnet/Common/Vec2.fs b/aoc-2022-dotnet/Common/Vec2.fs
index 8183083..24af9bb 100644
--- a/aoc-2022-dotnet/Common/Vec2.fs
+++ b/aoc-2022-dotnet/Common/Vec2.fs
@@ -73,6 +73,10 @@ type Vec2 =
static member inline cross (Vec2 (x1, y1)) (Vec2 (x2, y2)) = x1 * y2 - y1 * x2
static member inline sign = Vec2._map sign
static member inline lengthSquared v = Vec2.dot v v
+ static member inline rotateLeft(Vec2 (x, y)) = Vec2(-y, x)
+ static member inline rotateRight(Vec2 (x, y)) = Vec2(y, -x)
+ static member inline flip = Vec2.op_UnaryNegation
+
static member manhattanDist (Vec2 (x1, y1)) (Vec2 (x2, y2)) = abs (x2 - x1) + abs (y2 - y1)
static member chebyshevDist (Vec2 (x1, y1)) (Vec2 (x2, y2)) = max (abs <| x2 - x1) (abs <| y2 - y1)
diff --git a/aoc-2022-dotnet/Day22/Day22.fsproj b/aoc-2022-dotnet/Day22/Day22.fsproj
new file mode 100644
index 0000000..e7e4a65
--- /dev/null
+++ b/aoc-2022-dotnet/Day22/Day22.fsproj
@@ -0,0 +1,19 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ <TargetFramework>net7.0</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <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/Day22/Program.fs b/aoc-2022-dotnet/Day22/Program.fs
new file mode 100644
index 0000000..7bb6b2d
--- /dev/null
+++ b/aoc-2022-dotnet/Day22/Program.fs
@@ -0,0 +1,94 @@
+module Day22
+
+open System.IO
+open System.Text.RegularExpressions
+open FSharpPlus
+open FSharpPlus.Math.Generic
+open Common
+
+let passwordRegex = Regex("L|R|\d+", RegexOptions.Compiled)
+
+let facing =
+ function
+ | Vec2 (1, 0) -> 0
+ | Vec2 (0, 1) -> 1
+ | Vec2 (-1, 0) -> 2
+ | Vec2 (0, -1) -> 3
+ | v -> failwithf "Invalid direction: %A" v
+
+let solution wrapper input =
+ let map, password = Util.splitStringToTuple "\n\n" input
+
+ let map =
+ map
+ |> String.split [ "\n" ]
+ |> Seq.map (String.padRight 150)
+ |> array2D
+
+ let (pos, dir) =
+ passwordRegex.Matches(password)
+ |> Seq.fold
+ (fun (pos, dir) c ->
+ match c.Value with
+ | "R" -> pos, Vec2.rotateLeft dir
+ | "L" -> pos, Vec2.rotateRight dir
+ | dist ->
+ Util.composition
+ (int dist)
+ (fun state ->
+ let state' = state |> mapItem1 ((+) <| snd state) |> wrapper
+
+ match Util.mAt map (fst state') with
+ | '.' -> state'
+ | _ -> state)
+ (pos, dir))
+ (Vec2(Seq.findIndex ((=) '.') map[0, *], 0), Vec2.right)
+
+ let (Vec2 (x, y)) = pos + Vec2.ones
+ y * 1000 + x * 4 + facing dir
+
+let wrap1 (Vec2 (x, y), d) =
+ let x, y =
+ match (divE x 50, divE y 50, d) with
+ | (1, 3, Vec2 (0, 1))
+ | (2, 1, Vec2 (0, 1)) -> x, 0
+ | (2, -1, Vec2 (0, -1)) -> x, 49
+ | (0, 4, Vec2 (0, 1)) -> x, 100
+ | (1, -1, Vec2 (0, -1)) -> x, 149
+ | (0, 1, Vec2 (0, -1)) -> x, 199
+ | (1, 3, Vec2 (1, 0))
+ | (2, 2, Vec2 (1, 0)) -> 0, y
+ | (-1, 3, Vec2 (-1, 0)) -> 49, y
+ | (2, 1, Vec2 (1, 0))
+ | (3, 0, Vec2 (1, 0)) -> 50, y
+ | (-1, 2, Vec2 (-1, 0))
+ | (0, 1, Vec2 (-1, 0)) -> 99, y
+ | (0, 0, Vec2 (-1, 0)) -> 149, y
+ | _ -> x, y
+
+ Vec2(x, y), d
+
+let wrap2 (Vec2 (x, y), d) =
+ let x, y, t =
+ match (divE x 50, divE y 50, d) with
+ | (-1, 2, Vec2 (-1, 0)) -> 50, 149 - y, Vec2.flip
+ | (-1, 3, Vec2 (-1, 0)) -> y - 100, 0, Vec2.rotateRight
+ | (0, 0, Vec2 (-1, 0)) -> 0, 149 - y, Vec2.flip
+ | (0, 1, Vec2 (-1, 0)) -> y - 50, 100, Vec2.rotateRight
+ | (0, 1, Vec2 (0, -1)) -> 50, x + 50, Vec2.rotateLeft
+ | (0, 4, Vec2 (0, 1)) -> x + 100, 0, id
+ | (1, -1, Vec2 (0, -1)) -> 0, x + 100, Vec2.rotateLeft
+ | (1, 3, Vec2 (1, 0)) -> y - 100, 149, Vec2.rotateRight
+ | (1, 3, Vec2 (0, 1)) -> 49, x + 100, Vec2.rotateLeft
+ | (2, -1, Vec2 (0, -1)) -> x - 100, 199, id
+ | (2, 1, Vec2 (1, 0)) -> y + 50, 49, Vec2.rotateRight
+ | (2, 1, Vec2 (0, 1)) -> 99, x - 50, Vec2.rotateLeft
+ | (2, 2, Vec2 (1, 0)) -> 149, 149 - y, Vec2.flip
+ | (3, 0, Vec2 (1, 0)) -> 99, 149 - y, Vec2.flip
+ | _ -> x, y, id
+
+ Vec2(x, y), t d
+
+let input = File.ReadAllText("input.txt")
+printfn "%b" (solution wrap1 input = 103224)
+printfn "%b" (solution wrap2 input = 189097)
diff --git a/aoc-2022-dotnet/README.md b/aoc-2022-dotnet/README.md
index 2cf006d..3765775 100644
--- a/aoc-2022-dotnet/README.md
+++ b/aoc-2022-dotnet/README.md
@@ -1,6 +1,6 @@
# Advent of Code 2022 in F#
![F#](https://img.shields.io/badge/F%23-grey?logo=.NET)
-![Stars](https://img.shields.io/badge/🌟%20stars-47/50-orange)
+![Stars](https://img.shields.io/badge/🌟%20stars-50/50-orange)
| Day | Problem Name | Part 1 | Part 2 | Practiced Concepts |
| :----: | ---------------------------------------------------------------- | :----: | :----: | ----------------------------------------------------- |
@@ -25,7 +25,7 @@
| **19** | [Not Enough Minerals](https://adventofcode.com/2022/day/19) | :star: | :star: | `List.fold`, records, `Map`, mutability, optimization |
| **20** | [Grove Positioning System](https://adventofcode.com/2022/day/20) | :star: | :star: | linked lists, remainder |
| **21** | [Monkey Math](https://adventofcode.com/2022/day/21) | :star: | :star: | topological sort, ADTs, complex numbers |
-| **22** | [Monkey Map](https://adventofcode.com/2022/day/22) | | | |
+| **22** | [Monkey Map](https://adventofcode.com/2022/day/22) | :star: | :star: | 2D vectors, rotations, `Array2D`, 3D geometry |
| **23** | [Unstable Diffusion](https://adventofcode.com/2022/day/23) | :star: | :star: | `Set`, 2D vectors, `Seq.unfold`, composition |
| **24** | [Blizzard Basin](https://adventofcode.com/2022/day/24) | :star: | :star: | `Set`, 2D vectors, remainder, records |
-| **25** | [Full of Hot Air](https://adventofcode.com/2022/day/25) | :star: | | positional numeral systems, recursion |
+| **25** | [Full of Hot Air](https://adventofcode.com/2022/day/25) | :star: | :star: | positional numeral systems, recursion |
diff --git a/aoc-2022-dotnet/aoc-2022-dotnet.sln b/aoc-2022-dotnet/aoc-2022-dotnet.sln
index 5d1708a..86bedbd 100644
--- a/aoc-2022-dotnet/aoc-2022-dotnet.sln
+++ b/aoc-2022-dotnet/aoc-2022-dotnet.sln
@@ -58,9 +58,11 @@ Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Day25", "Day25\Day25.fsproj
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Day23", "Day23\Day23.fsproj", "{E6AEEB69-7669-4026-AC28-94D7B4467838}"
EndProject
-Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Day24", "Day24\Day24.fsproj", "{253313A4-C9F8-4A83-89A5-8FCB426004E0}"
+Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Day24", "Day24\Day24.fsproj", "{253313A4-C9F8-4A83-89A5-8FCB426004E0}"
EndProject
-Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Day19", "Day19\Day19.fsproj", "{65ED4E60-D36D-4519-9DF1-EFCE6787D480}"
+Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Day19", "Day19\Day19.fsproj", "{65ED4E60-D36D-4519-9DF1-EFCE6787D480}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Day22", "Day22\Day22.fsproj", "{303EA589-0290-4205-8A3D-467840D86A4D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -172,6 +174,10 @@ Global
{65ED4E60-D36D-4519-9DF1-EFCE6787D480}.Debug|Any CPU.Build.0 = Debug|Any CPU
{65ED4E60-D36D-4519-9DF1-EFCE6787D480}.Release|Any CPU.ActiveCfg = Release|Any CPU
{65ED4E60-D36D-4519-9DF1-EFCE6787D480}.Release|Any CPU.Build.0 = Release|Any CPU
+ {303EA589-0290-4205-8A3D-467840D86A4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {303EA589-0290-4205-8A3D-467840D86A4D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {303EA589-0290-4205-8A3D-467840D86A4D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {303EA589-0290-4205-8A3D-467840D86A4D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE