diff options
author | Tomasz Chojnacki <tomaszchojnacki2001@gmail.com> | 2022-12-13 16:38:41 +0100 |
---|---|---|
committer | Tomasz Chojnacki <tomaszchojnacki2001@gmail.com> | 2022-12-13 16:38:41 +0100 |
commit | 6fc820cd0cb61a4bacda5f5b40c98dda850d75da (patch) | |
tree | 7d08b0adbf8c1b60be906cab3ee7b76767b6908e /aoc-2022-dotnet/Day13 | |
parent | eb7cdaab9b9c13b3594e0abdbbff6f72f8cb4807 (diff) | |
download | gleam_aoc2020-6fc820cd0cb61a4bacda5f5b40c98dda850d75da.tar.gz gleam_aoc2020-6fc820cd0cb61a4bacda5f5b40c98dda850d75da.zip |
Upload days 12 and 13
Diffstat (limited to 'aoc-2022-dotnet/Day13')
-rw-r--r-- | aoc-2022-dotnet/Day13/Day13.fsproj | 26 | ||||
-rw-r--r-- | aoc-2022-dotnet/Day13/Program.fs | 73 |
2 files changed, 99 insertions, 0 deletions
diff --git a/aoc-2022-dotnet/Day13/Day13.fsproj b/aoc-2022-dotnet/Day13/Day13.fsproj new file mode 100644 index 0000000..358ef88 --- /dev/null +++ b/aoc-2022-dotnet/Day13/Day13.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/Day13/Program.fs b/aoc-2022-dotnet/Day13/Program.fs new file mode 100644 index 0000000..2ff8b8d --- /dev/null +++ b/aoc-2022-dotnet/Day13/Program.fs @@ -0,0 +1,73 @@ +module Day13 + +#nowarn "0342" + +open System +open System.IO +open FParsec +open Common + +[<StructuralEquality; CustomComparison>] +type Packet = + | Integer of int + | List of Packet list + + static member dividers = + [ Packet.parse "[[2]]" + Packet.parse "[[6]]" ] + + interface IComparable with + member this.CompareTo other = + match other with + | :? Packet as p -> (this :> IComparable<_>).CompareTo p + | _ -> failwith "Can only compare packets with other packets!" + + interface IComparable<Packet> with + member this.CompareTo other = + match (this, other) with + | Integer l, Integer r -> compare l r + | List l, List r -> compare l r + | (Integer _ as l), (List _ as r) -> compare (List [ l ]) r + | (List _ as l), (Integer _ as r) -> compare l (List [ r ]) + + static member parse = + let ppacket, ppacketImpl = createParserForwardedToRef () + let pinteger = pint32 |>> Integer + + let plist = + between (pchar '[') (pchar ']') (sepBy ppacket (pchar ',')) + |>> List + + ppacketImpl.Value <- pinteger <|> plist + + Util.parse ppacket + +let solution (transform, predicate, reducer) = + Seq.filter (not << String.IsNullOrWhiteSpace) + >> Seq.map Packet.parse + >> transform + >> Seq.indexed + >> Seq.choose (fun (i, p) -> + match predicate p with + | true -> Some(i + 1) + | false -> None) + >> Seq.reduce reducer + +let part1 = + (Seq.chunkBySize 2 + >> Seq.map (function + | [| l; r |] -> compare l r + | _ -> failwith "Invalid packet groupings!"), + (>=) 0, + (+)) + +let part2 = + (Seq.append Packet.dividers >> Seq.sort, (fun p -> List.contains p Packet.dividers), (*)) + +let test = File.ReadLines("test.txt") +assert (solution part1 test = 13) +assert (solution part2 test = 140) + +let input = File.ReadLines("input.txt") +printfn "%d" <| solution part1 input +printfn "%d" <| solution part2 input |