Heres a fun problem I have.
I have a function that returns a var of items;
var Items = new { sumList = SumList, ratesList = List, sum = List.Sum() };
return Items;
From a function that is dynamic:
public override dynamic GetRates()
and I return it to a function I else where and try to apply it to my code:
dynamic res = cl.mainC.GetRates();
List<double> MashkantaSumList = res.sumList;
Now when I try to apply it, it says the object doesnt exist. But if I look in the debugger the items are happily there as a generic list or what not.
How do I resolve this?
EDIT:
as per request I'll post the full code:
//virtual
public virtual dynamic TotalMashkanta(int i, double sum, double ribit, string[] discount)
{
return 0;
}
//override
public override dynamic TotalMashkanta(int i, double sum, double ribit, string[] discount)
{
double SumTemp = sum;
double monthlyRibit = ribit / 12;
Double permPayPerMont = Financial.Pmt(monthlyRibit, i, sum, 0, DueDate.EndOfPeriod);
List<double> MashkantaList = new List<double>();
List<double> MashkantaSumList = new List<double>();
for (int j = 1; j <= i; j++)
{
MashkantaList.Add(Mashkanta(j, sum, ribit, permPayPerMont) * (1 - CalcDiscount((j / 12) + 1, discount)));
SumTemp = getSum(j, sum, ribit, permPayPerMont * -1); ;
MashkantaSumList.Add(SumTemp);
}
var K_Mashkanta = new { sumList = MashkantaSumList, ratesList = MashkantaList, sum = MashkantaList.Sum() };
return K_Mashkanta;
}
//Function that calls the results
public void GetSilukinTable(string Path, string ClientID, DAL.Client client, string partner_checked, string insurance_Amount, string Premiya_Structure_Mashkanta, string Premiya_Life_Mashkanta, string Discount_Life_Mashkanta, string Loan_Period,string Loan_EndDate, string Bank, string Loan_Interest, string Loan_Amount, string Discount_Loan, string AgentNotes, string ManID)
{
BL.CalculateLogic.Companies t = BL.CalculateLogic.Companies.כלל;
if(ManID == "211") t = BL.CalculateLogic.Companies.הפניקס;
if(ManID == "207") t = BL.CalculateLogic.Companies.הראל;
if(ManID == "206") t = BL.CalculateLogic.Companies.מנורה;
if(ManID == "208") t = BL.CalculateLogic.Companies.הכשרה;
BL.CalculateLogic cl = new BL.CalculateLogic(client, t);
DateTime LoanEnd = DateTime.Now;
int months = 0;
if (DateTime.TryParse(Loan_EndDate, out LoanEnd))
months = BL.Calculating_Companies.Company.GetMonthsBetween(DateTime.Now, LoanEnd);
else
months = Int32.Parse(Loan_Period) * 12;
string[] Discount = Discount_Loan.Split('-');
dynamic res = cl.mainC.TotalMashkanta(months, Double.Parse(Loan_Amount), Double.Parse(Loan_Interest.Trim('%')), Discount);
var MashkantaSumList = res.sumList;
List<double> MashkantaList = res.ratesList;
List<double> MashkantaSumListPartner = new List<double>();
List<double> MashkantaListPartner = new List<double>();
List<double> MashkantaListSum = res.ratesList;
}
The compiler is happy about it because dynamic is compiled and checked at run time. Whatever the problem is, the types don't match. It evaluates this at run time, so you won't see issues at compile time. (Advice: use dynamic only when you really must! Else you will have this kind of problems all the time!)
I tried your code using this and it works fine:
static dynamic GetRates()
{
List<double> SumList = new List<double>();
List<double> List = new List<double>();
var Items = new { sumList = SumList, ratesList = List, sum = List.Sum() };
return Items;
}
static void Main(string[] args)
{
dynamic res = GetRates();
List<double> MashkantaSumList = res.sumList;
}
Related
I Have a list that contains four item (A, B, C, D). Every item has a probability to be chosen. Let's say for example A has 74% of chance to be picked, B 15%, C 7% ,and D 4%.
I want to create a function that choose randomly an item according to its probability.
Any help please?
Define a class for your items like this:
class Items<T>
{
public double Probability { get; set; }
public T Item { get; set; }
}
then initialize it
var initial = new List<Items<string>>
{
new Items<string> {Probability = 74 / 100.0, Item = "A"},
new Items<string> {Probability = 15 / 100.0, Item = "B"},
new Items<string> {Probability = 7 / 100.0, Item = "C"},
new Items<string> {Probability = 4 / 100.0, Item = "D"},
};
then you need to convert it to aggregate a sum of probabilities from 0 to 1
var converted = new List<Items<string>>(initial.Count);
var sum = 0.0;
foreach (var item in initial.Take(initial.Count - 1))
{
sum += item.Probability;
converted.Add(new Items<string> {Probability = sum, Item = item.Item});
}
converted.Add(new Items<string> {Probability = 1.0, Item = initial.Last().Item});
now you can pick an item from converted collection with respect to probability:
var rnd = new Random();
while (true)
{
var probability = rnd.NextDouble();
var selected = converted.SkipWhile(i => i.Probability < probability).First();
Console.WriteLine($"Selected item = {selected.Item}");
}
NOTE: my implementation have O(n) complexity. You can optimize it with binary search (because values in converted collection are sorted)
My apologies for answering this one like this - I'm kinda viewing it as a sort of "Euler.Net" puzzle, and a way of playing around with Generics.
Anyway, here's my go at it:
public class WeightedItem<T>
{
private T value;
private int weight;
private int cumulativeSum;
private static Random rndInst = new Random();
public WeightedItem(T value, int weight)
{
this.value = value;
this.weight = weight;
}
public static T Choose(List<WeightedItem<T>> items)
{
int cumulSum = 0;
int cnt = items.Count();
for (int slot = 0; slot < cnt; slot++)
{
cumulSum += items[slot].weight;
items[slot].cumulativeSum = cumulSum;
}
double divSpot = rndInst.NextDouble() * cumulSum;
WeightedItem<T> chosen = items.FirstOrDefault(i => i.cumulativeSum >= divSpot);
if (chosen == null) throw new Exception("No item chosen - there seems to be a problem with the probability distribution.");
return chosen.value;
}
}
Usage:
WeightedItem<string> alice = new WeightedItem<string>("alice", 1);
WeightedItem<string> bob = new WeightedItem<string>("bob", 1);
WeightedItem<string> charlie = new WeightedItem<string>("charlie", 1);
WeightedItem<string> diana = new WeightedItem<string>("diana", 4);
WeightedItem<string> elaine = new WeightedItem<string>("elaine", 1);
List<WeightedItem<string>> myList = new List<WeightedItem<string>> { alice, bob, charlie, diana, elaine };
string chosen = WeightedItem<string>.Choose(myList);
using System;
public class Test{
private static String[] values = {"A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","B","B","B","B","B","B","B","C","C","C","C","C","C","C","D","D","D","D",};
private static Random PRNG = new Random();
public static void Main(){
Console.WriteLine( values[PRNG.Next(values.Length)] );
}
}
I have a problem to solve where given a string source and a collection of search criteria criteria, the algorithm has to return the shortest possible substring of source that contains all items of criteria.
=================================
UPDATE
The same search criteria might be in the source string multiple
times. In that case, it is required to return the sub-string
containing the particular instance of the search criteria such that
it is the shortest among all possible sub-strings.
The search items can contain spaces in them such as hello world
The order in which the search criteria are found does not matter as long as they are all in the resultant sub-string
==================================
String source = "aaa wwwww fgffsd ththththt sss sgsgsgsghs bfbfb hhh sdfg kkk dhdhtrherhrhrthrthrt ddfhdetehehe kkk wdwd aaa vcvc hhh zxzx sss nbnbn";
List<String> criteria = new List<string> { "kkk", "aaa", "sss", "hhh" };
The input above should return the following substring: kkk wdwd aaa vcvc hhh zxzx sss
Unfortunately, I spent a lot of time trying to write such an algorithm but I couldn't get it just right. Below is the code I have got so far:
public struct Extraction
{
public int Start { get; set; }
public int End { get; set; }
public int Length
{
get
{
var length = this.End - this.Start;
return length;
}
}
public Extraction(int start, int end)
{
this.Start = start;
this.End = end;
}
}
public class TextExtractor
{
private String _source;
private Dictionary<String, List<Int32>> _criteriaIndexes;
private Dictionary<String, int> _entryIndex;
public TextExtractor(String source, List<String> searchCriteria)
{
this._source = source;
this._criteriaIndexes = this.ExtractIndexes(source, searchCriteria);
this._entryIndex = _criteriaIndexes.ToDictionary(x => x.Key, v => 0);
}
public String Extract()
{
List<Extraction> possibleExtractions = new List<Extraction>();
int index = 0;
int min = int.MaxValue;
int max = 0;
bool shouldStop = false;
while (index < _criteriaIndexes.Count && !shouldStop)
{
Boolean compareWithAll = index == _criteriaIndexes.Count - 1;
if (!compareWithAll)
{
var current = _criteriaIndexes.ElementAt(index);
this.CalculateMinMax(current, ref min, ref max);
index++;
}
else
{
var entry = _criteriaIndexes.Last();
while (_entryIndex[entry.Key] < entry.Value.Count)
{
int a = min;
int b = max;
this.CalculateMinMax(entry, ref a, ref b);
_entryIndex[entry.Key]++;
Extraction ext = new Extraction(a, b);
possibleExtractions.Add(ext);
}
int k = index - 1;
while (k >= 0)
{
var prev = _criteriaIndexes.ElementAt(k);
if (prev.Value.Count - 1 > _entryIndex[prev.Key])
{
_entryIndex[prev.Key]++;
break;
}
else
{
k--;
}
}
shouldStop = _criteriaIndexes.All(x => x.Value.Count - 1 <= _entryIndex[x.Key]);
_entryIndex[entry.Key] = 0;
index = 0;
min = int.MaxValue;
max = 0;
}
}
Extraction shortest = possibleExtractions.First(x => x.Length.Equals(possibleExtractions.Min(p => p.Length)));
String result = _source.Substring(shortest.Start, shortest.Length);
return result;
}
private Dictionary<String, List<Int32>> ExtractIndexes(String source, List<String> searchCriteria)
{
Dictionary<String, List<Int32>> result = new Dictionary<string, List<int>>();
foreach (var criteria in searchCriteria)
{
Int32 i = 0;
Int32 startingIndex = 0;
var indexes = new List<int>();
while (i > -1)
{
i = source.IndexOf(criteria, startingIndex);
if (i > -1)
{
startingIndex = i + 1;
indexes.Add(i);
}
}
if (indexes.Any())
{
result.Add(criteria, indexes);
}
}
return result;
}
private void CalculateMinMax(KeyValuePair<String, List<int>> current, ref int min, ref int max)
{
int j = current.Value[_entryIndex[current.Key]];
if (j < min)
{
min = j;
}
int indexPlusWordLength = j + current.Key.Length;
if (indexPlusWordLength > max)
{
max = indexPlusWordLength;
}
}
}
I would appreciate it if someone could point out where did I go wrong in my algorithm. Moreover, I kinda feel this is a very naive implementation. Maybe there is a better approach to solve this problem than trying to try out combinations of indexes?
Thanks!
This is a much simpler algorithm that will give you the shortest substring.
void Main()
{
String source = "aaa wwwww fgffsd ththththt sss ww sgsgsgsghs bfbfb hhh sdfg kkk " +
"dhdhtrherhrhrthrthrt ddfhdetehehe kkk wdwd aaa vcvc hhh zxzx sss ww nbnbn";
List<String> criteria = new List<string> { "kkk", "aaa", "sss ww", "hhh" };
var result = GetAllSubstringContainingCriteria(source, criteria)
.OrderBy(sub => sub.Length).FirstOrDefault();
// result is "kkk wdwd aaa vcvc hhh zxzx sss ww"
}
private IEnumerable<string> GetAllSubstringContainingCriteria(
string source, List<string> criteria)
{
for (int i = 0; i < source.Length; i++)
{
var subString = source.Substring(i);
if (criteria.Any(crit => subString.StartsWith(crit)))
{
var lastWordIndex =
GetLastCharacterIndexFromLastCriteriaInSubstring(subString, criteria);
if (lastWordIndex >= 0)
yield return string.Join(" ", subString.Substring(0, lastWordIndex));
}
else
continue;
}
}
private int GetLastCharacterIndexFromLastCriteriaInSubstring(
string subString, List<string> criteria)
{
var results = criteria.Select(crit => new {
index = subString.IndexOf(crit),
criteria = crit});
return results.All(result => result.index >= 0)
? results.Select(result => result.index + result.criteria.Length).Max()
: -1;
}
Let the Java built-in classes do the work. How about converting your criteria to a regular expression Pattern. If the criteria are X or Y or Z . . ., convert this into a regular expression of the form "(X)|(Y)|(Z)|...", compile it, and execute it against the source string.
This, of course, returns the leftmost match. You could code a very straightforward loop that iterates across all occurrences, caches them, and chooses the shortest--or the leftmost shortest--or, if two or more are equally short, then all of those.
public Dictionary<string, List<double>> GetTotalLengt_VolumehofMemberUsed_AlongStaadName()
{
var memberData = new Dictionary<string, List<double>>();
var sec_Dict = _sectionDetails.GetAllMemberIDsWithinATable();
string _stdName = "";
double _memLength = 0.0; double _totalMemLength = 0.0;
double _memVolume = 0.0; double _totalMemVolume = 0.0;
foreach(string s in sec_Dict.Keys)
{
foreach(int n in sec_Dict.Values)
{
_memLength = this.Getlengthofmember(n);
_totalMemLength = _memLength + _totalMemLength;
_memVolume = this.GetVolumeofmember(n);
_totalMemVolume = _memVolume + _totalMemVolume;
}
}
this.STAAD_NAME = _stdName;
this.TOTAL_MEMBER_LENGTH = _totalMemLength;
this.TOTAL_MEMBER_VOLUME = _totalMemVolume;
List<double> list = new List<double>();
list.Add(this.TOTAL_MEMBER_LENGTH);
list.Add(this.TOTAL_MEMBER_VOLUME);
memberData.Add(this.STAAD_NAME, list);
return memberData;
}
This foreach(int n in sec_Dict.Values) is wrong in my code. Please show me that how should I fetch each int from the List<int> values in my dictionary.
Because the type of each of values is List<int> and you want to cast it to int.
Use this Code:
foreach(string s in sec_Dict.Keys)
{
foreach(int n in sec_Dict[s])
{
_memLength = this.Getlengthofmember(n);
_totalMemLength = _memLength + _totalMemLength;
_memVolume = this.GetVolumeofmember(n);
_totalMemVolume = _memVolume + _totalMemVolume;
}
}
Your values are List<int>, so you need to declare n as List<int>
The Dictionary which you have constructed is bit difficult to handle. For this reason Microsoft BCL team has introduced a new Collection type called MultiValueDictionary. Please find the below link for more details
http://blogs.msdn.com/b/dotnet/archive/2014/08/05/multidictionary-becomes-multivaluedictionary.aspx
As your values are of type List<int>
you should change your foreach to:
foreach (List<int> valueList in sec_Dict.Values)
{
foreach (int n in valueList)
{
_memLength = this.Getlengthofmember(n);
_totalMemLength = _memLength + _totalMemLength;
_memVolume = this.GetVolumeofmember(n);
_totalMemVolume = _memVolume + _totalMemVolume;
}
}
So I'm working on a game that uses a coordinate system, and I want to populate the map with a certain number of trees. The way I'm doing it (and it may not be the best way) is picking a random set of coordinates, checking to see if those coordinates are in the list of locations with trees in them, and if not adding the tree to the map, and adding those coordinates to the list. My instinct was to store the coordinates as an array, however I can't seem to figure out the syntax for it. Here's what I have:
int boardWidth = 10;
int boardHeight = 10;
int numTrees = 75;
List<int[]> hasTree = new List<int[]>();
public Transform tree;
Transform[,] SetTrees(Transform[,] map) {
int treex = Random.Range(0,boardWidth-1);
int treey = Random.Range(0,boardHeight-1);
int[] treeCoords = new int[] { treex,treey };
int treeCount = 0;
while(treeCount < numTrees){
if (hasTree.Contains(treeCoords)){
treex = Random.Range(0,boardWidth-1);
treey = Random.Range(0,boardHeight-1);
}
else{
map[treex,treey] = (Transform)Instantiate(tree, new Vector3(i*tileWidth, 10, j*tileHeight), Quaternion.AngleAxis(90, Vector3.left));
hasTree.Add(treeCoords);
treex = Random.Range(0,boardWidth-1);
treey = Random.Range(0,boardHeight-1);
treeCount++;
}
}
return(map);
}
Any thoughts?
If I were you I'd try something like this:
int boardWidth = 10;
int boardHeight = 10;
int numTrees = 75;
var rnd = new Random();
var query =
from x in Enumerable.Range(0, boardWidth)
from y in Enumerable.Range(0, boardHeight)
orderby rnd.NextDouble()
select new { x, y };
var board = new bool[boardWidth, boardHeight];
foreach (var pair in query.Take(numTrees))
{
board[pair.x, pair.y] = true;
}
Keep It Simple Silly:
Transform[,] SetTrees(Transform[,] map) {
for(int treeCount = 0; treeCount < numTrees; treeCount++){
int treex = Random.Range(0,boardWidth-1);
int treey = Random.Range(0,boardHeight-1);
map[treex,treey] = new TreeTransform(treex, treey}
}
return(map);
}
Bury the details of Tree creation in its constructor TreeTransform, where it belongs.
Who cares about a creation ordering of the trees on the board? it has no use.
There is no reason for the number of trees to be exact, so just ignore duplicates.
Simplify the code then it might be easier to determine your best course of action.
I simplify by breaking down the problem until its so simple I can't really see how not to do it !!!
I am guessing how some of this code works here but I think you want something like this ...
Transform[,] SetTrees(Transform[,] map) {
for (int i = 0; i < numTrees; i++){
if(!AddTreeTo(map)){
--i;
}
}
return(map);
}
bool AddTreeToMap(Transform[,] map)
{
int[] treeCoord = GetRandomCoord(map.Width, map.Height);
if (!map[treeCoord[0],treeCoord[1]].HasTree()){
map[treex,treey] = (Transform)Instantiate(tree, new Vector3(i*tileWidth, 10, j*tileHeight), Quaternion.AngleAxis(90, Vector3.left));
map[treeCoord[0],treeCoord[1]].Add(treeCoords);
return true;
}
return false;
}
int[] GetRandomTreeCoord(int maxX, int maxY)
{
int treex = Random.Range(0,maxX-1);
int treey = Random.Range(0,maxY-1);
int[] treeCoords = new int[] { treex,treey };
return treeCoords;
}
I have my code to decrypt the string to numbers but i have the result
every time "-1-1-1"
protected void submit_Click(object sender, EventArgs e)
{
decryptScore(txtscore.Text);
}
public string decryptScore(string s)
{
string[] firstDigitArray = { "f85au", "kt50e", "cmt5s", "v5072", "fc5i3", "56f7l", "7gj81", "yn90y", "5o3ko", "ntakn" };
string[] secondDigitArray = { "hkym6", "xj97c", "54v6q", "nawf9", "9e1gp", "9gww9", "5oj5p", "0ba5t", "yizld", "bt064" };
string[] thirdDigitArray = { "uku91", "rn2k4", "uuq78", "nkurt", "8kxqs", "9p7kc", "hd8x6", "57b6o", "7iucu", "do6bq" };
string[] fourthDigitArray = { "0hdro", "0wqrc", "wa5ny", "857mg", "3f7ro", "kerph", "0mhw1", "tpb8f", "8rho3", "4hc11" };
string[][] digitsArray = {firstDigitArray, secondDigitArray, thirdDigitArray, fourthDigitArray};
string decryptedScore = "";
int scorelength = s.Length / 5;
for (int i = 0; i < scorelength; i++)
{
string d = s.Substring(i * 5, 5);
decryptedScore += (digitsArray[i][i].IndexOf(d));
}
score.Text = decryptedScore;
return decryptedScore;
}
public string decryptScore(string s)
{
var firstDigitArray = new List<string>{ "f85au", "kt50e", "cmt5s", "v5072", "fc5i3", "56f7l", "7gj81", "yn90y", "5o3ko", "ntakn" };
var secondDigitArray = new List<string> { "hkym6", "xj97c", "54v6q", "nawf9", "9e1gp", "9gww9", "5oj5p", "0ba5t", "yizld", "bt064" };
var thirdDigitArray = new List<string> { "uku91", "rn2k4", "uuq78", "nkurt", "8kxqs", "9p7kc", "hd8x6", "57b6o", "7iucu", "do6bq" };
var fourthDigitArray = new List<string> { "0hdro", "0wqrc", "wa5ny", "857mg", "3f7ro", "kerph", "0mhw1", "tpb8f", "8rho3", "4hc11" };
var digitsArray = new List<List<string>>{ firstDigitArray, secondDigitArray, thirdDigitArray, fourthDigitArray };
string decryptedScore = "";
int scorelength = s.Length / 5;
for (int i = 0; i < scorelength; i++)
{
string d = s.Substring(i * 5, 5);
decryptedScore += (digitsArray[i].FindIndex(x=>x==d));
}
return decryptedScore;
}
PS: Don't forget if scorelength is greater or equal to 4 you'll get an exception(since you only have 4 digitArrays)
In the line
decryptedScore += (digitsArray[i][i].IndexOf(d));
you are searching for a string a single string for a the value. You need to search the array.
Change this line to
decryptedScore += Array.IndexOf(digitsArray[i], d);
This will search the array for a particular value and return you it's index. As a result you will get the required number back.
Replace
decryptedScore += (digitsArray[i][i].IndexOf(d));
with
decryptedScore += Array.IndexOf(digitsArray[i], d);