Skip to content

Instantly share code, notes, and snippets.

@satish860
Created August 21, 2012 17:30
Show Gist options
  • Save satish860/3417563 to your computer and use it in GitHub Desktop.
Save satish860/3417563 to your computer and use it in GitHub Desktop.
3n+1 Sequence
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SequenceGenerator
{
public class SequenceGenerator
{
IDictionary<Predicate<int>, Func<int, int, Tuple<int, int>>> compositeDictionary;
public SequenceGenerator()
{
compositeDictionary = new Dictionary<Predicate<int>, Func<int, int, Tuple<int, int>>>();
compositeDictionary.Add((number) => (number % 2 == 0), ApplyEvenRule);
compositeDictionary.Add((number) => (number % 2 != 0), ApplyOddRule);
}
public int Generate(int start, int end)
{
int max = 0;
Enumerable.Range(start, end).ToList().ForEach(p =>
{
var generatedSequence = GenerateSequenceFor(p);
if (max < generatedSequence.Item2)
max = generatedSequence.Item2;
});
return max;
}
public Func<int, int, Tuple<int, int>> GetRuleFor(int number)
{
return compositeDictionary.First(p => p.Key(number)).Value;
}
public Tuple<int, int> ApplyEvenRule(int number, int seriesCount = 0)
{
return Tuple.Create<int, int>(number / 2, seriesCount + 1);
}
public Tuple<int, int> ApplyOddRule(int number, int seriesCount = 0)
{
return Tuple.Create<int, int>((3 * number) + 1, seriesCount + 1);
}
public Tuple<IList<int>, int> GenerateSequenceFor(int number, int count = 1, IList<int> sequence = default(IList<int>))
{
if (sequence == null)
{
sequence = new List<int>();
sequence.Add(number);
}
if (number == 1)
{
if (sequence.Contains(1))
sequence.Add(1);
return Tuple.Create<IList<int>, int>(sequence, count);
}
var nextGeneratedNumber = compositeDictionary.First(p => p.Key(number)).Value(number, count);
sequence.Add(nextGeneratedNumber.Item1);
return GenerateSequenceFor(nextGeneratedNumber.Item1, nextGeneratedNumber.Item2, sequence);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using FluentAssertions;
namespace SequenceGenerator.Test
{
[TestFixture]
public class SequenceGenearatorTest
{
[Test]
public void Should_be_able_to_divide_the_number_by_2()
{
int number = 20;
SequenceGenerator generator = new SequenceGenerator();
Tuple<int, int> generartedNumber = generator.ApplyEvenRule(number);
generartedNumber.Item1.Should().Be(10);
generartedNumber.Item2.Should().Be(1);
}
[Test]
public void Should_be_able_Apply_if_3n_1_rule()
{
int number = 7;
SequenceGenerator generator = new SequenceGenerator();
Tuple<int, int> generartedNumber = generator.ApplyOddRule(number);
generartedNumber.Item1.Should().Be(22);
generartedNumber.Item2.Should().Be(1);
}
[Test]
public void Should_Apply_Even_Rule_only_if_its_a_even_Number()
{
int number = 20;
SequenceGenerator generator = new SequenceGenerator();
Tuple<int, int> generartedNumber = generator.GetRuleFor(number)(number, 0);
generartedNumber.Item1.Should().Be(10);
generartedNumber.Item2.Should().Be(1);
number = 7;
generartedNumber = generator.GetRuleFor(number)(number, 0);
generartedNumber.Item1.Should().Be(22);
generartedNumber.Item2.Should().Be(1);
}
[Test]
public void Should_Generate_the_Sequence_for_the_Number_and_the_Count_of_the_Sequence()
{
int number = 22;
SequenceGenerator generator = new SequenceGenerator();
Tuple<IList<int>,int> sequence=generator.GenerateSequenceFor(number);
sequence.Item2.Should().Be(16);
}
[Test]
public void Should_be_able_to_Generated_the_Sequence_Between_the_range_and_the_Maximum_Count()
{
SequenceGenerator generator = new SequenceGenerator();
int value=generator.Generate(1, 10);
value.Should().Be(20);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment