diff options
author | Tomasz Chojnacki <tomaszchojnacki2001@gmail.com> | 2022-12-05 23:44:52 +0100 |
---|---|---|
committer | Tomasz Chojnacki <tomaszchojnacki2001@gmail.com> | 2022-12-05 23:44:52 +0100 |
commit | f0820f9561713bf6a14455d3b218f2144d8d43d0 (patch) | |
tree | f0b5e9458a5085cb4747e9170bf96692982ac03e /aoc-2022-dotnet/Day05 | |
parent | 72fb5738c5891974abacb3149bdd7e9db2cf6e70 (diff) | |
download | gleam_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.fsproj | 22 | ||||
-rw-r--r-- | aoc-2022-dotnet/Day05/Program.fs | 67 |
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 |