aboutsummaryrefslogtreecommitdiff
path: root/aoc-2022-dotnet/Day05
diff options
context:
space:
mode:
authorTomasz Chojnacki <tomaszchojnacki2001@gmail.com>2022-12-05 23:44:52 +0100
committerTomasz Chojnacki <tomaszchojnacki2001@gmail.com>2022-12-05 23:44:52 +0100
commitf0820f9561713bf6a14455d3b218f2144d8d43d0 (patch)
treef0b5e9458a5085cb4747e9170bf96692982ac03e /aoc-2022-dotnet/Day05
parent72fb5738c5891974abacb3149bdd7e9db2cf6e70 (diff)
downloadgleam_aoc2020-f0820f9561713bf6a14455d3b218f2144d8d43d0.tar.gz
gleam_aoc2020-f0820f9561713bf6a14455d3b218f2144d8d43d0.zip
Finish day 5
Diffstat (limited to 'aoc-2022-dotnet/Day05')
-rw-r--r--aoc-2022-dotnet/Day05/Day05.fsproj22
-rw-r--r--aoc-2022-dotnet/Day05/Program.fs67
2 files changed, 89 insertions, 0 deletions
diff --git a/aoc-2022-dotnet/Day05/Day05.fsproj b/aoc-2022-dotnet/Day05/Day05.fsproj
new file mode 100644
index 0000000..44c3fba
--- /dev/null
+++ b/aoc-2022-dotnet/Day05/Day05.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>
+ <PackageReference Include="FParsec" Version="1.1.1" />
+ </ItemGroup>
+
+</Project>
diff --git a/aoc-2022-dotnet/Day05/Program.fs b/aoc-2022-dotnet/Day05/Program.fs
new file mode 100644
index 0000000..e15f53d
--- /dev/null
+++ b/aoc-2022-dotnet/Day05/Program.fs
@@ -0,0 +1,67 @@
+open System
+open System.IO
+open FParsec
+
+type Move =
+ | Move of int * int * int
+
+ static member parse str =
+ let dec n = n - 1
+ let pPart str = pstring str >>. pint32
+ let pMove = tuple3 (pPart "move ") (pPart " from " |>> dec) (pPart " to " |>> dec)
+
+ match run pMove str with
+ | Success (result, _, _) -> Move result
+ | _ -> failwith "Invalid move format!"
+
+ static member execute order stacks (Move (n, fi, ti)) =
+ List.mapi
+ (fun i x ->
+ if i = fi then
+ List.item fi stacks |> List.skip n
+ elif i = ti then
+ (List.item fi stacks |> List.take n |> order)
+ @ List.item ti stacks
+ else
+ x)
+ stacks
+
+let parseStacks str =
+ let pFullCrate = pchar '[' >>. anyChar .>> pchar ']' |>> Some
+ let pEmptyCrate = pstring " " >>% None
+ let pCrate = pFullCrate <|> pEmptyCrate
+ let pCrateLine = sepBy pCrate (pchar ' ') .>> skipNewline
+ let pHeader = many pCrateLine
+
+ let parsed =
+ match run pHeader str with
+ | Success (result, _, _) -> result
+ | _ -> failwith "Invalid header format!"
+
+ parsed
+ |> List.transpose
+ |> List.map (List.choose id)
+
+let solve order input =
+ let headerList =
+ input
+ |> Seq.takeWhile (not << String.IsNullOrEmpty)
+ |> Seq.toList
+
+ let stacks = parseStacks <| String.Join("\n", headerList)
+
+ String.Concat(
+ input
+ |> Seq.skip (headerList.Length + 1)
+ |> Seq.map Move.parse
+ |> Seq.fold (Move.execute order) stacks
+ |> List.map List.head
+ )
+
+let test = File.ReadLines "test.txt"
+assert (solve List.rev test = "CMZ")
+assert (solve id test = "MCD")
+
+let input = File.ReadLines "input.txt"
+printfn "%s" <| solve List.rev input
+printfn "%s" <| solve id input