Reputation: 5384
OK so today is one of those days that my mind cannot work properly.
I cannot make this to work (:
class Program
{
static private List<KeyValuePair<int, double>> _list;
static protected List<KeyValuePair<int, double>> list
{
get
{
if (_list == null)
{
_list = new List<KeyValuePair<int, double>>();
_list.Add(new KeyValuePair<int, double>(1, 11.60));
_list.Add(new KeyValuePair<int, double>(2, 11.20));
_list.Add(new KeyValuePair<int, double>(3, 13.00));
_list.Add(new KeyValuePair<int, double>(4, 13.60));
_list.Add(new KeyValuePair<int, double>(5, 15.90));
_list.Add(new KeyValuePair<int, double>(6, 16.10));
_list.Add(new KeyValuePair<int, double>(7, 19.10));
_list.Add(new KeyValuePair<int, double>(8, 19.10));
_list.Add(new KeyValuePair<int, double>(9, 19.10));
_list.Add(new KeyValuePair<int, double>(10, 21.00));
_list.Add(new KeyValuePair<int, double>(11, 23.00));
}
return _list;
}
}
static void Main(string[] args)
{
Program p = new Program();
int value = 27;
double d = p.GetCost(value);
}
public double GetCost(int tot)
{
double cost = 0;
if (tot < 1)
return list[tot-1].Value;
cost += GetCost(tot - list.Count);
return cost;
}
}
So conceptually, I need to set that recursion GETCOST procedure to work properly so that it will call itself and get the RIGHT value (the second column) from the LIST and add it to the recursive caller.
EXPECTED RESULTS
if the "value" is 8 the total should be $19.10 $19.10 from KeyParValue(8 - 19.10)
if the "value" is 12 the total should be $36.60 $23 + 11.60 from KeyParValue(11 - 23.00) + KeyParValue(1 - 13.60)
if the "value" is 27 the total should be $61.90
$23 + $23 + $15.90; from KeyParValue(11 - 23.00) + KeyParValue(11 - 23.00) + KeyParValue(5 - 15.90)
Thanks advanced, F.
Upvotes: 1
Views: 1202
Reputation: 10347
Maybe you want something like this:
public static double GetCost ( int tot ) {
double cost = 0;
if ( tot > list.Count () )
cost += ( (int)tot / list.Count () ) * list[list.Count () - 1].Value; // add n times the max value
if ( tot % list.Count () > 0 )
cost += list[( tot % list.Count () ) - 1].Value; // should add the remainder
return cost;
}
Checked now in Visual Studio. Your second example is off by two. It should be 34.60 ( 23.00 + 11.60 = 34.60 ). As Jon has pointed out, there is an issue with 0. Maybe throw an ArgumentException or return zero, whatever fits your needs.
Edit: From your comment on Jon's answer I think that the list isn't ordered as in your sample. That means, calculating the total must be based on the key and not the index. A first shot ( giving you the expected results):
public static double GetCost ( int tot ) {
int maxKey = list.Aggregate ( ( current, next ) => next.Key > current.Key ? next : current ).Key;
double cost = 0;
if ( tot > maxKey )
cost += ( (int)tot / maxKey ) * list.Where ( kvp => kvp.Key == maxKey ).First ().Value; // add n times the max value
if ( tot % maxKey > 0 )
cost += list.Where ( kvp => kvp.Key == tot % maxKey ).First ().Value; // should add the remainder
return cost;
}
Doesn't look that different. This function assumes all keys between one and maxKey do exist. If not, it will fail for the cases a required key is missing.
Upvotes: 0
Reputation: 6054
You don't need recursion or loops...
public double GetCost( int tot )
{
int multipliers;
int count;
double cost;
var dictionary = list.ToDictionary( kvp => kvp.Key, kvp => kvp.Value );
count = list.Count;
multipliers = tot / count;
cost = multipliers * dictionary[count];
tot %= count;
if ( dictionary.ContainsKey( tot ) )
{
cost += dictionary[tot];
}
return cost;
}
Edit: Fixed the "tot==0 issue".
Upvotes: 0
Reputation: 389
I'd go with something like the following and remove the recursion. However, since the question was about recursion I've included the recursion logic as well. Really it just your list that is causing logic issues.
class Program
{
private static Dictionary<int, double> _dollarValues;
protected static Dictionary<int, double> DollarValues
{
get
{
if (_dollarValues == null)
{
_dollarValues = new Dictionary<int, double>();
_dollarValues.Add(1, 11.60);
_dollarValues.Add(2, 11.20);
_dollarValues.Add(3, 13.00);
_dollarValues.Add(4, 13.60);
_dollarValues.Add(5, 15.90);
_dollarValues.Add(6, 16.10);
_dollarValues.Add(7, 19.10);
_dollarValues.Add(8, 19.10);
_dollarValues.Add(9, 19.10);
_dollarValues.Add(10, 21.00);
_dollarValues.Add(11, 23.00);
}
return _dollarValues;
}
}
private static int _maxKey = 0;
private static void Main(string[] args)
{
_maxKey = DollarValues.Max(key => key.Key);
int value = 27;
double cost = 0; //GetCost(value); If I wanted to use recursion instead.
while(value > 0)
{
int key = value >= _maxKey ? _maxKey : value;
cost += DollarValues[key];
value -= key;
}
}
//Recursion if I had to
public static double GetCost(int value)
{
double cost = 0;
cost +=
value >= _maxKey ?
DollarValues[_maxKey] + GetCost(value - _maxKey)
: DollarValues[value];
return cost;
}
}
Upvotes: 0
Reputation: 16038
This will return what you described in yout expected result section. But it feels like the thing you really want to achieve is something different.
public double GetCost(int tot)
{
double cost = 0;
while(tot > 0) {
cost += tot >= 11
? list[11]
: list[tot];
tot -= tot % 11;
}
return cost;
}
Upvotes: 2
Reputation: 1503290
This is problematic to start with:
if (tot < 1)
return list[tot-1].Value;
If tot
is less than 1, then tot - 1
is less than zero, and list[tot - 1]
will throw an exception.
Do you actually want:
if (tot < 1)
return list[tot].Value - 1;
? That's still only going to work if tot
is 0, mind you...
It's not really clear to me what your code is meant to achieve in the first place - but I strongly suspect it would be clearer without using recursion. Perhaps you could describe what you're trying to do?
Upvotes: 2