diff --git a/CHANGELOG.md b/CHANGELOG.md index b4e3289..2417423 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] +### Changed +- Fix empty `Deque.GetEnumerator()` + ## [3.1.0] - 2023-09-24 ### Added - Add IModInt interface diff --git a/Source/ac-library-csharp/STL/Deque.cs b/Source/ac-library-csharp/STL/Deque.cs index 30ead34..e7848d3 100644 --- a/Source/ac-library-csharp/STL/Deque.cs +++ b/Source/ac-library-csharp/STL/Deque.cs @@ -143,7 +143,11 @@ public Enumerator(Deque deque, bool isReverse) { this.deque = deque; this.isReverse = isReverse; - if (isReverse) + if (deque.head == deque.tail) + { + index = last = 0; + } + else if (isReverse) { index = deque.tail; last = deque.head; diff --git a/Test/ac-library-csharp.Test/STL/DequeTest.cs b/Test/ac-library-csharp.Test/STL/DequeTest.cs index 79beeee..585fb5f 100644 --- a/Test/ac-library-csharp.Test/STL/DequeTest.cs +++ b/Test/ac-library-csharp.Test/STL/DequeTest.cs @@ -3,12 +3,106 @@ using System.Linq; using AtCoder.Internal; using FluentAssertions; +using MersenneTwister; using Xunit; namespace AtCoder { public class DequeTest { + [Fact] + public void Empty() + { + Impl(new Deque()); + for (int capacity = 0; capacity < 10; capacity++) + { + Impl(new Deque(capacity)); + + var deque = new Deque(capacity); + deque.AddFirst(0); + deque.PopLast(); + Impl(new Deque(capacity)); + } + + static void Impl(Deque deque) + { + deque.GetEnumerator().MoveNext().Should().BeFalse(); + deque.Count.Should().Be(0); + deque.Should().BeEmpty(); + deque.Should().Equal(Array.Empty()); + } + } + + [Fact] + public void Lengths() + { + for (int size = 1; size < 10; size++) + { + var orig = Enumerable.Range(1, size).ToArray(); + var deque = new Deque(); + foreach (var num in orig) + deque.AddLast(num); + deque.Count.Should().Be(size); + deque.Should().Equal(orig); + } + } + + [Fact] + public void Random() + { + var mt = MTRandom.Create(); + var deque = new Deque(); + var list = new LinkedList(); + + void AddFirst(int num) + { + deque.AddFirst(num); + list.AddFirst(num); + } + + void AddLast(int num) + { + deque.AddLast(num); + list.AddLast(num); + } + void PopFirst() + { + deque.PopFirst(); + list.RemoveFirst(); + } + + void PopLast() + { + deque.PopLast(); + list.RemoveLast(); + } + + + for (int q = 0; q < 10000; q++) + { + var type = mt.Next(4); + if (deque.Count == 0) type %= 2; + + switch (type) + { + case 0: + AddFirst(mt.Next()); + break; + case 1: + AddLast(mt.Next()); + break; + case 2: + PopFirst(); + break; + case 3: + PopLast(); + break; + } + + deque.Should().Equal(list); + } + } + [Fact] public void Simple() {