Skip to content
Snippets Groups Projects
Verified Commit 2f9eeb3a authored by Dmytro Bogatov's avatar Dmytro Bogatov :two_hearts:
Browse files

Add Coin Chnage Problem from HAcker Rank.

parent 67113180
Branches
No related tags found
No related merge requests found
using System.Collections.Generic;
using System.Linq;
namespace CodingInterview.HackerRank
{
/// <summary>
/// You are working at the cash counter at a fun-fair, and you have different types of coins available to you in infinite quantities.
/// The value of each coin is already given.
/// Can you determine the number of ways of making change for a particular number of units using the given types of coins?
///
/// For example, if you have 4 types of coins, and the value of each type is given as 8, 3, 1, 2 respectively, you can make change for 3 units in three ways: {1, 1, 1}, {1, 2}, and {3}.
///
/// https://www.hackerrank.com/challenges/coin-change/problem
/// </summary>
public class CoinChange
{
// memoization cache;
// the key is (change, number of coins), the value is the number of ways to make change;
// because the list is always in the same order, the number of coins totally defines which coins there are;
private Dictionary<(int, int), long> cache = new Dictionary<(int, int), long>();
/// <summary>
/// Solve the Coin Change Problem
/// </summary>
/// <param name="n">the amount to make change for</param>
/// <param name="c">available denominations (guaranteed to be unique)</param>
/// <returns>the number of ways to make change</returns>
public long Solve(int n, List<long> c)
{
// check memoization first
if (cache.ContainsKey((n, c.Count)))
{
return cache[(n, c.Count)];
}
else
{
long result;
// n == 0 means that the caller could have used the subtracted coin alone to fullfil the change, thus 1
if (n == 0)
{
result = 1;
}
// below 0 change or empty list of denominations means going out of bound of the problem (below the leaf level of the tree)
else if (n < 0 || c.Count == 0)
{
result = 0;
}
// else we are somwhere in the middle (or top) of the tree
else
{
// most important, the number of ways one can make change for n given c.Count distinct denominations is like this;
// the number of ways to make change for n WITHOUT the last coin (thus c without last of c), AND
// the number of ways to make change for n WITH the last coin (thus, n - last of c)
result = Solve(n, c.Take(c.Count - 1).ToList()) + Solve(n - (int)c.Last(), c);
}
// there is a ton of dupplicate invocations when run recursively, so we use memoization
cache.Add((n, c.Count), result);
return result;
}
}
}
}
using System.Collections.Generic;
using Xunit;
namespace CodingInterview.Tests.HackerRank
{
public class CoinChange
{
[Fact]
public void TestCases()
{
// From Hacker Rank
Assert.Equal(3, new CodingInterview.HackerRank.CoinChange().Solve(3, new List<long> { 8, 3, 1, 2 }));
Assert.Equal(4, new CodingInterview.HackerRank.CoinChange().Solve(4, new List<long> { 1, 2, 3 }));
Assert.Equal(5, new CodingInterview.HackerRank.CoinChange().Solve(10, new List<long> { 2, 5, 3, 6 }));
}
}
}
......@@ -3,16 +3,16 @@ using CodingInterview.School;
namespace CodingInterview.Tests.School
{
public class ChildrenTests
public class Children
{
[Fact]
public void TestCases()
{
Assert.Equal(4, Children.Solve(10, 3));
Assert.Equal(5, Children.Solve(10, 2));
Assert.Equal(10, Children.Solve(10, 1));
Assert.Equal(1, Children.Solve(1, 10));
Assert.Equal(1, Children.Solve(2, 10));
Assert.Equal(4, CodingInterview.School.Children.Solve(10, 3));
Assert.Equal(5, CodingInterview.School.Children.Solve(10, 2));
Assert.Equal(10, CodingInterview.School.Children.Solve(10, 1));
Assert.Equal(1, CodingInterview.School.Children.Solve(1, 10));
Assert.Equal(1, CodingInterview.School.Children.Solve(2, 10));
}
}
}
......@@ -3,14 +3,14 @@ using CodingInterview.School;
namespace CodingInterview.Tests.School
{
public class HanoiTests
public class Hanoi
{
[Fact]
public void TestCases()
{
Assert.Equal(
"1->2\n1->3\n2->3\n1->2\n3->1\n3->2\n1->2\n",
Hanoi.Solve(3)
CodingInterview.School.Hanoi.Solve(3)
);
}
}
......
......@@ -7,14 +7,14 @@ using System.Linq;
namespace CodingInterview.Tests.School
{
public class PortalsTests
public class Portals
{
[Fact]
public void TestCases()
{
Assert.Equal(
10,
Portals.Solve(
CodingInterview.School.Portals.Solve(
new int[] { 7, 4, 7, 3 },
new Tuple<int, int>[] {
new Tuple<int, int>(1, 3),
......@@ -30,7 +30,7 @@ namespace CodingInterview.Tests.School
{
var arguments = ParseFile(fileId.ToString("D2"));
Assert.Equal(arguments.Item3, Portals.Solve(arguments.Item1, arguments.Item2));
Assert.Equal(arguments.Item3, CodingInterview.School.Portals.Solve(arguments.Item1, arguments.Item2));
}
public static IEnumerable<object[]> Cases(int upTo) => Enumerable.Range(1, upTo).Select(i => new object[] { i });
......
......@@ -5,29 +5,29 @@ using CodingInterview.Sort;
namespace CodingInterview.Tests.Sort
{
public class BubbleSortTests
public class BubbleSort
{
[Fact]
public void TestCases()
{
Assert.Equal(
new int[] { 2, 5, 6, 8, 9 },
BubbleSort.Sort(new int[] { 5, 2, 6, 8, 9 })
CodingInterview.Sort.BubbleSort.Sort(new int[] { 5, 2, 6, 8, 9 })
);
Assert.Equal(
new int[] { 1 },
BubbleSort.Sort(new int[] { 1 })
CodingInterview.Sort.BubbleSort.Sort(new int[] { 1 })
);
Assert.Equal(
new int[] { },
BubbleSort.Sort(new int[] { })
CodingInterview.Sort.BubbleSort.Sort(new int[] { })
);
Assert.Equal(
new int[] { 5, 5, 6 },
BubbleSort.Sort(new int[] { 5, 6, 5 })
CodingInterview.Sort.BubbleSort.Sort(new int[] { 5, 6, 5 })
);
Random randNum = new Random();
......@@ -38,7 +38,7 @@ namespace CodingInterview.Tests.Sort
Assert.Equal(
expected,
BubbleSort.Sort(input)
CodingInterview.Sort.BubbleSort.Sort(input)
);
}
}
......
......@@ -5,34 +5,34 @@ using CodingInterview.Sort;
namespace CodingInterview.Tests.Sort
{
public class HeapSortTests
public class HeapSort
{
[Fact]
public void TestCases()
{
Assert.Equal(
new int[] { -1, 1, 2, 5, 8, 9, 45 },
HeapSort.Sort(new int[] { 5, 2, 1, -1, 8, 45, 9 })
CodingInterview.Sort.HeapSort.Sort(new int[] { 5, 2, 1, -1, 8, 45, 9 })
);
Assert.Equal(
new int[] { 2, 5, 6, 8, 9 },
HeapSort.Sort(new int[] { 5, 2, 6, 8, 9 })
CodingInterview.Sort.HeapSort.Sort(new int[] { 5, 2, 6, 8, 9 })
);
Assert.Equal(
new int[] { 1 },
HeapSort.Sort(new int[] { 1 })
CodingInterview.Sort.HeapSort.Sort(new int[] { 1 })
);
Assert.Equal(
new int[] { },
HeapSort.Sort(new int[] { })
CodingInterview.Sort.HeapSort.Sort(new int[] { })
);
Assert.Equal(
new int[] { 5, 5, 6 },
HeapSort.Sort(new int[] { 5, 6, 5 })
CodingInterview.Sort.HeapSort.Sort(new int[] { 5, 6, 5 })
);
......@@ -44,7 +44,7 @@ namespace CodingInterview.Tests.Sort
Assert.Equal(
expected,
HeapSort.Sort(input)
CodingInterview.Sort.HeapSort.Sort(input)
);
}
}
......
......@@ -5,29 +5,29 @@ using CodingInterview.Sort;
namespace CodingInterview.Tests.Sort
{
public class InsertionSortTests
public class InsertionSort
{
[Fact]
public void TestCases()
{
Assert.Equal(
new int[] { 2, 5, 6, 8, 9 },
InsertionSort.Sort(new int[] { 5, 2, 6, 8, 9 })
CodingInterview.Sort.InsertionSort.Sort(new int[] { 5, 2, 6, 8, 9 })
);
Assert.Equal(
new int[] { 1 },
InsertionSort.Sort(new int[] { 1 })
CodingInterview.Sort.InsertionSort.Sort(new int[] { 1 })
);
Assert.Equal(
new int[] { },
InsertionSort.Sort(new int[] { })
CodingInterview.Sort.InsertionSort.Sort(new int[] { })
);
Assert.Equal(
new int[] { 5, 5, 6 },
InsertionSort.Sort(new int[] { 5, 6, 5 })
CodingInterview.Sort.InsertionSort.Sort(new int[] { 5, 6, 5 })
);
Random randNum = new Random();
......@@ -39,7 +39,7 @@ namespace CodingInterview.Tests.Sort
Assert.Equal(
expected,
InsertionSort.Sort(input)
CodingInterview.Sort.InsertionSort.Sort(input)
);
}
}
......
......@@ -5,34 +5,34 @@ using CodingInterview.Sort;
namespace CodingInterview.Tests.Sort
{
public class MergeSortTests
public class MergeSort
{
[Fact]
public void TestCases()
{
Assert.Equal(
new int[] { -1, 1, 2, 5, 8, 9, 45 },
MergeSort.Sort(new int[] { 5, 2, 1, -1, 8, 45, 9 })
CodingInterview.Sort.MergeSort.Sort(new int[] { 5, 2, 1, -1, 8, 45, 9 })
);
Assert.Equal(
new int[] { 2, 5, 6, 8, 9 },
MergeSort.Sort(new int[] { 5, 2, 6, 8, 9 })
CodingInterview.Sort.MergeSort.Sort(new int[] { 5, 2, 6, 8, 9 })
);
Assert.Equal(
new int[] { 1 },
MergeSort.Sort(new int[] { 1 })
CodingInterview.Sort.MergeSort.Sort(new int[] { 1 })
);
Assert.Equal(
new int[] { },
MergeSort.Sort(new int[] { })
CodingInterview.Sort.MergeSort.Sort(new int[] { })
);
Assert.Equal(
new int[] { 5, 5, 6 },
MergeSort.Sort(new int[] { 5, 6, 5 })
CodingInterview.Sort.MergeSort.Sort(new int[] { 5, 6, 5 })
);
......@@ -44,7 +44,7 @@ namespace CodingInterview.Tests.Sort
Assert.Equal(
expected,
MergeSort.Sort(input)
CodingInterview.Sort.MergeSort.Sort(input)
);
}
}
......
......@@ -5,34 +5,34 @@ using CodingInterview.Sort;
namespace CodingInterview.Tests.Sort
{
public class QuickSortTests
public class QuickSort
{
[Fact]
public void TestCases()
{
Assert.Equal(
new int[] { -1, 1, 2, 5, 8, 9, 45 },
QuickSort.Sort(new int[] { 5, 2, 1, -1, 8, 45, 9 })
CodingInterview.Sort.QuickSort.Sort(new int[] { 5, 2, 1, -1, 8, 45, 9 })
);
Assert.Equal(
new int[] { 2, 5, 6, 8, 9 },
QuickSort.Sort(new int[] { 5, 2, 6, 8, 9 })
CodingInterview.Sort.QuickSort.Sort(new int[] { 5, 2, 6, 8, 9 })
);
Assert.Equal(
new int[] { 1 },
QuickSort.Sort(new int[] { 1 })
CodingInterview.Sort.QuickSort.Sort(new int[] { 1 })
);
Assert.Equal(
new int[] { },
QuickSort.Sort(new int[] { })
CodingInterview.Sort.QuickSort.Sort(new int[] { })
);
Assert.Equal(
new int[] { 5, 5, 6 },
QuickSort.Sort(new int[] { 5, 6, 5 })
CodingInterview.Sort.QuickSort.Sort(new int[] { 5, 6, 5 })
);
......@@ -44,7 +44,7 @@ namespace CodingInterview.Tests.Sort
Assert.Equal(
expected,
QuickSort.Sort(input)
CodingInterview.Sort.QuickSort.Sort(input)
);
}
}
......
......@@ -5,29 +5,29 @@ using CodingInterview.Sort;
namespace CodingInterview.Tests.Sort
{
public class SelectionSortTests
public class SelectionSort
{
[Fact]
public void TestCases()
{
Assert.Equal(
new int[] { 2, 5, 6, 8, 9 },
SelectionSort.Sort(new int[] { 5, 2, 6, 8, 9 })
CodingInterview.Sort.SelectionSort.Sort(new int[] { 5, 2, 6, 8, 9 })
);
Assert.Equal(
new int[] { 1 },
SelectionSort.Sort(new int[] { 1 })
CodingInterview.Sort.SelectionSort.Sort(new int[] { 1 })
);
Assert.Equal(
new int[] { },
SelectionSort.Sort(new int[] { })
CodingInterview.Sort.SelectionSort.Sort(new int[] { })
);
Assert.Equal(
new int[] { 5, 5, 6 },
SelectionSort.Sort(new int[] { 5, 6, 5 })
CodingInterview.Sort.SelectionSort.Sort(new int[] { 5, 6, 5 })
);
Random randNum = new Random();
......@@ -39,7 +39,7 @@ namespace CodingInterview.Tests.Sort
Assert.Equal(
expected,
SelectionSort.Sort(input)
CodingInterview.Sort.SelectionSort.Sort(input)
);
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment