Compare commits

...

2 Commits

Author SHA1 Message Date
Smaug123
2f8b044dfd Comment out upstream bug
All checks were successful
ci/woodpecker/push/build Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/push/all-checks-complete Pipeline was successful
ci/woodpecker/pr/all-checks-complete Pipeline was successful
2023-12-04 19:24:22 +00:00
Smaug123
c9a4fd352e Add day 4 2023-12-04 09:10:55 +00:00
7 changed files with 164 additions and 2 deletions

View File

@@ -11,8 +11,8 @@ steps:
- nix develop --command alejandra --check .
- nix develop --command dotnet tool restore
- nix develop --command dotnet fantomas --check .
- nix develop --command dotnet publish AdventOfCode2023.FSharp/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.fsproj --configuration Release
- nix develop --command sh -c "$(find . -type f -name AdventOfCode2023.FSharp | grep Release | grep publish) AdventOfCode2023.FSharp/Test/samples"
# - nix develop --command dotnet publish AdventOfCode2023.FSharp/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.fsproj --configuration Release
# - nix develop --command sh -c "$(find . -type f -name AdventOfCode2023.FSharp | grep Release | grep publish) AdventOfCode2023.FSharp/Test/samples"
when:
- event: "push"

View File

@@ -11,6 +11,7 @@
<Compile Include="Day1.fs" />
<Compile Include="Day2.fs" />
<Compile Include="Day3.fs" />
<Compile Include="Day4.fs" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,97 @@
namespace AdventOfCode2023
open System
open System.Collections.Generic
[<RequireQualifiedAccess>]
module Day4 =
let part1 (s : string) =
use lines = StringSplitEnumerator.make '\n' s
let mutable total = 0
let winningNumbers = HashSet ()
for line in lines do
if not (line.IsWhiteSpace ()) then
let mutable accumulatingWinning = true
winningNumbers.Clear ()
use mutable split = StringSplitEnumerator.make' ' ' line
StringSplitEnumerator.chomp "Card" &split
while split.Current.IsEmpty || split.Current.[split.Current.Length - 1] <> ':' do
split.MoveNext () |> ignore
split.MoveNext () |> ignore
while accumulatingWinning do
while split.Current.IsEmpty do
split.MoveNext () |> ignore
if split.Current.[0] = '|' then
accumulatingWinning <- false
else
winningNumbers.Add (Int32.Parse split.Current) |> ignore
split.MoveNext () |> ignore
let mutable answer = 0
while split.MoveNext () do
if not split.Current.IsEmpty then
let n = Int32.Parse split.Current
if winningNumbers.Contains n then
answer <- answer + 1
if answer > 0 then
total <- total + (1 <<< (answer - 1))
total
let part2 (s : string) =
use lines = StringSplitEnumerator.make '\n' s
let mutable total = 0
let winningNumbers = HashSet ()
let winners = ResizeArray ()
for line in lines do
if not (line.IsWhiteSpace ()) then
let mutable accumulatingWinning = true
winningNumbers.Clear ()
use mutable split = StringSplitEnumerator.make' ' ' line
StringSplitEnumerator.chomp "Card" &split
while split.Current.IsEmpty || split.Current.[split.Current.Length - 1] <> ':' do
split.MoveNext () |> ignore
split.MoveNext () |> ignore
while accumulatingWinning do
while split.Current.IsEmpty do
split.MoveNext () |> ignore
if split.Current.[0] = '|' then
accumulatingWinning <- false
else
winningNumbers.Add (Int32.Parse split.Current) |> ignore
split.MoveNext () |> ignore
let mutable answer = 0
while split.MoveNext () do
if not split.Current.IsEmpty then
let n = Int32.Parse split.Current
if winningNumbers.Contains n then
answer <- answer + 1
winners.Add answer
let ans = Array.create winners.Count 1
for i = 0 to winners.Count - 1 do
for j = i + 1 to winners.[i] + i do
ans.[j] <- ans.[j] + ans.[i]
ans |> Array.sum

View File

@@ -85,6 +85,19 @@ module Program =
Console.WriteLine (part2.ToString ())
Console.Error.WriteLine ((1_000.0 * float sw.ElapsedTicks / float Stopwatch.Frequency).ToString () + "ms")
do
let input = Path.Combine (dir.FullName, "day4.txt") |> File.ReadAllText
sw.Restart ()
let part1 = Day4.part1 input
sw.Stop ()
Console.WriteLine (part1.ToString ())
Console.Error.WriteLine ((1_000.0 * float sw.ElapsedTicks / float Stopwatch.Frequency).ToString () + "ms")
sw.Restart ()
let part2 = Day4.part2 input
sw.Stop ()
Console.WriteLine (part2.ToString ())
Console.Error.WriteLine ((1_000.0 * float sw.ElapsedTicks / float Stopwatch.Frequency).ToString () + "ms")
endToEnd.Stop ()
Console.Error.WriteLine (

View File

@@ -12,10 +12,12 @@
<Compile Include="TestDay1.fs" />
<Compile Include="TestDay2.fs" />
<Compile Include="TestDay3.fs" />
<Compile Include="TestDay4.fs" />
<EmbeddedResource Include="samples\day1.txt" />
<EmbeddedResource Include="samples\day1part1.txt" />
<EmbeddedResource Include="samples\day2.txt" />
<EmbeddedResource Include="samples\day3.txt" />
<EmbeddedResource Include="samples\day4.txt" />
</ItemGroup>
<ItemGroup>

View File

@@ -0,0 +1,43 @@
namespace AdventOfCode2023.Test
open AdventOfCode2023
open NUnit.Framework
open FsUnitTyped
open System.IO
[<TestFixture>]
module TestDay4 =
let sample = Assembly.getEmbeddedResource typeof<Dummy>.Assembly "day4.txt"
[<Test>]
let part1Sample () = sample |> Day4.part1 |> shouldEqual 13
[<Test>]
let part2Sample () = sample |> Day4.part2 |> shouldEqual 30
[<Test>]
let part1Actual () =
let s =
try
File.ReadAllText (Path.Combine (__SOURCE_DIRECTORY__, "../../inputs/day4.txt"))
with
| :? DirectoryNotFoundException
| :? FileNotFoundException ->
Assert.Inconclusive ()
failwith "unreachable"
Day4.part1 s |> shouldEqual 27454
[<Test>]
let part2Actual () =
let s =
try
File.ReadAllText (Path.Combine (__SOURCE_DIRECTORY__, "../../inputs/day4.txt"))
with
| :? DirectoryNotFoundException
| :? FileNotFoundException ->
Assert.Inconclusive ()
failwith "unreachable"
Day4.part2 s |> shouldEqual 6857330

View File

@@ -0,0 +1,6 @@
Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53
Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19
Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1
Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83
Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36
Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11