Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,12 @@
"beer-song",
"kindergarten-garden",
"pascals-triangle",
"saddle-points"
"saddle-points",
"nth-prime",
"palindrome-products",
"binary-search-tree",
"robot-simulator",
"simple-linked-list"
],
"deprecated": [

Expand Down
85 changes: 85 additions & 0 deletions exercises/binary-search-tree/BinarySearchTreeTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using System.Linq;
using NUnit.Framework;

public class BinarySearchTreeTest
{
[Test]
public void Data_is_retained()
{
var tree = new BinarySearchTree(4);
Assert.That(tree.Value, Is.EqualTo(4));
}

[Ignore("Remove to run test")]
[Test]
public void Inserting_less()
{
var tree = new BinarySearchTree(4).Add(2);
Assert.That(tree.Value, Is.EqualTo(4));
Assert.That(tree.Left.Value, Is.EqualTo(2));
}

[Ignore("Remove to run test")]
[Test]
public void Inserting_same()
{
var tree = new BinarySearchTree(4).Add(4);
Assert.That(tree.Value, Is.EqualTo(4));
Assert.That(tree.Left.Value, Is.EqualTo(4));
}

[Ignore("Remove to run test")]
[Test]
public void Inserting_greater()
{
var tree = new BinarySearchTree(4).Add(5);
Assert.That(tree.Value, Is.EqualTo(4));
Assert.That(tree.Right.Value, Is.EqualTo(5));
}

[Ignore("Remove to run test")]
[Test]
public void Complex_tree()
{
var tree = new BinarySearchTree(new [] { 4, 2, 6, 1, 3, 7, 5 });
Assert.That(tree.Value, Is.EqualTo(4));
Assert.That(tree.Left.Value, Is.EqualTo(2));
Assert.That(tree.Left.Left.Value, Is.EqualTo(1));
Assert.That(tree.Left.Right.Value, Is.EqualTo(3));
Assert.That(tree.Right.Value, Is.EqualTo(6));
Assert.That(tree.Right.Left.Value, Is.EqualTo(5));
Assert.That(tree.Right.Right.Value, Is.EqualTo(7));
}

[Ignore("Remove to run test")]
[Test]
public void Iterating_one_element()
{
var elements = new BinarySearchTree(4);
Assert.That(elements, Is.EqualTo(new [] { 4 }));
}

[Ignore("Remove to run test")]
[Test]
public void Iterating_over_smaller_element()
{
var elements = new BinarySearchTree(new[] { 4, 2 }).AsEnumerable();
Assert.That(elements, Is.EqualTo(new[] { 2, 4 }));
}

[Ignore("Remove to run test")]
[Test]
public void Iterating_over_larger_element()
{
var elements = new BinarySearchTree(new[] { 4, 5 }).AsEnumerable();
Assert.That(elements, Is.EqualTo(new[] { 4, 5 }));
}

[Ignore("Remove to run test")]
[Test]
public void Iterating_over_complex_element()
{
var elements = new BinarySearchTree(new[] { 4, 2, 1, 3, 6, 7, 5 }).AsEnumerable();
Assert.That(elements, Is.EqualTo(new[] { 1, 2, 3, 4, 5, 6, 7 }));
}
}
79 changes: 79 additions & 0 deletions exercises/binary-search-tree/Example.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

public class BinarySearchTree : IEnumerable<int>
{
public BinarySearchTree(int value)
{
Value = value;
}

public BinarySearchTree(IEnumerable<int> values)
{
var array = values.ToArray();

if (array.Length == 0)
{
throw new ArgumentException("Cannot create tree from empty list");
}

Value = array[0];

foreach (var value in array.Skip(1))
{
Add(value);
}
}

public int Value { get; }

public BinarySearchTree Left { get; private set; }

public BinarySearchTree Right { get; private set; }

public BinarySearchTree Add(int value)
{
if (value <= Value)
{
Left = Add(value, Left);
}
else
{
Right = Add(value, Right);
}

return this;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that this is composable :-)

}

private static BinarySearchTree Add(int value, BinarySearchTree tree)
{
if (tree == null)
{
return new BinarySearchTree(value);
}

return tree.Add(value);
}

public IEnumerator<int> GetEnumerator()
{
foreach (var left in Left?.AsEnumerable() ?? Enumerable.Empty<int>())
{
yield return left;
}

yield return Value;

foreach (var right in Right?.AsEnumerable() ?? Enumerable.Empty<int>())
{
yield return right;
}
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
42 changes: 42 additions & 0 deletions exercises/nth-prime/Example.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;

public static class NthPrime
{
public static int Nth(int nth)
{
return Primes().Skip(nth - 1).First();
}

private static IEnumerable<int> Primes()
{
yield return 2;
yield return 3;

foreach (var prime in PossiblePrimes().Where(IsPrime))
{
yield return prime;
}
}

private static IEnumerable<int> PossiblePrimes()
{
var n = 6;

while (true)
{
yield return n - 1;
yield return n + 1;

n += 6;
}
}

private static bool IsPrime(int n)
{
var r = (int)Math.Floor(Math.Sqrt(n));

return r < 5 || Enumerable.Range(5, r - 4).All(x => n % x != 0);
}
}
20 changes: 20 additions & 0 deletions exercises/nth-prime/NthPrimeTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using NUnit.Framework;

public class NthPrimeTest
{
[TestCase(1, ExpectedResult = 2)]
[TestCase(2, ExpectedResult = 3, Ignore = "Remove to run test case")]
[TestCase(3, ExpectedResult = 5, Ignore = "Remove to run test case")]
[TestCase(4, ExpectedResult = 7, Ignore = "Remove to run test case")]
[TestCase(5, ExpectedResult = 11, Ignore = "Remove to run test case")]
[TestCase(6, ExpectedResult = 13, Ignore = "Remove to run test case")]
[TestCase(7, ExpectedResult = 17, Ignore = "Remove to run test case")]
[TestCase(8, ExpectedResult = 19, Ignore = "Remove to run test case")]
[TestCase(1000, ExpectedResult = 7919, Ignore = "Remove to run test case")]
[TestCase(10000, ExpectedResult = 104729, Ignore = "Remove to run test case")]
[TestCase(10001, ExpectedResult = 104743, Ignore = "Remove to run test case")]
public int Nth_prime_calculated(int nth)
{
return NthPrime.Nth(nth);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

}
}
75 changes: 75 additions & 0 deletions exercises/palindrome-products/Example.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;

public class Palindrome
{
private Palindrome(int value, ISet<Tuple<int, int>> factors)
{
Value = value;
Factors = factors;
}

public int Value { get; }

public ISet<Tuple<int, int>> Factors { get; }

public static Palindrome Largest(int maxFactor)
{
return Largest(1, maxFactor);
}

public static Palindrome Largest(int minFactor, int maxFactor)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that other language tracks allow for Largest & Smallest to take just a maxFactor and default minFactor to 1. Maybe add overloads that do that?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion.

{
return FindPalindrome(minFactor, maxFactor, x => x.Max(p => p.Item1));
}

public static Palindrome Smallest(int maxFactor)
{
return Smallest(1, maxFactor);
}

public static Palindrome Smallest(int minFactor, int maxFactor)
{
return FindPalindrome(minFactor, maxFactor, x => x.Min(p => p.Item1));
}

private static Palindrome FindPalindrome(int minFactor, int maxFactor, Func<List<Tuple<int, Tuple<int, int>>>, int> valueSelector)
{
var palindromes = FindAllPalindromes(minFactor, maxFactor);
var value = valueSelector(palindromes);
var factors = new HashSet<Tuple<int, int>>(palindromes.Where(p => p.Item1 == value).Select(p => p.Item2));

return new Palindrome(value, factors);
}

private static List<Tuple<int, Tuple<int, int>>> FindAllPalindromes(int minFactor, int maxFactor)
{
return (from pair in Pairs(minFactor, maxFactor)
let product = pair.Item1 * pair.Item2
where IsPalindrome(product)
select Tuple.Create(product, pair))
.ToList();
}

private static IEnumerable<Tuple<int, int>> Pairs(int minFactor, int maxFactor)
{
return from x in Enumerable.Range(minFactor, maxFactor + 1 - minFactor)
from y in Enumerable.Range(x, maxFactor + 1 - x)
select Tuple.Create(x, y);
}

private static bool IsPalindrome(int num)
{
var n = num;
var rev = 0;
while (num > 0)
{
var dig = num % 10;
rev = rev * 10 + dig;
num = num / 10;
}

return n == rev;
}
}
Loading