diff --git a/config.json b/config.json index 70bf998150..25fd5401a1 100644 --- a/config.json +++ b/config.json @@ -47,7 +47,11 @@ "tournament", "acronym", "hexadecimal", - "largest-series-product" + "largest-series-product", + "beer-song", + "kindergarten-garden", + "pascals-triangle", + "saddle-points" ], "deprecated": [ diff --git a/exercises/beer-song/BeerTests.cs b/exercises/beer-song/BeerTests.cs new file mode 100644 index 0000000000..d66f4c51b7 --- /dev/null +++ b/exercises/beer-song/BeerTests.cs @@ -0,0 +1,20 @@ +using NUnit.Framework; + +public class BeerTests +{ + [TestCase(8, ExpectedResult = "8 bottles of beer on the wall, 8 bottles of beer.\nTake one down and pass it around, 7 bottles of beer on the wall.\n")] + [TestCase(2, ExpectedResult = "2 bottles of beer on the wall, 2 bottles of beer.\nTake one down and pass it around, 1 bottle of beer on the wall.\n", Ignore = "Remove to run test case")] + [TestCase(1, ExpectedResult = "1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n", Ignore = "Remove to run test case")] + [TestCase(0, ExpectedResult = "No more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.\n", Ignore = "Remove to run test case")] + public string Verse(int number) + { + return Beer.Verse(number); + } + + [TestCase(8, 6, ExpectedResult = "8 bottles of beer on the wall, 8 bottles of beer.\nTake one down and pass it around, 7 bottles of beer on the wall.\n\n7 bottles of beer on the wall, 7 bottles of beer.\nTake one down and pass it around, 6 bottles of beer on the wall.\n\n6 bottles of beer on the wall, 6 bottles of beer.\nTake one down and pass it around, 5 bottles of beer on the wall.\n\n", Ignore = "Remove to run test case")] + [TestCase(3, 0, ExpectedResult = "3 bottles of beer on the wall, 3 bottles of beer.\nTake one down and pass it around, 2 bottles of beer on the wall.\n\n2 bottles of beer on the wall, 2 bottles of beer.\nTake one down and pass it around, 1 bottle of beer on the wall.\n\n1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n\nNo more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.\n\n", Ignore = "Remove to run test case")] + public string Sing(int start, int stop) + { + return Beer.Sing(start, stop); + } +} \ No newline at end of file diff --git a/exercises/beer-song/Example.cs b/exercises/beer-song/Example.cs new file mode 100644 index 0000000000..dc189d838e --- /dev/null +++ b/exercises/beer-song/Example.cs @@ -0,0 +1,27 @@ +using System.Linq; + +public static class Beer +{ + public static string Verse(int number) + { + switch (number) + { + case 0: + return "No more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.\n"; + case 1: + return "1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n"; + case 2: + return "2 bottles of beer on the wall, 2 bottles of beer.\nTake one down and pass it around, 1 bottle of beer on the wall.\n"; + default: + return string.Format("{0} bottles of beer on the wall, {0} bottles of beer.\nTake one down and pass it around, {1} bottles of beer on the wall.\n", number, number - 1); + } + } + + public static string Sing(int start, int stop) + { + return Enumerable.Range(stop, start - stop + 1) + .Reverse() + .Select(Verse) + .Aggregate("", (acc, verse) => acc + verse + "\n"); + } +} \ No newline at end of file diff --git a/exercises/kindergarten-garden/Example.cs b/exercises/kindergarten-garden/Example.cs new file mode 100644 index 0000000000..428ae468e3 --- /dev/null +++ b/exercises/kindergarten-garden/Example.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +public enum Plant +{ + Violets, + Radishes, + Clover, + Grass +} + +public class Garden +{ + private const int PlantsPerChildPerRow = 2; + private const char RowSeparator = '\n'; + + private static readonly string[] DefaultChildren = + { + "Alice", "Bob", "Charlie", "David", + "Eve", "Fred", "Ginny", "Harriet", + "Ileana", "Joseph", "Kincaid", "Larry" + }; + + private static readonly IDictionary PlantCodesToPlants = new Dictionary + { + { 'V', Plant.Violets }, + { 'R', Plant.Radishes }, + { 'C', Plant.Clover }, + { 'G', Plant.Grass } + }; + + private readonly IDictionary> plantsByChild; + + public Garden(IEnumerable children, string windowSills) + { + var plantsPerChild = PlantsPerChild(windowSills); + plantsByChild = children.OrderBy(c => c) + .Zip(plantsPerChild, Tuple.Create) + .ToDictionary(kv => kv.Item1, kv => kv.Item2); + } + + public IEnumerable GetPlants(string child) + { + return plantsByChild.ContainsKey(child) ? plantsByChild[child] : Enumerable.Empty(); + } + + public static Garden DefaultGarden(string windowSills) + { + return new Garden(DefaultChildren, windowSills); + } + + private static Plant PlantFromCode(char code) + { + return PlantCodesToPlants[code]; + } + + private static IEnumerable> PlantsPerChild(string windowSills) + { + var row = windowSills.Split(RowSeparator).Select(PlantsInRow).ToArray(); + return row[0].Zip(row[1], (row1Plants, row2Plants) => row1Plants.Concat(row2Plants)); + } + + private static IEnumerable> PlantsInRow(string row) + { + return Partition(row.Select(PlantFromCode), PlantsPerChildPerRow); + } + + private static IEnumerable> Partition(IEnumerable input, int partitionSize) + { + return input.Select((item, inx) => new { item, inx }) + .GroupBy(x => x.inx / partitionSize) + .Select(g => g.Select(x => x.item)); + } +} \ No newline at end of file diff --git a/exercises/kindergarten-garden/KinderGartenGardenTest.cs b/exercises/kindergarten-garden/KinderGartenGardenTest.cs new file mode 100644 index 0000000000..0c419aa364 --- /dev/null +++ b/exercises/kindergarten-garden/KinderGartenGardenTest.cs @@ -0,0 +1,65 @@ +using NUnit.Framework; + +public class KinderGartenGardenTest +{ + [Test] + public void Missing_child() + { + var actual = Garden.DefaultGarden("RC\nGG").GetPlants("Potter"); + Assert.That(actual, Is.Empty); + } + + [Ignore("Remove to run test")] + [Test] + public void Alice() + { + Assert.That(Garden.DefaultGarden("RC\nGG").GetPlants("Alice"), Is.EqualTo(new [] { Plant.Radishes, Plant.Clover, Plant.Grass, Plant.Grass })); + Assert.That(Garden.DefaultGarden("VC\nRC").GetPlants("Alice"), Is.EqualTo(new[] { Plant.Violets, Plant.Clover, Plant.Radishes, Plant.Clover })); + } + + [Ignore("Remove to run test")] + [Test] + public void Small_garden() + { + var actual = Garden.DefaultGarden("VVCG\nVVRC").GetPlants("Bob"); + Assert.That(actual, Is.EqualTo(new[] { Plant.Clover, Plant.Grass, Plant.Radishes, Plant.Clover })); + } + + [Ignore("Remove to run test")] + [Test] + public void Medium_garden() + { + var garden = Garden.DefaultGarden("VVCCGG\nVVCCGG"); + Assert.That(garden.GetPlants("Bob"), Is.EqualTo(new[] { Plant.Clover, Plant.Clover, Plant.Clover, Plant.Clover })); + Assert.That(garden.GetPlants("Charlie"), Is.EqualTo(new[] { Plant.Grass, Plant.Grass, Plant.Grass, Plant.Grass })); + } + + [Ignore("Remove to run test")] + [Test] + public void Full_garden() + { + var garden = Garden.DefaultGarden("VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"); + Assert.That(garden.GetPlants("Alice"), Is.EqualTo(new[] { Plant.Violets, Plant.Radishes, Plant.Violets, Plant.Radishes })); + Assert.That(garden.GetPlants("Bob"), Is.EqualTo(new[] { Plant.Clover, Plant.Grass, Plant.Clover, Plant.Clover })); + Assert.That(garden.GetPlants("David"), Is.EqualTo(new[] { Plant.Radishes, Plant.Violets, Plant.Clover, Plant.Radishes })); + Assert.That(garden.GetPlants("Eve"), Is.EqualTo(new[] { Plant.Clover, Plant.Grass, Plant.Radishes, Plant.Grass })); + Assert.That(garden.GetPlants("Fred"), Is.EqualTo(new[] { Plant.Grass, Plant.Clover, Plant.Violets, Plant.Clover })); + Assert.That(garden.GetPlants("Ginny"), Is.EqualTo(new[] { Plant.Clover, Plant.Grass, Plant.Grass, Plant.Clover })); + Assert.That(garden.GetPlants("Harriet"), Is.EqualTo(new[] { Plant.Violets, Plant.Radishes, Plant.Radishes, Plant.Violets })); + Assert.That(garden.GetPlants("Ileana"), Is.EqualTo(new[] { Plant.Grass, Plant.Clover, Plant.Violets, Plant.Clover })); + Assert.That(garden.GetPlants("Joseph"), Is.EqualTo(new[] { Plant.Violets, Plant.Clover, Plant.Violets, Plant.Grass })); + Assert.That(garden.GetPlants("Kincaid"), Is.EqualTo(new[] { Plant.Grass, Plant.Clover, Plant.Clover, Plant.Grass })); + Assert.That(garden.GetPlants("Larry"), Is.EqualTo(new[] { Plant.Grass, Plant.Violets, Plant.Clover, Plant.Violets })); + } + + [Ignore("Remove to run test")] + [Test] + public void Surprise_garden() + { + var garden = new Garden(new [] { "Samantha", "Patricia", "Xander", "Roger" }, "VCRRGVRG\nRVGCCGCV"); + Assert.That(garden.GetPlants("Patricia"), Is.EqualTo(new[] { Plant.Violets, Plant.Clover, Plant.Radishes, Plant.Violets })); + Assert.That(garden.GetPlants("Roger"), Is.EqualTo(new[] { Plant.Radishes, Plant.Radishes, Plant.Grass, Plant.Clover })); + Assert.That(garden.GetPlants("Samantha"), Is.EqualTo(new[] { Plant.Grass, Plant.Violets, Plant.Clover, Plant.Grass })); + Assert.That(garden.GetPlants("Xander"), Is.EqualTo(new[] { Plant.Radishes, Plant.Grass, Plant.Clover, Plant.Violets })); + } +} \ No newline at end of file diff --git a/exercises/pascals-triangle/Example.cs b/exercises/pascals-triangle/Example.cs new file mode 100644 index 0000000000..b2bfa7b103 --- /dev/null +++ b/exercises/pascals-triangle/Example.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; + +public static class PascalsTriangle +{ + public static IEnumerable> Calculate(int rows) + { + for (var i = 1; i <= rows; i++) + { + yield return Row(i); + } + } + + private static IEnumerable Row(int row) + { + yield return 1; + var column = 1; + + for (var j = 1; j < row; j++) + { + column = column * (row - j) / j; + yield return column; + } + } +} \ No newline at end of file diff --git a/exercises/pascals-triangle/PascalsTriangleTest.cs b/exercises/pascals-triangle/PascalsTriangleTest.cs new file mode 100644 index 0000000000..ebc1950188 --- /dev/null +++ b/exercises/pascals-triangle/PascalsTriangleTest.cs @@ -0,0 +1,52 @@ +using System.Linq; +using NUnit.Framework; + +public class PascalsTriangleTest +{ + [Test] + public void One_row() + { + var actual = PascalsTriangle.Calculate(1); + Assert.That(actual, Is.EqualTo(new[] { new[] { 1 } })); + } + + [Ignore("Remove to run test")] + [Test] + public void Two_rows() + { + var actual = PascalsTriangle.Calculate(2); + Assert.That(actual, Is.EqualTo(new[] { new[] { 1 }, new[] { 1, 1 } })); + } + + [Ignore("Remove to run test")] + [Test] + public void Three_rows() + { + var actual = PascalsTriangle.Calculate(3); + Assert.That(actual, Is.EqualTo(new[] { new[] { 1 }, new[] { 1, 1 }, new[] { 1, 2, 1 } })); + } + + [Ignore("Remove to run test")] + [Test] + public void Four_rows() + { + var actual = PascalsTriangle.Calculate(4); + Assert.That(actual, Is.EqualTo(new[] { new[] { 1 }, new[] { 1, 1 }, new[] { 1, 2, 1 }, new[] { 1, 3, 3, 1 } })); + } + + [Ignore("Remove to run test")] + [Test] + public void Five_rows() + { + var actual = PascalsTriangle.Calculate(5); + Assert.That(actual, Is.EqualTo(new[] { new[] { 1 }, new[] { 1, 1 }, new[] { 1, 2, 1 }, new[] { 1, 3, 3, 1 }, new [] { 1, 4, 6, 4, 1 } })); + } + + [Ignore("Remove to run test")] + [Test] + public void Twenty_rows() + { + var actual = PascalsTriangle.Calculate(20).Last(); + Assert.That(actual, Is.EqualTo(new[] { 1, 19, 171, 969, 3876, 11628, 27132, 50388, 75582, 92378, 92378, 75582, 50388, 27132, 11628, 3876, 969, 171, 19, 1 })); + } +} \ No newline at end of file diff --git a/exercises/saddle-points/Example.cs b/exercises/saddle-points/Example.cs new file mode 100644 index 0000000000..a28414d26b --- /dev/null +++ b/exercises/saddle-points/Example.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +public class Matrix +{ + private readonly int[,] values; + private readonly int[] maxRows; + private readonly int[] minCols; + + public Matrix(int[,] values) + { + this.values = values; + this.maxRows = Rows().Select(r => r.Max()).ToArray(); + this.minCols = Columns().Select(r => r.Min()).ToArray(); + } + + public IEnumerable> SaddlePoints() + { + return Coordinates().Where(IsSaddlePoint); + } + + private bool IsSaddlePoint(Tuple coordinate) + { + return maxRows[coordinate.Item1] == values[coordinate.Item1, coordinate.Item2] && + minCols[coordinate.Item2] == values[coordinate.Item1, coordinate.Item2]; + } + + private IEnumerable> Coordinates() + { + return Enumerable.Range(0, RowCount).SelectMany(x => Enumerable.Range(0, ColumnCount).Select(y => Tuple.Create(x, y))); + } + + private IEnumerable> Rows() + { + return Enumerable.Range(0, RowCount).Select(x => Enumerable.Range(0, ColumnCount).Select(y => values[x, y])); + } + + private IEnumerable> Columns() + { + return Enumerable.Range(0, ColumnCount).Select(y => Enumerable.Range(0, RowCount).Select(x => values[x, y])); + } + + private int ColumnCount => values.GetLength(1); + + private int RowCount => values.GetLength(0); +} \ No newline at end of file diff --git a/exercises/saddle-points/SaddlePointTests.cs b/exercises/saddle-points/SaddlePointTests.cs new file mode 100644 index 0000000000..2f8fb53667 --- /dev/null +++ b/exercises/saddle-points/SaddlePointTests.cs @@ -0,0 +1,72 @@ +using System; +using NUnit.Framework; + +public class SaddlePointTests +{ + [Test] + public void Readme_example() + { + var values = new[,] + { + { 9, 8, 7 }, + { 5, 3, 2 }, + { 6, 6, 7 } + }; + var actual = new Matrix(values).SaddlePoints(); + Assert.That(actual, Is.EqualTo(new [] { Tuple.Create(1, 0)})); + } + + [Ignore("Remove to run test")] + [Test] + public void No_saddle_point() + { + var values = new[,] + { + { 2, 1 }, + { 1, 2 } + }; + var actual = new Matrix(values).SaddlePoints(); + Assert.That(actual, Is.Empty); + } + + [Ignore("Remove to run test")] + [Test] + public void Saddle_point() + { + var values = new[,] + { + { 1, 2 }, + { 3, 4 } + }; + var actual = new Matrix(values).SaddlePoints(); + Assert.That(actual, Is.EqualTo(new[] { Tuple.Create(0, 1) })); + } + + [Ignore("Remove to run test")] + [Test] + public void Another_saddle_point() + { + var values = new[,] + { + { 18, 3, 39, 19, 91 }, + { 38, 10, 8, 77, 320 }, + { 3, 4, 8, 6, 7 } + }; + var actual = new Matrix(values).SaddlePoints(); + Assert.That(actual, Is.EqualTo(new[] { Tuple.Create(2, 2) })); + } + + [Ignore("Remove to run test")] + [Test] + public void Multiple_saddle_points() + { + var values = new[,] + { + { 4, 5, 4 }, + { 3, 5, 5 }, + { 1, 5, 4 } + }; + var actual = new Matrix(values).SaddlePoints(); + Assert.That(actual, Is.EqualTo(new[] { Tuple.Create(0, 1), Tuple.Create(1, 1), Tuple.Create(2, 1) })); + } +} \ No newline at end of file