Related
I have a list of n objects. I want to grab a maximum of n items (-n previous items and n + next items), starting from the selected index. I want a method for this, in which I provide the list with certain parameters.
How can I achieve this in C#?
First example:
int selectedIndex = 5
int itemsToTake = 4 (2 previous and 2 next)
Returned list = 3-4-5-6-7
Second example:
int selectedIndex = 1
int itemsToTake = 4 (take 1 previous and 3 next, because list starts with 0)
Returned list = 0-1-2-3-4
I have already tried a combination of list.skip().take(), only that didn't go so well.
Example:
nextIndex = nextIndex - prevIndex + 1;
return List.Skip (prevIndex) .Take (nextIndex) .ToList ();
An inefficient but visually aesthetic way of doing it:
public static IEnumerable<T> Nearby<T>(this IEnumerable<T> source,
int selectedIndex, int itemsToTake)
{
var left = source.Take(selectedIndex).Reverse().Take(itemsToTake / 2).Reverse();
var middle = source.ElementAt(selectedIndex);
var right = source.Skip(selectedIndex).Skip(1).Take(itemsToTake / 2);
return left.Append(middle).Concat(right);
}
Usage example:
var source = Enumerable.Range(0, 10);
Console.WriteLine($"Result: {String.Join(", ", source.Nearby(5, 5))}");
Output:
Result: 3, 4, 5, 6, 7
Skip + Take should work fine, try this:
int firstIndex = selectedIndex - itemsToTake / 2;
firstIndex = firstIndex < 0 ? 0 : firstIndex;
return list.Skip(firstIndex).Take(itemsToTake);
First, make sure that the list contains enough elements:
if(itemsToTake + 1 > List.Count)
return List.ToList(); //copy the list
The first index you want to take is (not considering sequence borders):
var firstIndex = selectedIndex - itemsToTake / 2;
The corresponding last index would be firstIndex + n.
Then, make sure that the range is valid
if(firstIndex < 0)
firstIndex = 0;
if(firstIndex + nitemsToTake >= List.Count)
firstIndex = List.Count - 1 - itemsToTake ;
And finally do as you tried:
return List.Skip(firstIndex).Take(itemsToTake + 1).ToList();
You need to handle the special case of when selectedIndex - itemsToTake / 2 is less than 0:
public static List<T> Take<T>(this List<T> list, int selectedIndex, int itemsToTake) {
if (selectedIndex - n / 2 < 0) {
return list.Take(itemsToTake + 1).ToList();
}
return list.Skip(selectedIndex - itemsToTake / 2).Take(itemsToTake +1).ToList();
}
public static IEnumerable<T> Nearby<T>(IEnumerable<T> source, int selectedIndex, int itemsToTake)
{
itemsToTake = ((itemsToTake/2)*2)+1;
Queue<T> queue = new Queue<T>();
bool foundItem = false;
int afterItemCount = 0;
int recommendedAfterItemCount = itemsToTake/2;
foreach(var pair in source.Select((t, i) => new {t, i}))
{
T t = pair.t;
int i = pair.i;
queue.Enqueue(t);
if (itemsToTake < queue.Count) queue.Dequeue();
if (i == selectedIndex) foundItem = true;
else if (foundItem) afterItemCount += 1;
bool enoughItems = queue.Count == itemsToTake;
bool enoughAfterItems = recommendedAfterItemCount <= afterItemCount;
if (enoughItems && enoughAfterItems) break;
}
foreach(T t in queue)
{
yield return t;
}
}
i am trying to use an Interpolation Search algorithm to find a value and return it. (Which is what it does currently). I am trying to modify it so it returns a number which i can use to find the closest values to the inputted item if the item which was searched was not found within the array.
public static int InterSearch(double[] array, double data)
{
int size = array.Length;
int lo = 0;
int mid = -1;
int hi = array.Length - 1;
int index = -1;
int count = 0;
while (lo <= hi)
{
mid = (int)(lo + (((double)(hi - lo) / (array[hi] - array[lo])) * (data - array[lo])));
count++;
if (array[mid] == data)
{
index = mid;
break;
}
else
{
if (array[mid] < data)
lo = mid + 1;
else
hi = mid - 1;
}
}
return index;
}
You can use an aggregate that find the closest value.
this is a custom extension method but you get the idea.
public static double GetValueClosestTo(this List<double> values, double closestTo)
{
return values.Aggregate((x, y) => Math.Abs(x - closestTo) < Math.Abs(y - closestTo) ? x : y);
}
Let's say you have the following array {1, 5, 9.2, 6, 17} and you test the following number {6, 15, 5.2}. You will use the following code
var sourceArray = new [] {1, 5, 9.2, 6, 17}.ToList() // for simplicity i use a list
var closestToX = sourceArray.GetValueClosestTo(6); // this return 6
closestToX = sourceArray.GetValueClosestTo(15); // this return 17
closestToX = sourceArray.GetValueClosestTo(5.2); // this return 5
I am trying to write a method to calculate the sum of the odd numbers in all the numbers less than the given number. so eg. CalcOdd(7) would return 5 + 3 + 1 = 9. CalcOdd (10) would return 9 + 7 + 5 + 3 + 1 = 25 etc
The method needs to take in a number, subtract 1, then recursively work backwards adding all odd numbers until it reaches 0. This is what I have so far.
private static int CalcOdd(int n)
{
if (n <= 1)
return 1;
else
if (n % 2 == 0)
n--;
return n + CalcOdd(n - 2);
}
It doesn't work so well, it includes the number passed in in the addition which is not what I want. Can anyone suggest a better way of doing this ? I would also loke to be able to port the answer to work for even numbers and add the option to include the original passed in number in the answer.
Many thanks
Why would you use recursion here? Just loop; or better, figure out the math to do it in a simple equation...
The fact is that C# doesn't make for excellent deep recursion for things like maths; the tail-call isn't really there at the moment.
Loop approach:
private static int CalcOdd(int n)
{
int sum = 0, i = 1;
while (i < n)
{
sum += i;
i += 2;
}
return sum;
}
You could do this with recursion as you say, but if you wish to do it quicker, then I can tell you that the sum of the n first odd numbers is equal to n*n.
private static int CalcOdd(int n) {
if (n<=1)
return 0;
if (n%2 == 1)
n--;
int k = n/2;
return k*k;
}
The reason this works is:
Every even number is of the form 2k, and the odd number before it is 2k-1.
Because 2*1-1 = 1, there are k odd numbers below 2k.
If n is odd, we don't want to include it, so we simply go down to the even number below it and we automatically have what we want.
Edited to fix broken code.
the sum of odd numbers less than a given number is a perfect square.
get the whole part of (n/2) to get the number of odd number less than itself.
square that and voila!
private static int CalcSumOdd(int n)
{
int i;
int.tryParse(n / 2, out i);
return i*i;
}
for even numbers its:
int i = n/2;
return i*(i+1);
correction. The above "even number sum" includes the original number "n". ie fn(12) = 42 = 2 + 4 + 6 + 8 + 10 + 12
if you want to exclude it, you should either unilaterally exclude it, or remove it with logic based on a passed in parameter.
Here is a correction,
int CalcOdd(int n)
{
n--; // <----
if (n <= 1)
return 0; // <----
else
if (n % 2 == 0)
n--;
return n + CalcOdd(n); // <----
}
i'm new here but this seems like a silly recursion exercise, given it can be done with a simple equation:
int sum(n,isEven,notFirst) {
int c=1; //skip the else
if (isEven) c=2;
if (notFirst) n-=2;
return ((n+c)*((n+c)/2))/2; }
classic discrete math sum series..
sum from 1 to 100 (odds and evens) is ((100+1)*(100/2))=5050
edit: in my code here, if you're calculating the sum of odds with n being even, or vice versa, it doesn't work, but i'm not going to put the work into that (and slop the code) right now. i'll assume your code will take care of that by the time it hits the function.. for example 7/2 isn't an int (obviously)
Why use recursion?
private Int32 CalcOdd(Int32 value)
{
Int32 r = 0;
{
while (value >= 1)
{
value--;
if (value % 2 != 0)
{
r += value;
}
}
}
return r;
}
Use a helper function. CalcOdd consists of testing n to see if it is even or odd; if it is even, return helper(n); if it is odd, return helper(n-2).
The helper function must handle three cases:
1) n is less than 1; in this case return 0.
2) n is even, in this case return helper(n-1).
3) n is odd, in this case return n+helper(n-1).
public static int CalcOdd(int n) {
// Find the highest even number. (Either n, or n-1.)
// Divide that by 2, and the answer should be the square of that number.
n = (n & 0x3FFFFFFE) >> 1;
return (int)Math.Pow(n, 2);
}
private static int CalcOdd(int n) {
n -= 1;
if ((n & 1) == 0) n--;
if (n <= 1) return 1;
return n + CalcOdd(n - 1);
}
But I would say doing loops is better and cleaner.
private static int CalcOdd(int n) {
int i, r = 1;
for (i = 3; i < n; i+=2)
r += i;
return r;
}
Since you want the option of including or excluding the first answer (and, keeping your "recursion" constraint in mind):
int calcOdd(int n, bool includeN)
{
if( !includeN )
return calcOdd(n-1, true);
if(n<=1)
return 1;
else
if(n%2 == 0)
n--;
return n+calcOdd(n-1, true);
}
The includeFirst, if passed as true, will include n in the calculations. Otherwise, the next layer down will start "including N".
Granted, as others have said, this is a horribly inefficient use of recursion, but... If you like recursion, try Haskell. It's a language built almost entirely on the concept.
int CalcOdd(int n)
{
n -= 1;
if (n <= 0)
return 0;
if (n % 2 == 0)
n--;
return n + CalcOdd(n);
}
This function is also recursive, and it has parameters which makes you able to decide wether to do even or odd number and wether you want to include the first number or not. If you are confused as to how it works, remember that bools also can be seen as 1 (true) and 0 (false)
int Calc(int n, bool even = false, bool includeFirst = false)
{
n -= !includeFirst;
if (n <= 0)
return 0;
if (n % 2 == even)
n--;
return n + Calc(n - includeFirst, even);
}
HÃ¥kon, I have ported your code to c# in VS 2008 as follows
static int Calc(int n, bool bEven, bool bIncludeFirst)
{
int iEven = Bool2Int(bEven);
int iIncludeFirst = Bool2Int(bIncludeFirst);
n -= 1 - iIncludeFirst;
if (n <= 0)
return 0;
if (n % 2 == iEven)
n--;
return n + Calc(n - iIncludeFirst, bEven, bIncludeFirst);
}
private static int Bool2Int(bool b)
{
return b ? 1 : 0;
}
It seems to be working. Now is there anything I can do to optomise ? i.e. I dont want to have to parse those bools to ints every time etc ?
I'd isolate the 'make it odd' part from the 'sum every other descending number' part: (forgive the Python)
def sumEveryTwoRecursive(n):
if n <= 0:
return 0
return n + sumEveryTwoRecursive(n - 2)
def calcOdd(n):
return sumEveryTwoRecursive(n - (2 if n % 2 else 1))
Just because there isn't one here yet, I've decided to use the LINQ hammer on this nail...
(borrowed from Nick D and Jason's pair programmed answer here)
void Main()
{
GetIterator(7, true, false).Sum().Dump();
// Returns 9
GetIterator(10, true, false).Sum().Dump();
// Returns 25
}
public IEnumerable<int> GetIterator(int n, bool isOdd, bool includeOriginal)
{
if (includeOriginal)
n++;
if (isOdd)
return GetIterator(n, 1);
else
return GetIterator(n, 0);
}
public IEnumerable<int> GetIterator(int n, int odd)
{
n--;
if (n < 0)
yield break;
if (n % 2 == odd)
yield return n;
foreach (int i in GetIterator(n, odd))
yield return i;
}
#include <iostream>
using namespace std;
int sumofodd(int num);
int main()
{
int number,res;
cin>>number;
res=sumofodd(number);
cout<<res;
return 0;
}
int sumofodd(int num)
{ if(num<1) return 0;
if (num%2==0) num--;
return num+sumofodd(num-1);
}
I have an array:
private int[,] _blocks = new int[6, 4];
It represents a set of blocks which is 6 deep horizontally and 4 deep vertically. Graphically it looks like this:
alt text http://www.angryhacker.com/toys/array.png
I need a function that would take in a number, from 1 to 24 and return the array element that matches. So for number 14, I'd get back _blocks[1, 2];
I've created a simplistic function:
private int GetBlockByPosition(int position)
{
int count = 0;
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 4; j++)
{
if (++count == position)
return _blocks[i, j];
}
}
return -1;
}
But this seems very wasteful and smells bad. Is there a more elegant and faster way?
Both in the horizontal direction and the vertical direction, you can see a pattern in your table of numbers. You can determine the horizontal position with position / 6 and a vertical position with position % 6 -- the modulo operation.
private int GetBlockByPosition(int position)
{
return _blocks[((position + 6) / 6) - 1, position % 6];
}
This makes mathematical sense. Division increases in chunks, and modulo (remainder on division) increases one by one. The math is pretty simple.
I'm not sure I follow, but why can't you just calculate he indexes based on the position? Something like this:
return _blocks[((position - 1) % 6),((position + 5) / 6) - 1];
I think you can do like this :
private int GetBlockByPosition(int position)
{
return _blocks[(position - 1 ) % 6 , (position - 1) / 6];
}
Are the numbers in your array ACTUALLY 1, 2, 3, ... or are you just using them as an example?
If there isn't any pattern to the data in your array that can be taken advantage of, then it looks like the simplistic option may be your best bet.
Or you could always make a one-time pass of the entire structure and build a hash table to be used in subsequent calls...
Depending on your definition of elegant, the following is perhaps a more functional way of solving the problem:
class Program
{
static void Main(string[] args)
{
var blocks = new int[,] {{1,2,3,4,5,6},{7,8,9,10,11,12},{13,14,15,16,17,18},{19,20,21,22,23,24}};
var position = blocks.FirstPositionOf(14);
Console.WriteLine(position.X + "," + position.Y + " has the element " + blocks[position.X,position.Y]);
}
}
class PositionTuple
{
public int X {get; set;}
public int Y {get; set;}
}
static class ArrayExtensions
{
public static IEnumerable<int> AsEnumerable(this int[,] someTwoDimensionalArray)
{
foreach (var num in someTwoDimensionalArray)
yield return num;
}
public static PositionTuple FirstPositionOf(this int[,] someTwoDimensionalArray, int someNumber)
{
return someTwoDimensionalArray
.AsEnumerable()
.Select((num, index) => new { Number = num, Tuple = new PositionTuple { X = index / (someTwoDimensionalArray.GetUpperBound(1) + 1), Y = index % (someTwoDimensionalArray.GetUpperBound(1)+1) }})
.Where(pair => pair.Number == someNumber)
.Select(pair => pair.Tuple)
.First();
}
}
I would make a more flexible function that can be used elsewhere if you need to
public static T Get2DArrayValueByPosition<T> (T[,] arr, int position)
{
// Gets the size of the array in first dimention
step = arr.GetUpperBound(0) + 1;
return arr[(position / step ), position % step];
}
Comprehensive solution considering the corner cases:
private int GetBlockByPosition(int position)
{
if(position % 6 == 0) { // last cells in each row. 6 gives [0,5]
return _blocks[(position / 6) - 1, (position - 1) % 6];
} else { // 11 gives [1,4]
return _blocks[position / 6 , (position % 6) - 1];
}
}
int result = GetByPosition(_blocks, 14);
private int GetByPosition(int[,] array, int position)
{
return GetByPositionBaseZero(array, position - 1);
}
private int GetByPositionBaseZero(int[,] array, int position)
{
int width = array.GetLength(0);
return array[position % width, position / width];
}
I am trying to create a function which will give me alphabet position when an index is passed. It will be same like how excel shows it's columns. A...Z, AA,AB.... I wrote the below function to get the results upto Z. It looks like
static string GetColumnName(int index)
{
const int alphabetsCount = 26;
if (index <= alphabetsCount)
{
int code = (index - 1) + (int)'A';
return char.ConvertFromUtf32(code);
}
return string.Empty;
}
This works fine until 'Z'. It return 'A' if I pass 1 and return 'B' if I pass 2 and so on. But, I am not able to figure out how will I get AA when I pass 27 to this function. I guess I need a recursive method to find it.
Any inputs to this problem will be great!
Edit
This is suggested by Tordek. But his code will fail in numbers like 52, 78 etc. Added workaround for that and here is the final working code.
static string GetColumnName(int index)
{
const int alphabetsCount = 26;
if (index > alphabetsCount)
{
int mod = index % alphabetsCount;
int columnIndex = index / alphabetsCount;
// if mod is 0 (clearly divisible) we reached end of one combination. Something like AZ
if (mod == 0)
{
// reducing column index as index / alphabetsCount will give the next value and we will miss one column.
columnIndex -= 1;
// passing 0 to the function will return character '#' which is invalid
// mod should be the alphabets count. So it takes the last char in the alphabet.
mod = alphabetsCount;
}
return GetColumnName(columnIndex) + GetColumnName(mod);
}
else
{
int code = (index - 1) + (int)'A';
return char.ConvertFromUtf32(code);
}
}
Any recursive function can be converted into an equivalent iterative one. I find it always easy to think recursively first:
static string GetColumnName(int index)
{
const int alphabetsCount = 26;
if (index > alphabetsCount) {
return GetColumnName(index / alphabetsCount) + GetColumnName(index % alphabetsCount);
} else {
int code = (index - 1) + (int)'A';
return char.ConvertFromUtf32(code);
}
}
Which can be simple converted into:
static string GetColumnName(int index)
{
const int alphabetsCount = 26;
string result = string.Empty;
while (index > 0) {
result = char.ConvertFromUtf32(64 + (index % alphabetsCount)) + result;
index /= alphabetsCount;
}
return result;
}
Even so, listen to Joel.
See this question:
Translate a column index into an Excel Column Name
or this one:
How to convert a column number (eg. 127) into an excel column (eg. AA)
Though the first link has a correct answer right at the top and the 2nd has several that are not correct.
Recursion is one possibility -- if index > 26, you deal with index % 26 in this call and concatenate it to a recursive call on index / 26. However, iteration is often speedier and not hard to arrange for simple cases such as this one. In pseudocode:
string result = <convert `index % 26`>
while index > 26:
index = index / 26
result = <convert `index % 26`> + result
return result
or the like.
static string GetColumnName(int index)
{
const int alphabetsCount = 26;
string result = '';
if (index >= alphabetsCount)
{
result += GetColumnName(index-alphabetsCount)
}
return (string) (64 + index);
}
My C# is HORRIBLE AND RUSTY. Interpret this as pseudocode - it will almost certainly not compile, but may get you started.