i have big problem with explanation code under, meanwhile i made two loops function which does the same thing. I send my code to friend to tell me if it is possible to make is simplier :) So i get something like that.
Array.Copy(
myImageData
.Select(
(b, index) =>
(
index > rooflimit && index < floorlimit && b == 252 &&
(myImageData[index + width] == 0 || (myImageData[index + width] > 168 && myImageData[index + width] < 173)) &&
myImageData[index - width] == 252 &&
myImageData[index - (2 * width)] == 159
) ? (byte)172 : b
).ToArray(),
rooflimit + 1,
myImageData,
rooflimit + 1,
floorlimit - rooflimit - 1
);
My loops was doing something like that (above do the same thing):
when you get all pixelse, copy them to array of bytes
find all pixels which have value 255, pixel under has 0 or it is from range 168-173
pixel above has value 255 and pixel 2 times above has value 159
if i found that pixel change that value to 172
* pixel checking starts from the second row [0][1][2], and finish before last row, to be able check pixels above and under of current pixel *
I get almost about that code above, however i don't understand that part which starts with:
rooflimit + 1,
myImageData,
rooflimit + 1,
floorlimit - rooflimit - 1);
So i ask you for a help, thanks!
PS. please change topic if it is not good specified.
The last four parameters are the last parameters to Array.Copy. Your code would be clearer if you split it up:
byte[] tmp = myImageData.Select([... big lambda expression ...])
.ToArray();
Array.Copy(tmp, rooflimit + 1,
myImageData, rooflimit + 1,
floorlimit - rooflimit - 1);
I would also be very tempted to use a separate method instead of a lambda expression here - it's too complicated to be readable, really.
I think it's better see MSDN Array.Copy for this:
Copies a range of elements from an Array starting at the specified
source index and pastes them to another Array starting at the
specified destination index. The length and the indexes are specified
as 32-bit integers.
Related
I can't figure out how I can remove right-hand zeros in a given binary number like this:
00110000 -> 11
1000 -> 1
According to my example, I know I can perform a right-shift of 4 and 3 to remove the unwanted zeros but I don't know how could I calculate the number of bits needed for the right-shift.
This should work:
if (x != 0)
{
while (x % 2 == 0)
x = x >> 1;
}
It basically says keep bit shifting right whilst the number is even (doesn't have 1 as the right-most bit).
As mentioned in the comments by #Streamline, the loop alone won't work for a value of 0, so you have to check it's not 0 first.
No need to check every time round the loop for this though because if x != 0 then x >> n will never be 0 given the other looping condition that we stop when x % 2 != 0
If you need to know the number of bit-shifts, you can add a counter to the loop.
If you don't want to change the value of x, you can assign it to a temporary variable and use that instead.
I created LINQ implementation of mod10 algorithm.
The source code:
string number = "7992739871";
int mod10sum = number.Reverse()
.Select((c, i) => (c - '0') << ((i + 1) & 1)) // Double every other digit and sum the digits of the products (e.g., 10: 1 + 0 = 1, 14: 1 + 4 = 5)
.Sum(c => c - '0') % 10; // together with the undoubled digits from the original number
string checkDigit = (mod10sum == 0 ? 0 : 10 - mod10sum).ToString("0");
Console.WriteLine(checkDigit);
As per the example, 7992739871 number should have check digit as 3; however, what I am getting is 15.
What I am doing wrong? I am sure the mistake is very small but can't find it.
The problem is with the Select method. In order to sum up all the digits (as described in the algorithm) you would need to return 1 and 0 instead of 10, 1 and 4 instead of 14 (as in your example).
The easiest (but it does not have to be the most optimal) way to do that is to conert number from Select to string (14 -> "14") and then split the string characters using SelectMany.
So your code should look as follows:
int mod10sum = number.Reverse()
.SelectMany((c, i) => ((c - '0') << ((i + 1) & 1)).ToString())
.Sum(c => c - '0') % 10;
checkDigit = (mod10sum == 0 ? 0 : 10 - mod10sum).ToString("0");
Console.WriteLine(checkDigit);
A bit of theory
LINQ SelectMany returns IEnumerable<>. When you return string (which is IEnumerable) then that's why SelectMany "splits" returned string into characters.
Microsoft has very nice page (101 LINQ Samples) with different LINQ samples which should help you out.
EDIT
I would also recommend working on that conversion from int to string. I was working on similar project literally yesterday and in my case that conversion is a bit problematic from performance point of view as we call that method millions of times. If you have to calculate lots of mod10's then it might be not the best solution.
I would change the Sum.
At this point, you don't have a sequence of characters, but the single-or-doubled-as-appropriate value for each original digit.
Thus, you don't need to be subtracting 0, you need to be calculating the digit sum of each of these integers, and (since you know they'll be small) you can do this as simply as
.Sum(i => (i % 10) + (i / 10))
giving
string number = "7992739871";
int mod10sum = number.Reverse()
.Select((c, i) => (c - '0') << ((i + 1) & 1))
.Sum(i => (i % 10) + (i / 10)) % 10;
This should be more effecient than calling ToString() and iterating over the result.
I need to find the n-th term of this infinite series: 1,2,2,3,3,3,4,4,4,4...
Can you give me a constant time function for this task?
int i = 1;
while(true)
{
if(i = n)
//do things and exit the loop
i++;
}
I think this isn`t going to be a constant time function...
Edit
After reading more comments, it appears I misunderstood the question.
If you want to find the item at nth position an array in constant time, then the answer is trivial: x[n], because array access is constant time. However, if for some reason you were using some container where access time is not constant (e.g. linked list), or did not want to look up value in the array, you'd have to use the arithmetic series formulas to find the answer.
Arithmetic series tells us that the position n of the ith unique item would be
n = i * (i - 1) / 2
So we just need to solve for i. Using quadratic formula, and discarding the nonsensical negative option, we get:
i = Math.Floor( (1 + Math.Sqrt(1 + 8 * n)) / 2)
Original Response
I'm assuming you're looking for the position of the nth unique term, because otherwise the problem is trivial.
Sounds like the first occurrence of the nth unique term should follow arithmetic series. I.e. the position of nth unique term would be:
n * (n - 1) / 2
Given my understanding of the problem, this is more of a math problem than a programming one.
If the problem is:
Given an infinite series that consists of 1 copy of 1, 2 copies of 2, 3 copies of 3... n copies of n, what is the kth value in this series?
Now the first clue when approaching this problem is that there are 1 + 2 + 3... + n values before the first occurance of n + 1. Specifically there are (sum of the first n numbers) values before n+1, or (n)(n-1)/2.
Now set (n)(n-1)/2 = k. Multiply out and rationalize to n^2 - n - 2k = 0. Solve using quadratic equation, you get n = (1 + sqrt(1+8k))/2. The floor of this gives you how many full copies of n there are before, and happily, given zero based indexing, the floor gives you the value at the kth point in the array.
That means your final answer in c# is
return (int) Math.Floor((1 + Math.Sqrt(1 + 8 * k)) / 2);
Given non zero based indexing,
return (int) Math.Floor((1 + Math.Sqrt(-7 + 8 * k)) / 2);
public static long Foo(long index)
{
if (index < 0)
{
throw new IndexOutOfRangeException();
}
long nowNum = 0;
long nowIndex = 0;
do
{
nowIndex += nowNum;
nowNum++;
} while (nowIndex < index);
return nowNum;
}
I have two positions on a 3D system, say [15, 32, 42] and [16, 32, 42]
Is there a easy way to check if they are within a 1 block radius from each other?
This is what I have, but is there a better way of doing it:
if (pos[0] == pos1[0] / 32 || pos[0] == pos1[0] + 1 || pos[0] == pos1[0] - 1)
{
if (pos[1] == pos1[1] || pos[1] == pos1[1] - 1 || pos[1] == pos1[1] + 1)
{
if (pos[2] == pos1[2] || pos[2] == pos1[2] + 1 || pos[2] == pos1[2] - 1)
{
Thanks,
David
You can use Math.abs(pos[0]-pos1[0]) <= 1 to check if two coordinates in the same plane are at most 1 apart.
So all in all, your code could look like this:
if( Math.abs(pos[0]-pos1[0]) <= 1
&& Math.abs(pos[1]-pos1[1]) <= 1
&& Math.abs(pos[2]-pos1[2]) <= 1 )
{
Within a 1 block radius
}
Note that I do not understand why you divided your first equation by 32. I did not include that in this answer.
Note also that this solution makes things a little more readable, but that yours is correct too.
I haven't done this in c# but in Java I use JTS. http://geoapi.codeplex.com/ seems to provice the same functionality in c#. Then you will represent your points as Point objects and have all sorts of useful geospatial functions to use.
But for this case, are you looking for the "as the crow flies" distance, which is just pythagoras, or the "walking distance", which would involve finding the shortest valid route in a directed graph of footpaths?
Julian
I try to write a LINQ statement which returns me all possible combinations of numbers (I need this for a test and I was inspired by this article of Eric Lippert). The method's prototype I call looks like:
IEnumerable<Collection<int>> AllSequences( int start, int end, int size );
The rules are:
all returned collections have a length of size
number values within a collection have to increase
every number between start and end should be used
So calling the AllSequences( 1, 5, 3 ) should result in 10 collections, each of size 3:
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
Now, somehow I'd really like to see a pure LINQ solution. I am able to write a non LINQ solution on my own, so please put no effort into a solution without LINQ.
My tries so far ended at a point where I have to join a number with the result of a recursive call of my method - something like:
return from i in Enumerable.Range( start, end - size + 1 )
select BuildCollection(i, AllSequences( i, end, size -1));
But I can't manage it to implement BuildCollection() on a LINQ base - or even skip this method call. Can you help me here?
Enumerable.Range(1, 12)
.Select(x => (x - 1) + 1);
Think I've got it.
IEnumerable<List<int>> AllSequences(int start, int end, int size)
{
if (size == 0)
return Enumerable.Repeat<List<int>>(new List<int>(), 1);
return from i in Enumerable.Range(start, end - size - start + 2)
from seq in AllSequences(i + 1, end, size - 1)
select new List<int>{i}.Concat(seq).ToList();
}
Something like the following should do the job, I think.
public static IEnumerable<IEnumerable<int>> AllSequences(int start, int end,
int size)
{
return size <= 0 ? new[] { new int[0] } :
from i in Enumerable.Range(start, end - size - start + 2)
from seq in AllSequences(i + 1, end, size - 1)
select Enumerable.Concat(new[] { i }, seq);
}
The key to the solution is the compound from clause, which is quite handy for dealing with nested enumerables.
Notice that I've changed the method signature slightly to IEnumerable<IEnumerable<int>>, since this is more convenient when using (pure) LINQ. You can always convert it easily to a IEnumerable<ICollection<int>> at the end if you like, however.
Let me know if the code needs any explanation, but I'm hoping the LINQ syntax makes it reasonably clear.
Edit 1: Fixed bug and improved conciseness.
Edit 2:
Because I'm bored and have nothing better to do (no, not really), I thought I'd write an extension method that compute the combinations of a given list of elements, making use of the AllSequences method.
public static IEnumerable<IEnumerable<T>> Combinations<T>(this IList<T> source,
int num)
{
return AllSequences(0, source.Count - 1, num).Select(
seq => seq.Select(i => source[i]));
}
Perhaps not the most efficient way of computing combinations, but certainly pretty compact code!