mirror of
https://github.com/Smaug123/AdventOfCode2022
synced 2025-10-07 02:28:40 +00:00
Day 11 (#14)
This commit is contained in:
12
.github/workflows/dotnet.yaml
vendored
12
.github/workflows/dotnet.yaml
vendored
@@ -13,6 +13,12 @@ env:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
config:
|
||||||
|
- Release
|
||||||
|
- Debug
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@@ -24,11 +30,11 @@ jobs:
|
|||||||
- name: Restore dependencies
|
- name: Restore dependencies
|
||||||
run: dotnet restore
|
run: dotnet restore
|
||||||
- name: Build
|
- name: Build
|
||||||
run: dotnet build --no-restore
|
run: dotnet build --no-restore --configuration ${{matrix.config}}
|
||||||
- name: Test
|
- name: Test
|
||||||
run: dotnet test --no-build --verbosity normal
|
run: dotnet test --no-build --verbosity normal --configuration ${{matrix.config}}
|
||||||
- name: Run app
|
- name: Run app
|
||||||
run: dotnet run --project AdventOfCode2022.App/AdventOfCode2022.App.fsproj --no-build
|
run: dotnet run --project AdventOfCode2022.App/AdventOfCode2022.App.fsproj --no-build --configuration ${{matrix.config}}
|
||||||
|
|
||||||
check-format:
|
check-format:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
<EmbeddedResource Include="..\AdventOfCode2022.Test\Inputs\Day8.txt" />
|
<EmbeddedResource Include="..\AdventOfCode2022.Test\Inputs\Day8.txt" />
|
||||||
<EmbeddedResource Include="..\AdventOfCode2022.Test\Inputs\Day9.txt" />
|
<EmbeddedResource Include="..\AdventOfCode2022.Test\Inputs\Day9.txt" />
|
||||||
<EmbeddedResource Include="..\AdventOfCode2022.Test\Inputs\Day10.txt" />
|
<EmbeddedResource Include="..\AdventOfCode2022.Test\Inputs\Day10.txt" />
|
||||||
|
<EmbeddedResource Include="..\AdventOfCode2022.Test\Inputs\Day11.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@@ -20,7 +20,7 @@ module Program =
|
|||||||
|
|
||||||
[<EntryPoint>]
|
[<EntryPoint>]
|
||||||
let main _ =
|
let main _ =
|
||||||
let days = Array.init 10 (fun day -> readResource $"Day%i{day + 1}.txt")
|
let days = Array.init 11 (fun day -> readResource $"Day%i{day + 1}.txt")
|
||||||
|
|
||||||
let inline day (i : int) = days.[i - 1]
|
let inline day (i : int) = days.[i - 1]
|
||||||
|
|
||||||
@@ -73,12 +73,16 @@ module Program =
|
|||||||
printfn "%i" (Day9.part1 day9)
|
printfn "%i" (Day9.part1 day9)
|
||||||
printfn "%i" (Day9.part2 day9)
|
printfn "%i" (Day9.part2 day9)
|
||||||
|
|
||||||
|
|
||||||
do
|
do
|
||||||
let day10 = StringSplitEnumerator.make '\n' (day 10)
|
let day10 = StringSplitEnumerator.make '\n' (day 10)
|
||||||
printfn "%i" (Day10.part1 day10)
|
printfn "%i" (Day10.part1 day10)
|
||||||
Day10.render (printfn "%s") (Day10.part2 day10)
|
Day10.render (printfn "%s") (Day10.part2 day10)
|
||||||
|
|
||||||
|
do
|
||||||
|
let day11 = StringSplitEnumerator.make '\n' (day 11)
|
||||||
|
printfn "%i" (Day11.part1 day11)
|
||||||
|
printfn "%i" (Day11.part2 day11)
|
||||||
|
|
||||||
time.Stop ()
|
time.Stop ()
|
||||||
printfn $"Took %i{time.ElapsedMilliseconds}ms"
|
printfn $"Took %i{time.ElapsedMilliseconds}ms"
|
||||||
0
|
0
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
<Compile Include="Day8.fs" />
|
<Compile Include="Day8.fs" />
|
||||||
<Compile Include="Day9.fs" />
|
<Compile Include="Day9.fs" />
|
||||||
<Compile Include="Day10.fs" />
|
<Compile Include="Day10.fs" />
|
||||||
|
<Compile Include="Day11.fs" />
|
||||||
<EmbeddedResource Include="Inputs\Day1.txt" />
|
<EmbeddedResource Include="Inputs\Day1.txt" />
|
||||||
<EmbeddedResource Include="Inputs\Day2.txt" />
|
<EmbeddedResource Include="Inputs\Day2.txt" />
|
||||||
<EmbeddedResource Include="Inputs\Day3.txt" />
|
<EmbeddedResource Include="Inputs\Day3.txt" />
|
||||||
@@ -28,6 +29,7 @@
|
|||||||
<EmbeddedResource Include="Inputs\Day8.txt" />
|
<EmbeddedResource Include="Inputs\Day8.txt" />
|
||||||
<EmbeddedResource Include="Inputs\Day9.txt" />
|
<EmbeddedResource Include="Inputs\Day9.txt" />
|
||||||
<EmbeddedResource Include="Inputs\Day10.txt" />
|
<EmbeddedResource Include="Inputs\Day10.txt" />
|
||||||
|
<EmbeddedResource Include="Inputs\Day11.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
67
AdventOfCode2022.Test/Day11.fs
Normal file
67
AdventOfCode2022.Test/Day11.fs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
namespace AdventOfCode2022.Test
|
||||||
|
|
||||||
|
open NUnit.Framework
|
||||||
|
open FsUnitTyped
|
||||||
|
open AdventOfCode2022
|
||||||
|
|
||||||
|
[<TestFixture>]
|
||||||
|
module TestDay11 =
|
||||||
|
|
||||||
|
let input =
|
||||||
|
"""Monkey 0:
|
||||||
|
Starting items: 79, 98
|
||||||
|
Operation: new = old * 19
|
||||||
|
Test: divisible by 23
|
||||||
|
If true: throw to monkey 2
|
||||||
|
If false: throw to monkey 3
|
||||||
|
|
||||||
|
Monkey 1:
|
||||||
|
Starting items: 54, 65, 75, 74
|
||||||
|
Operation: new = old + 6
|
||||||
|
Test: divisible by 19
|
||||||
|
If true: throw to monkey 2
|
||||||
|
If false: throw to monkey 0
|
||||||
|
|
||||||
|
Monkey 2:
|
||||||
|
Starting items: 79, 60, 97
|
||||||
|
Operation: new = old * old
|
||||||
|
Test: divisible by 13
|
||||||
|
If true: throw to monkey 1
|
||||||
|
If false: throw to monkey 3
|
||||||
|
|
||||||
|
Monkey 3:
|
||||||
|
Starting items: 74
|
||||||
|
Operation: new = old + 3
|
||||||
|
Test: divisible by 17
|
||||||
|
If true: throw to monkey 0
|
||||||
|
If false: throw to monkey 1
|
||||||
|
"""
|
||||||
|
|
||||||
|
[<Test>]
|
||||||
|
let ``Part 1, given`` () =
|
||||||
|
Day11.part1 (StringSplitEnumerator.make '\n' input) |> shouldEqual 10605
|
||||||
|
|
||||||
|
[<Test>]
|
||||||
|
let ``Part 1, single round, given`` () =
|
||||||
|
let monkeys = Day11.parse (StringSplitEnumerator.make '\n' input)
|
||||||
|
let inspections = Array.zeroCreate monkeys.Count
|
||||||
|
|
||||||
|
Day11.oneRoundDivThree monkeys inspections
|
||||||
|
|
||||||
|
inspections |> shouldEqual [| 2 ; 4 ; 3 ; 5 |]
|
||||||
|
|
||||||
|
[<Test>]
|
||||||
|
let ``Part 1`` () =
|
||||||
|
let input = Assembly.readResource "Day11.txt"
|
||||||
|
|
||||||
|
Day11.part1 (StringSplitEnumerator.make '\n' input) |> shouldEqual 120384
|
||||||
|
|
||||||
|
|
||||||
|
[<Test>]
|
||||||
|
let ``Part 2, given 1`` () =
|
||||||
|
Day11.part2 (StringSplitEnumerator.make '\n' input) |> shouldEqual 2713310158L
|
||||||
|
|
||||||
|
[<Test>]
|
||||||
|
let ``Part 2`` () =
|
||||||
|
let input = Assembly.readResource "Day11.txt"
|
||||||
|
Day11.part2 (StringSplitEnumerator.make '\n' input) |> shouldEqual 32059801242L
|
55
AdventOfCode2022.Test/Inputs/Day11.txt
Normal file
55
AdventOfCode2022.Test/Inputs/Day11.txt
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
Monkey 0:
|
||||||
|
Starting items: 99, 67, 92, 61, 83, 64, 98
|
||||||
|
Operation: new = old * 17
|
||||||
|
Test: divisible by 3
|
||||||
|
If true: throw to monkey 4
|
||||||
|
If false: throw to monkey 2
|
||||||
|
|
||||||
|
Monkey 1:
|
||||||
|
Starting items: 78, 74, 88, 89, 50
|
||||||
|
Operation: new = old * 11
|
||||||
|
Test: divisible by 5
|
||||||
|
If true: throw to monkey 3
|
||||||
|
If false: throw to monkey 5
|
||||||
|
|
||||||
|
Monkey 2:
|
||||||
|
Starting items: 98, 91
|
||||||
|
Operation: new = old + 4
|
||||||
|
Test: divisible by 2
|
||||||
|
If true: throw to monkey 6
|
||||||
|
If false: throw to monkey 4
|
||||||
|
|
||||||
|
Monkey 3:
|
||||||
|
Starting items: 59, 72, 94, 91, 79, 88, 94, 51
|
||||||
|
Operation: new = old * old
|
||||||
|
Test: divisible by 13
|
||||||
|
If true: throw to monkey 0
|
||||||
|
If false: throw to monkey 5
|
||||||
|
|
||||||
|
Monkey 4:
|
||||||
|
Starting items: 95, 72, 78
|
||||||
|
Operation: new = old + 7
|
||||||
|
Test: divisible by 11
|
||||||
|
If true: throw to monkey 7
|
||||||
|
If false: throw to monkey 6
|
||||||
|
|
||||||
|
Monkey 5:
|
||||||
|
Starting items: 76
|
||||||
|
Operation: new = old + 8
|
||||||
|
Test: divisible by 17
|
||||||
|
If true: throw to monkey 0
|
||||||
|
If false: throw to monkey 2
|
||||||
|
|
||||||
|
Monkey 6:
|
||||||
|
Starting items: 69, 60, 53, 89, 71, 88
|
||||||
|
Operation: new = old + 5
|
||||||
|
Test: divisible by 19
|
||||||
|
If true: throw to monkey 7
|
||||||
|
If false: throw to monkey 1
|
||||||
|
|
||||||
|
Monkey 7:
|
||||||
|
Starting items: 72, 54, 63, 80
|
||||||
|
Operation: new = old + 3
|
||||||
|
Test: divisible by 7
|
||||||
|
If true: throw to monkey 1
|
||||||
|
If false: throw to monkey 3
|
@@ -19,6 +19,7 @@
|
|||||||
<Compile Include="Day8.fs" />
|
<Compile Include="Day8.fs" />
|
||||||
<Compile Include="Day9.fs" />
|
<Compile Include="Day9.fs" />
|
||||||
<Compile Include="Day10.fs" />
|
<Compile Include="Day10.fs" />
|
||||||
|
<Compile Include="Day11.fs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
253
AdventOfCode2022/Day11.fs
Normal file
253
AdventOfCode2022/Day11.fs
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
namespace AdventOfCode2022
|
||||||
|
|
||||||
|
open System.Collections.Generic
|
||||||
|
open System
|
||||||
|
#if DEBUG
|
||||||
|
open Checked
|
||||||
|
#endif
|
||||||
|
|
||||||
|
[<Measure>]
|
||||||
|
type monkey
|
||||||
|
|
||||||
|
[<RequireQualifiedAccess>]
|
||||||
|
module Day11 =
|
||||||
|
|
||||||
|
type Monkey =
|
||||||
|
{
|
||||||
|
Number : int<monkey>
|
||||||
|
StartingItems : int64 ResizeArray
|
||||||
|
OperationIsPlus : bool
|
||||||
|
Argument : int64 option
|
||||||
|
TestDivisibleBy : int64
|
||||||
|
TrueCase : int<monkey>
|
||||||
|
FalseCase : int<monkey>
|
||||||
|
}
|
||||||
|
|
||||||
|
let parse (lines : StringSplitEnumerator) : Monkey IReadOnlyList =
|
||||||
|
use mutable enum = lines
|
||||||
|
let output = ResizeArray ()
|
||||||
|
|
||||||
|
while enum.MoveNext () do
|
||||||
|
let monkey =
|
||||||
|
let line = enum.Current.TrimEnd ()
|
||||||
|
let mutable enum = StringSplitEnumerator.make' ' ' (line.TrimEnd ':')
|
||||||
|
StringSplitEnumerator.chomp "Monkey" &enum
|
||||||
|
let monkey = StringSplitEnumerator.consumeInt &enum * 1<monkey>
|
||||||
|
|
||||||
|
if enum.MoveNext () then
|
||||||
|
failwith "Bad Monkey row"
|
||||||
|
|
||||||
|
monkey
|
||||||
|
|
||||||
|
if not (enum.MoveNext ()) then
|
||||||
|
failwith "Ran out of rows"
|
||||||
|
|
||||||
|
let line = enum.Current
|
||||||
|
|
||||||
|
let startItems =
|
||||||
|
let line = line.Trim ()
|
||||||
|
let mutable enum = StringSplitEnumerator.make' ' ' line
|
||||||
|
StringSplitEnumerator.chomp "Starting" &enum
|
||||||
|
StringSplitEnumerator.chomp "items:" &enum
|
||||||
|
let items = ResizeArray ()
|
||||||
|
|
||||||
|
while enum.MoveNext () do
|
||||||
|
let s = enum.Current.TrimEnd ','
|
||||||
|
items.Add (Int64.Parse s)
|
||||||
|
|
||||||
|
items
|
||||||
|
|
||||||
|
if not (enum.MoveNext ()) then
|
||||||
|
failwith "Ran out of rows"
|
||||||
|
|
||||||
|
let line = enum.Current
|
||||||
|
|
||||||
|
let operationIsPlus, arg =
|
||||||
|
let line = line.Trim ()
|
||||||
|
let mutable enum = StringSplitEnumerator.make' ':' line
|
||||||
|
StringSplitEnumerator.chomp "Operation" &enum
|
||||||
|
|
||||||
|
if not (enum.MoveNext ()) then
|
||||||
|
failwith "expected an operation"
|
||||||
|
|
||||||
|
let line = enum.Current.Trim ()
|
||||||
|
|
||||||
|
if enum.MoveNext () then
|
||||||
|
failwith "bad formatting on operation"
|
||||||
|
|
||||||
|
let mutable enum = StringSplitEnumerator.make' '=' line
|
||||||
|
StringSplitEnumerator.chomp "new " &enum
|
||||||
|
|
||||||
|
if not (enum.MoveNext ()) then
|
||||||
|
failwith "expected an RHS"
|
||||||
|
|
||||||
|
let rhs = enum.Current.Trim ()
|
||||||
|
|
||||||
|
if enum.MoveNext () then
|
||||||
|
failwith "too many equals signs"
|
||||||
|
|
||||||
|
let mutable enum = StringSplitEnumerator.make' ' ' rhs
|
||||||
|
|
||||||
|
StringSplitEnumerator.chomp "old" &enum
|
||||||
|
|
||||||
|
if not (enum.MoveNext ()) then
|
||||||
|
failwith "expected three elements on RHS"
|
||||||
|
|
||||||
|
let operationIsPlus =
|
||||||
|
if enum.Current.Length > 1 then
|
||||||
|
failwith "expected operation of exactly 1 char"
|
||||||
|
|
||||||
|
match enum.Current.[0] with
|
||||||
|
| '*' -> false
|
||||||
|
| '+' -> true
|
||||||
|
| c -> failwithf "Unrecognised op: %c" c
|
||||||
|
|
||||||
|
if not (enum.MoveNext ()) then
|
||||||
|
failwith "expected three elements on RHS"
|
||||||
|
|
||||||
|
let arg =
|
||||||
|
if EfficientString.equals "old" enum.Current then
|
||||||
|
None
|
||||||
|
else
|
||||||
|
let literal = Int64.Parse enum.Current
|
||||||
|
Some literal
|
||||||
|
|
||||||
|
if enum.MoveNext () then
|
||||||
|
failwith "too many entries on row"
|
||||||
|
|
||||||
|
operationIsPlus, arg
|
||||||
|
|
||||||
|
if not (enum.MoveNext ()) then
|
||||||
|
failwith "Ran out of rows"
|
||||||
|
|
||||||
|
let line = enum.Current.Trim ()
|
||||||
|
|
||||||
|
let test =
|
||||||
|
if not (line.StartsWith "Test: divisible by ") then
|
||||||
|
failwith "bad formatting on test line"
|
||||||
|
|
||||||
|
Int32.Parse (line.Slice 19)
|
||||||
|
|
||||||
|
if not (enum.MoveNext ()) then
|
||||||
|
failwith "Ran out of rows"
|
||||||
|
|
||||||
|
let line = enum.Current.Trim ()
|
||||||
|
|
||||||
|
let ifTrue =
|
||||||
|
if not (line.StartsWith "If true: throw to monkey ") then
|
||||||
|
failwith "bad formatting for ifTrue line"
|
||||||
|
|
||||||
|
Int32.Parse (line.Slice 24) * 1<monkey>
|
||||||
|
|
||||||
|
if not (enum.MoveNext ()) then
|
||||||
|
failwith "Ran out of rows"
|
||||||
|
|
||||||
|
let line = enum.Current.Trim ()
|
||||||
|
|
||||||
|
let ifFalse =
|
||||||
|
if not (line.StartsWith "If false: throw to monkey ") then
|
||||||
|
failwith "bad formatting for ifFalse line"
|
||||||
|
|
||||||
|
Int32.Parse (line.Slice 25) * 1<monkey>
|
||||||
|
|
||||||
|
// We may be at the end, in which case there's no empty row.
|
||||||
|
enum.MoveNext () |> ignore
|
||||||
|
|
||||||
|
if ifTrue = monkey then
|
||||||
|
failwith "assumption broken: throws to self"
|
||||||
|
|
||||||
|
if ifFalse = monkey then
|
||||||
|
failwith "assumption broken: throws to self"
|
||||||
|
|
||||||
|
{
|
||||||
|
Number = monkey
|
||||||
|
StartingItems = startItems
|
||||||
|
OperationIsPlus = operationIsPlus
|
||||||
|
Argument = arg
|
||||||
|
TestDivisibleBy = test
|
||||||
|
TrueCase = ifTrue
|
||||||
|
FalseCase = ifFalse
|
||||||
|
}
|
||||||
|
|> output.Add
|
||||||
|
|
||||||
|
output :> IReadOnlyList<_>
|
||||||
|
|
||||||
|
let oneRoundDivThree (monkeys : IReadOnlyList<Monkey>) (inspections : int64 array) =
|
||||||
|
for i in 0 .. monkeys.Count - 1 do
|
||||||
|
let monkey = monkeys.[i]
|
||||||
|
inspections.[i] <- inspections.[i] + int64 monkey.StartingItems.Count
|
||||||
|
|
||||||
|
for worry in monkey.StartingItems do
|
||||||
|
let newWorry =
|
||||||
|
let arg =
|
||||||
|
match monkey.Argument with
|
||||||
|
| None -> worry
|
||||||
|
| Some l -> l
|
||||||
|
|
||||||
|
if monkey.OperationIsPlus then worry + arg else worry * arg
|
||||||
|
|
||||||
|
let newWorry = newWorry / 3L
|
||||||
|
|
||||||
|
let target =
|
||||||
|
if newWorry % monkey.TestDivisibleBy = 0 then
|
||||||
|
monkey.TrueCase
|
||||||
|
else
|
||||||
|
monkey.FalseCase
|
||||||
|
|
||||||
|
monkeys.[target / 1<monkey>].StartingItems.Add newWorry
|
||||||
|
|
||||||
|
monkey.StartingItems.Clear ()
|
||||||
|
|
||||||
|
let part1 (lines : StringSplitEnumerator) : int64 =
|
||||||
|
let monkeys = parse lines
|
||||||
|
|
||||||
|
let mutable inspections = Array.zeroCreate<int64> monkeys.Count
|
||||||
|
|
||||||
|
for _round in 1..20 do
|
||||||
|
oneRoundDivThree monkeys inspections
|
||||||
|
|
||||||
|
inspections |> Array.sortInPlace
|
||||||
|
inspections.[inspections.Length - 1] * inspections.[inspections.Length - 2]
|
||||||
|
|
||||||
|
let oneRound (modulus : int64) (monkeys : IReadOnlyList<Monkey>) (inspections : int64 array) =
|
||||||
|
for i in 0 .. monkeys.Count - 1 do
|
||||||
|
let monkey = monkeys.[i]
|
||||||
|
inspections.[i] <- inspections.[i] + int64 monkey.StartingItems.Count
|
||||||
|
|
||||||
|
for worryIndex in 0 .. monkey.StartingItems.Count - 1 do
|
||||||
|
let worry = monkey.StartingItems.[worryIndex]
|
||||||
|
|
||||||
|
let newWorry =
|
||||||
|
let arg =
|
||||||
|
match monkey.Argument with
|
||||||
|
| None -> worry
|
||||||
|
| Some l -> l
|
||||||
|
|
||||||
|
if monkey.OperationIsPlus then worry + arg else worry * arg
|
||||||
|
|
||||||
|
let newWorry = newWorry % modulus
|
||||||
|
|
||||||
|
let target =
|
||||||
|
if newWorry % monkey.TestDivisibleBy = 0 then
|
||||||
|
monkey.TrueCase
|
||||||
|
else
|
||||||
|
monkey.FalseCase
|
||||||
|
|
||||||
|
monkeys.[target / 1<monkey>].StartingItems.Add newWorry
|
||||||
|
|
||||||
|
monkey.StartingItems.Clear ()
|
||||||
|
|
||||||
|
|
||||||
|
let part2 (lines : StringSplitEnumerator) : int64 =
|
||||||
|
let monkeys = parse lines
|
||||||
|
|
||||||
|
let mutable inspections = Array.zeroCreate<int64> monkeys.Count
|
||||||
|
|
||||||
|
let modulus =
|
||||||
|
(1L, monkeys) ||> Seq.fold (fun i monkey -> i * monkey.TestDivisibleBy)
|
||||||
|
|
||||||
|
for _round in 1..10000 do
|
||||||
|
oneRound modulus monkeys inspections
|
||||||
|
|
||||||
|
inspections |> Array.sortInPlace
|
||||||
|
inspections.[inspections.Length - 1] * inspections.[inspections.Length - 2]
|
@@ -83,7 +83,7 @@ module StringSplitEnumerator =
|
|||||||
|
|
||||||
let chomp (s : string) (e : byref<StringSplitEnumerator>) =
|
let chomp (s : string) (e : byref<StringSplitEnumerator>) =
|
||||||
if not (e.MoveNext ()) || not (EfficientString.equals s e.Current) then
|
if not (e.MoveNext ()) || not (EfficientString.equals s e.Current) then
|
||||||
failwithf "expected '%s'" s
|
failwithf "expected '%s', got '%s'" s (e.Current.ToString ())
|
||||||
|
|
||||||
let consumeInt (e : byref<StringSplitEnumerator>) : int =
|
let consumeInt (e : byref<StringSplitEnumerator>) : int =
|
||||||
if not (e.MoveNext ()) then
|
if not (e.MoveNext ()) then
|
||||||
|
Reference in New Issue
Block a user