Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 00e9bc4

Browse files
authored
Add recursive shuffling algorithm (#519)
1 parent 99bc144 commit 00e9bc4

File tree

3 files changed

+107
-0
lines changed

3 files changed

+107
-0
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using Algorithms.Shufflers;
2+
using Algorithms.Tests.Helpers;
3+
using FluentAssertions;
4+
using NUnit.Framework;
5+
using System;
6+
7+
namespace Algorithms.Tests.Shufflers
8+
{
9+
public static class RecursiveShufflerTests
10+
{
11+
[Test]
12+
public static void ArrayShuffled_NewArraySameSize(
13+
[Random(10, 1000, 100, Distinct = true)]
14+
int n)
15+
{
16+
// Arrange
17+
var shuffler = new RecursiveShuffler<int>();
18+
var (correctArray, testArray) = RandomHelper.GetArrays(n);
19+
20+
// Act
21+
shuffler.Shuffle(testArray);
22+
23+
// Assert
24+
testArray.Length.Should().Be(correctArray.Length);
25+
}
26+
27+
[Test]
28+
public static void ArrayShuffled_NewArraySameValues(
29+
[Random(10, 1000, 100, Distinct = true)]
30+
int n)
31+
{
32+
// Arrange
33+
var shuffler = new RecursiveShuffler<int>();
34+
var (correctArray, testArray) = RandomHelper.GetArrays(n);
35+
36+
// Act
37+
shuffler.Shuffle(testArray);
38+
39+
// Assert
40+
testArray.Should().BeEquivalentTo(correctArray);
41+
}
42+
43+
[Test]
44+
public static void ArrayShuffled_NewArraySameShuffle(
45+
[Random(0, 1000, 2, Distinct = true)] int n,
46+
[Random(1000, 10000, 5, Distinct = true)] int seed)
47+
{
48+
// Arrange
49+
var shuffler = new RecursiveShuffler<int>();
50+
var (correctArray, testArray) = RandomHelper.GetArrays(n);
51+
52+
// Act
53+
shuffler.Shuffle(testArray, seed);
54+
shuffler.Shuffle(correctArray, seed);
55+
56+
// Assert
57+
correctArray.Should().BeEquivalentTo(testArray, options => options.WithStrictOrdering());
58+
}
59+
}
60+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System;
2+
3+
namespace Algorithms.Shufflers
4+
{
5+
/// <summary>
6+
/// Recursive Shuffler is a recursive version of
7+
/// Fisher-Yates shuffle algorithm. This can only be used
8+
/// for educational purposes due to stack depth limits.
9+
/// </summary>
10+
/// <typeparam name="T">Type array input.</typeparam>
11+
public class RecursiveShuffler<T> : IShuffler<T>
12+
{
13+
/// <summary>
14+
/// This is the public overload method that calls the private overload method.
15+
/// </summary>
16+
/// <param name="array">Array to shuffle.</param>
17+
/// <param name="seed">Random generator seed. Used to repeat the shuffle.</param>
18+
public void Shuffle(T[] array, int? seed = null)
19+
{
20+
Shuffle(array, array.Length - 1, seed);
21+
}
22+
23+
/// <summary>
24+
/// First, it will check the length of the array on the base case.
25+
/// Next, if there's still items left, it will shuffle the sub-array.
26+
/// Lastly, it will randomly select index from 0 to number of items of the array
27+
/// then swap the elements array[items] and array[index].
28+
/// </summary>
29+
/// <param name="array">Array to shuffle.</param>
30+
/// <param name="items">Number of items in the array.</param>
31+
/// <param name="seed">Random generator seed. Used to repeat the shuffle.</param>
32+
private void Shuffle(T[] array, int items, int? seed)
33+
{
34+
if (items <= 0)
35+
{
36+
return;
37+
}
38+
39+
Shuffle(array, items - 1, seed);
40+
var random = seed is null ? new Random() : new Random(seed.Value);
41+
int index = random.Next(items + 1);
42+
(array[items], array[index]) = (array[index], array[items]);
43+
(array[items], array[index]) = (array[index], array[items]);
44+
}
45+
}
46+
}

‎README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ find more than one implementation for the same objective but using different alg
150150
* [Fisher-Yates Shuffler](./Algorithms/Shufflers/FisherYatesShuffler.cs)
151151
* [LINQ Shuffler](./Algorithms/Shufflers/LinqShuffler.cs)
152152
* [Naive Shuffler](./Algorithms/Shufflers/NaiveShuffler.cs)
153+
* [Recursive Shuffler](./Algorithms/Shufflers/RecursiveShuffler.cs)
153154
* [Sequences](./Algorithms/Sequences)
154155
* [A000002 Kolakoski](./Algorithms/Sequences/KolakoskiSequence.cs)
155156
* [A000004 Zero](./Algorithms/Sequences/ZeroSequence.cs)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /