aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--aoc-2022-dotnet/Common/Common.fsproj4
-rw-r--r--aoc-2022-dotnet/Common/Library.fs8
-rw-r--r--aoc-2022-dotnet/Common/Util.fs43
-rw-r--r--aoc-2022-dotnet/Common/Vec2.fs13
-rw-r--r--aoc-2022-dotnet/Day01/Day01.fsproj4
-rw-r--r--aoc-2022-dotnet/Day01/Program.fs20
-rw-r--r--aoc-2022-dotnet/Day02/Day02.fsproj4
-rw-r--r--aoc-2022-dotnet/Day02/Program.fs8
-rw-r--r--aoc-2022-dotnet/Day03/Day03.fsproj4
-rw-r--r--aoc-2022-dotnet/Day03/Program.fs7
-rw-r--r--aoc-2022-dotnet/Day04/Program.fs7
-rw-r--r--aoc-2022-dotnet/Day05/Program.fs5
-rw-r--r--aoc-2022-dotnet/Day06/Day06.fsproj4
-rw-r--r--aoc-2022-dotnet/Day06/Program.fs3
-rw-r--r--aoc-2022-dotnet/Day07/Program.fs15
-rw-r--r--aoc-2022-dotnet/Day08/Day08.fsproj4
-rw-r--r--aoc-2022-dotnet/Day08/Program.fs9
-rw-r--r--aoc-2022-dotnet/Day09/Day09.fsproj4
-rw-r--r--aoc-2022-dotnet/Day09/Program.fs28
19 files changed, 119 insertions, 75 deletions
diff --git a/aoc-2022-dotnet/Common/Common.fsproj b/aoc-2022-dotnet/Common/Common.fsproj
index c8a185a..32057cf 100644
--- a/aoc-2022-dotnet/Common/Common.fsproj
+++ b/aoc-2022-dotnet/Common/Common.fsproj
@@ -6,11 +6,13 @@
</PropertyGroup>
<ItemGroup>
- <Compile Include="Library.fs" />
+ <Compile Include="Vec2.fs" />
+ <Compile Include="Util.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="FParsec" Version="1.1.1" />
+ <PackageReference Include="FSharpPlus" Version="1.3.2" />
</ItemGroup>
</Project>
diff --git a/aoc-2022-dotnet/Common/Library.fs b/aoc-2022-dotnet/Common/Library.fs
deleted file mode 100644
index 7354509..0000000
--- a/aoc-2022-dotnet/Common/Library.fs
+++ /dev/null
@@ -1,8 +0,0 @@
-module Common
-
-open FParsec
-
-let parse parser input =
- match run parser input with
- | Success (result, _, _) -> result
- | _ -> failwith "Invalid input format!"
diff --git a/aoc-2022-dotnet/Common/Util.fs b/aoc-2022-dotnet/Common/Util.fs
new file mode 100644
index 0000000..a9f3a1e
--- /dev/null
+++ b/aoc-2022-dotnet/Common/Util.fs
@@ -0,0 +1,43 @@
+namespace Common
+
+module Util =
+ open System.Globalization
+ open FParsec
+ open FSharpPlus
+
+ let parse parser input =
+ match run parser input with
+ | Success (result, _, _) -> result
+ | _ -> failwith "Invalid input format!"
+
+ let countDistinct seq = seq |> Set |> Set.count
+
+ let countWhere pred = Seq.filter pred >> Seq.length
+
+ let charToInt = CharUnicodeInfo.GetDigitValue
+
+ let cutInHalf xs =
+ let half = Seq.length xs / 2
+ [ Seq.take half xs; Seq.skip half xs ]
+
+ let splitStringToTuple sep str =
+ match Seq.toList <| String.split [ sep ] str with
+ | [ x; y ] -> x, y
+ | _ -> failwith "Invalid string format!"
+
+ let topN n xs =
+ let rec insertSorted x =
+ function
+ | h :: t -> min h x :: (insertSorted (max h x) t)
+ | _ -> [ x ]
+
+ Seq.fold
+ (fun acc x ->
+ if List.length acc < n then
+ insertSorted x acc
+ elif List.head acc < x then
+ insertSorted x <| List.tail acc
+ else
+ acc)
+ List.empty
+ xs
diff --git a/aoc-2022-dotnet/Common/Vec2.fs b/aoc-2022-dotnet/Common/Vec2.fs
new file mode 100644
index 0000000..20b9956
--- /dev/null
+++ b/aoc-2022-dotnet/Common/Vec2.fs
@@ -0,0 +1,13 @@
+namespace Common
+
+type Vec2 =
+ | Vec2 of int * int
+
+ static member zero = Vec2(0, 0)
+
+ static member (+)(Vec2 (x1, y1), Vec2 (x2, y2)) = Vec2(x1 + x2, y1 + y2)
+ static member (-)(Vec2 (x1, y1), Vec2 (x2, y2)) = Vec2(x1 - x2, y1 - y2)
+
+ static member apply f (Vec2 (x, y)) = Vec2(f x, f y)
+ static member sign = Vec2.apply sign
+ static member chebyshevDist (Vec2 (x1, y1)) (Vec2 (x2, y2)) = max (abs <| x2 - x1) (abs <| y2 - y1)
diff --git a/aoc-2022-dotnet/Day01/Day01.fsproj b/aoc-2022-dotnet/Day01/Day01.fsproj
index 0e98abc..795d59c 100644
--- a/aoc-2022-dotnet/Day01/Day01.fsproj
+++ b/aoc-2022-dotnet/Day01/Day01.fsproj
@@ -19,4 +19,8 @@
<PackageReference Include="FSharpPlus" Version="1.3.2" />
</ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Common\Common.fsproj" />
+ </ItemGroup>
+
</Project>
diff --git a/aoc-2022-dotnet/Day01/Program.fs b/aoc-2022-dotnet/Day01/Program.fs
index 71faaae..3a06ef1 100644
--- a/aoc-2022-dotnet/Day01/Program.fs
+++ b/aoc-2022-dotnet/Day01/Program.fs
@@ -2,6 +2,7 @@
open System.IO
open FSharpPlus
+open Common
let parseLine =
function
@@ -10,27 +11,10 @@ let parseLine =
let caloriesPerElf = Seq.split [ [ -1 ] ] >> Seq.map Seq.sum
-let topN n xs =
- let rec insertSorted x =
- function
- | h :: t -> min h x :: (insertSorted (max h x) t)
- | _ -> [ x ]
-
- Seq.fold
- (fun acc x ->
- if List.length acc < n then
- insertSorted x acc
- elif List.head acc < x then
- insertSorted x <| List.tail acc
- else
- acc)
- List.empty
- xs
-
let solution n =
Seq.map parseLine
>> caloriesPerElf
- >> topN n
+ >> Util.topN n
>> List.sum
let test = File.ReadLines "test.txt"
diff --git a/aoc-2022-dotnet/Day02/Day02.fsproj b/aoc-2022-dotnet/Day02/Day02.fsproj
index 0e98abc..795d59c 100644
--- a/aoc-2022-dotnet/Day02/Day02.fsproj
+++ b/aoc-2022-dotnet/Day02/Day02.fsproj
@@ -19,4 +19,8 @@
<PackageReference Include="FSharpPlus" Version="1.3.2" />
</ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Common\Common.fsproj" />
+ </ItemGroup>
+
</Project>
diff --git a/aoc-2022-dotnet/Day02/Program.fs b/aoc-2022-dotnet/Day02/Program.fs
index 0546195..8568f9a 100644
--- a/aoc-2022-dotnet/Day02/Program.fs
+++ b/aoc-2022-dotnet/Day02/Program.fs
@@ -2,6 +2,7 @@
open System.IO
open FSharpPlus
+open Common
type Move =
| Rock
@@ -36,11 +37,6 @@ type Strategy =
| "Z" -> Z
| s -> failwithf "Invalid strategy: %s" s
-let splitToTuple sep str =
- match Seq.toList <| String.split [ sep ] str with
- | [ x; y ] -> x, y
- | _ -> failwith "Invalid string format!"
-
let scoreRound (enemy, player) =
let selectionScore =
match player with
@@ -70,7 +66,7 @@ let guide2 (enemy: Move) =
let parseRound guide roundStr =
let (enemy, strategy) =
roundStr
- |> splitToTuple " "
+ |> Util.splitStringToTuple " "
|> mapItem1 Move.parse
|> mapItem2 Strategy.parse
diff --git a/aoc-2022-dotnet/Day03/Day03.fsproj b/aoc-2022-dotnet/Day03/Day03.fsproj
index e337a41..b9a3919 100644
--- a/aoc-2022-dotnet/Day03/Day03.fsproj
+++ b/aoc-2022-dotnet/Day03/Day03.fsproj
@@ -15,4 +15,8 @@
<Compile Include="Program.fs" />
</ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Common\Common.fsproj" />
+ </ItemGroup>
+
</Project>
diff --git a/aoc-2022-dotnet/Day03/Program.fs b/aoc-2022-dotnet/Day03/Program.fs
index 153e639..512ef40 100644
--- a/aoc-2022-dotnet/Day03/Program.fs
+++ b/aoc-2022-dotnet/Day03/Program.fs
@@ -1,6 +1,7 @@
module Day03
open System.IO
+open Common
let priority item =
if 'a' <= item && item <= 'z' then
@@ -10,13 +11,9 @@ let priority item =
else
failwithf "Invalid item: %c" item
-let cutInHalf xs =
- let half = Seq.length xs / 2
- [ Seq.take half xs; Seq.skip half xs ]
-
let solution1 =
Seq.sumBy (
- cutInHalf
+ Util.cutInHalf
>> Seq.map Set
>> Set.intersectMany
>> Seq.exactlyOne
diff --git a/aoc-2022-dotnet/Day04/Program.fs b/aoc-2022-dotnet/Day04/Program.fs
index 2221a4a..7d37d3e 100644
--- a/aoc-2022-dotnet/Day04/Program.fs
+++ b/aoc-2022-dotnet/Day04/Program.fs
@@ -2,19 +2,20 @@
open System.IO
open FParsec
+open Common
let parseLine line =
let prange = pint32 .>> pstring "-" .>>. pint32
let ppair = prange .>> pstring "," .>>. prange .>> eof
- Common.parse ppair line
+ Util.parse ppair line
let fullyOverlap ((a, b), (c, d)) =
(a <= c && d <= b) || (c <= a && b <= d)
let overlapAtAll ((a, b), (c, d)) = a <= d && b >= c
-let solution pred =
- Seq.map parseLine >> Seq.filter pred >> Seq.length
+let solution predicate =
+ Seq.map parseLine >> Util.countWhere predicate
let test = File.ReadLines "test.txt"
assert (solution fullyOverlap test = 2)
diff --git a/aoc-2022-dotnet/Day05/Program.fs b/aoc-2022-dotnet/Day05/Program.fs
index f471a31..7bad269 100644
--- a/aoc-2022-dotnet/Day05/Program.fs
+++ b/aoc-2022-dotnet/Day05/Program.fs
@@ -3,6 +3,7 @@
open System
open System.IO
open FParsec
+open Common
type Move =
| Move of int * int * int
@@ -11,7 +12,7 @@ type Move =
let dec n = n - 1
let pPart str = pstring str >>. pint32
let pMove = tuple3 (pPart "move ") (pPart " from " |>> dec) (pPart " to " |>> dec)
- Common.parse pMove str |> Move
+ Util.parse pMove str |> Move
static member execute order stacks (Move (n, fi, ti)) =
List.mapi
@@ -33,7 +34,7 @@ let parseStacks str =
let pHeader = many pCrateLine
str
- |> Common.parse pHeader
+ |> Util.parse pHeader
|> List.transpose
|> List.map (List.choose id)
diff --git a/aoc-2022-dotnet/Day06/Day06.fsproj b/aoc-2022-dotnet/Day06/Day06.fsproj
index 249287d..e7e4a65 100644
--- a/aoc-2022-dotnet/Day06/Day06.fsproj
+++ b/aoc-2022-dotnet/Day06/Day06.fsproj
@@ -12,4 +12,8 @@
<Compile Include="Program.fs" />
</ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Common\Common.fsproj" />
+ </ItemGroup>
+
</Project>
diff --git a/aoc-2022-dotnet/Day06/Program.fs b/aoc-2022-dotnet/Day06/Program.fs
index c9f6568..78902cd 100644
--- a/aoc-2022-dotnet/Day06/Program.fs
+++ b/aoc-2022-dotnet/Day06/Program.fs
@@ -1,10 +1,11 @@
module Day06
open System.IO
+open Common
let solution n =
Seq.windowed n
- >> Seq.findIndex (Set >> Set.count >> (=) n)
+ >> Seq.findIndex (Util.countDistinct >> (=) n)
>> (+) n
assert
diff --git a/aoc-2022-dotnet/Day07/Program.fs b/aoc-2022-dotnet/Day07/Program.fs
index 7e16cb6..e48bb53 100644
--- a/aoc-2022-dotnet/Day07/Program.fs
+++ b/aoc-2022-dotnet/Day07/Program.fs
@@ -2,6 +2,7 @@
open System.IO
open FParsec
+open Common
let fileSizeThreshold = 100_000
let totalDiskSpace = 70_000_000
@@ -28,7 +29,7 @@ let parseCommands input =
let pcmd = pcd <|> pls
let pinput = many pcmd
- Common.parse pinput input
+ Util.parse pinput input
let combine =
function
@@ -46,11 +47,11 @@ let buildFilesystem commands =
commands |> helper [] |> Map.ofList
-let rec directorySize fileSystem path =
- fileSystem
+let rec dirSize filesystem path =
+ filesystem
|> Map.find path
|> List.sumBy (function
- | Dir dir -> directorySize fileSystem <| combine (path, dir)
+ | Dir dir -> dirSize filesystem <| combine (path, dir)
| File size -> size)
let part1 = Seq.filter ((>=) fileSizeThreshold) >> Seq.sum
@@ -62,11 +63,11 @@ let part2 sizes =
sizes |> Seq.filter ((<=) missingSpace) |> Seq.min
let solution reduceSizes input =
- let fileSystem = input |> parseCommands |> buildFilesystem
+ let filesystem = input |> parseCommands |> buildFilesystem
- fileSystem
+ filesystem
|> Map.keys
- |> Seq.map (directorySize fileSystem)
+ |> Seq.map (dirSize filesystem)
|> reduceSizes
let test = File.ReadAllText("test.txt")
diff --git a/aoc-2022-dotnet/Day08/Day08.fsproj b/aoc-2022-dotnet/Day08/Day08.fsproj
index e337a41..b9a3919 100644
--- a/aoc-2022-dotnet/Day08/Day08.fsproj
+++ b/aoc-2022-dotnet/Day08/Day08.fsproj
@@ -15,4 +15,8 @@
<Compile Include="Program.fs" />
</ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Common\Common.fsproj" />
+ </ItemGroup>
+
</Project>
diff --git a/aoc-2022-dotnet/Day08/Program.fs b/aoc-2022-dotnet/Day08/Program.fs
index 1a98c6d..23f93c0 100644
--- a/aoc-2022-dotnet/Day08/Program.fs
+++ b/aoc-2022-dotnet/Day08/Program.fs
@@ -1,11 +1,9 @@
module Day08
open System.IO
-open System.Globalization
+open Common
-let parseMatrix =
- array2D
- >> Array2D.map CharUnicodeInfo.GetDigitValue
+let parseMatrix = array2D >> Array2D.map Util.charToInt
let mapEachToSeq mapping m =
seq {
@@ -35,8 +33,7 @@ let scenicScore (m: 'a [,]) r c =
let solution1 =
parseMatrix
>> mapEachToSeq isVisible
- >> Seq.filter id
- >> Seq.length
+ >> Util.countWhere id
let solution2 = parseMatrix >> mapEachToSeq scenicScore >> Seq.max
diff --git a/aoc-2022-dotnet/Day09/Day09.fsproj b/aoc-2022-dotnet/Day09/Day09.fsproj
index e337a41..b9a3919 100644
--- a/aoc-2022-dotnet/Day09/Day09.fsproj
+++ b/aoc-2022-dotnet/Day09/Day09.fsproj
@@ -15,4 +15,8 @@
<Compile Include="Program.fs" />
</ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Common\Common.fsproj" />
+ </ItemGroup>
+
</Project>
diff --git a/aoc-2022-dotnet/Day09/Program.fs b/aoc-2022-dotnet/Day09/Program.fs
index 5f49c63..df9f040 100644
--- a/aoc-2022-dotnet/Day09/Program.fs
+++ b/aoc-2022-dotnet/Day09/Program.fs
@@ -1,16 +1,10 @@
module Day09
open System.IO
-
-type Vec2D =
- | Vec2D of int * int
- static member zero = Vec2D(0, 0)
- static member (+)(Vec2D (x1, y1), Vec2D (x2, y2)) = Vec2D(x1 + x2, y1 + y2)
- static member (-)(Vec2D (x1, y1), Vec2D (x2, y2)) = Vec2D(x1 - x2, y1 - y2)
- static member chebyshevDist (Vec2D (x1, y1)) (Vec2D (x2, y2)) = max (abs <| x2 - x1) (abs <| y2 - y1)
+open Common
let directionToVec =
- Vec2D
+ Vec2
<< function
| 'U' -> (0, 1)
| 'R' -> (1, 0)
@@ -19,28 +13,26 @@ let directionToVec =
| char -> failwithf "Invalid direction: %c" char
let parseHeadMoves =
- Seq.collect (fun (line: string) -> List.replicate (int line[2..]) (directionToVec line[0]))
+ Seq.collect (fun (line: string) -> Seq.replicate (int line[2..]) (directionToVec line[0]))
-let constrainTail head tail =
- if Vec2D.chebyshevDist head tail <= 1 then
+let moveTail head tail =
+ if Vec2.chebyshevDist head tail <= 1 then
tail
else
- let (Vec2D (dx, dy)) = head - tail
- tail + Vec2D(sign dx, sign dy)
+ tail + Vec2.sign (head - tail)
-let createRope length = List.replicate length Vec2D.zero
+let createRope length = List.replicate length Vec2.zero
let solution ropeLength =
parseHeadMoves
>> Seq.scan
- (fun rope move ->
+ (fun rope headMove ->
match rope with
- | h :: t -> List.scan constrainTail (h + move) t
+ | head :: tail -> List.scan moveTail (head + headMove) tail
| [] -> [])
(createRope ropeLength)
>> Seq.map Seq.last
- >> Set
- >> Set.count
+ >> Util.countDistinct
let test = File.ReadLines("test.txt")
assert (solution 2 test = 13)