Skip to content

Commit

Permalink
Merge pull request #33 from naminodarie/feature/next_permutation
Browse files Browse the repository at this point in the history
NextPermutationの仕様を変更
  • Loading branch information
kzrnm authored Oct 8, 2020
2 parents d12ebe3 + eab3c34 commit 08aba17
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 19 deletions.
14 changes: 3 additions & 11 deletions AtCoderLibrary.Test/Math/MathLibTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,7 @@ public void CRTBound()
}
}

var factorInf = new long[] { 49, 73, 127, 337, 92737, 649657 };
do
foreach (var factorInf in StlFunction.NextPermutation(new long[] { 49, 73, 127, 337, 92737, 649657 }))
{
foreach (long ans in pred)
{
Expand All @@ -200,10 +199,9 @@ public void CRTBound()
var res = MathLib.CRT(r.ToArray(), m.ToArray());
res.Should().Be((ans % INF, INF));
}
} while (NextPermutation(factorInf));
}

var factorInfn1 = new long[] { 2, 3, 715827883, 2147483647 };
do
foreach (var factorInfn1 in StlFunction.NextPermutation(new long[] { 2, 3, 715827883, 2147483647 }))
{
foreach (long ans in pred)
{
Expand All @@ -217,12 +215,6 @@ public void CRTBound()
var res = MathLib.CRT(r.ToArray(), m.ToArray());
res.Should().Be((ans % (INF - 1), INF - 1));
}
} while (NextPermutation(factorInfn1));

static bool NextPermutation(long[] arr)
{
Skip.If(true, "NextPermutation is not implemented.");
throw new Exception(arr.ToString());
}
}
}
Expand Down
43 changes: 35 additions & 8 deletions AtCoderLibrary/STL/StlFunction.cs
Original file line number Diff line number Diff line change
@@ -1,32 +1,59 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace AtCoder
{
public static class StlFunction
{
/// <summary>
/// 辞書順によるその次の順列を生成します。返すインスタンスは共通です。
/// </summary>
public static IEnumerable<T[]> NextPermutation<T>(IEnumerable<T> orig) where T : IComparable<T>
public struct NextPermutationEnumerator<T> : IEnumerator<T[]>, IEnumerable<T[]> where T : IComparable<T>
{
var arr = orig.ToArray();
while (true)
private readonly IEnumerable<T> _orig;
internal NextPermutationEnumerator(IEnumerable<T> orig)
{
_orig = orig;
Current = null;
}

public T[] Current { get; private set; }

public bool MoveNext()
{
yield return arr;
if (Current == null)
{
Current = _orig.ToArray();
return true;
}

var arr = Current;

int i;
for (i = arr.Length - 2; i >= 0; i--)
if (arr[i].CompareTo(arr[i + 1]) < 0)
break;
if (i < 0) break;
if (i < 0)
return false;
int j;
for (j = arr.Length - 1; j >= 0; j--)
if (arr[i].CompareTo(arr[j]) < 0)
break;
(arr[i], arr[j]) = (arr[j], arr[i]);
Array.Reverse(arr, i + 1, arr.Length - i - 1);
return true;
}
public void Reset() => Current = null;
object IEnumerator.Current => Current;
void IDisposable.Dispose() { }
public NextPermutationEnumerator<T> GetEnumerator() => this;
IEnumerator<T[]> IEnumerable<T[]>.GetEnumerator() => this;
IEnumerator IEnumerable.GetEnumerator() => this;
}

/// <summary>
/// 辞書順によるその次の順列を生成します。返すインスタンスは共通です。
/// </summary>
public static NextPermutationEnumerator<T> NextPermutation<T>(IEnumerable<T> orig) where T : IComparable<T>
=> new NextPermutationEnumerator<T>(orig);
}
}

0 comments on commit 08aba17

Please sign in to comment.