Distributing k points among n entities to find distance between points? - c#

I have a known list of n entries. I also have a known quantity of k points.
I need to distribute those k points as equally distant to one another as I can among the n entries. The end result is that I know what distance (d) is between the points.
Example:
So if we had n={0, 1, 2, 3, 4, 5} entries (n=6) and k=3, and we assume we can start from 0 always, then we'd end up with a result of 0, 2 and 4 getting a point each as the "distance" between them all is 1 (d=1).
I've been racking my brain on how to calculate the d for an hour now. I'm not sure how to do it.
n will always be a list of integers.
k will always be less than n and an integer
d should always be an integer where k*d <= n.
I tried using the sqrt of n but that wouldn't work if I get fractions.
I know this sounds like a math assignment but it's not homework. It's just a problem I'm sitting with for a game.
How do I calculate d? I use C#.
Turns out what I actually needed was to discretely distribute k indices across n elements.
See an example of it in action here; https://youtu.be/SC0qwkNzvmo
You can see how bombs are distributed among players. That is what I needed but had difficulty explaining.

It seems to me that you just need this:
int[] indices = new [] { 0, 2, 4, };
double distance =
Enumerable
.Range(0, indices.Length)
.SelectMany(
i => Enumerable.Range(i + 1, indices.Length - i - 1),
(i, j) => Math.Sqrt(indices[i] * indices[i] + indices[j] * indices[j]))
.Average();
If you're trying to discretely distribute the k indices across the n elements, then this is it:
int n = 6;
int k = 3;
int[] bs =
Enumerable
.Range(0, k)
.Select(i => i * n / k)
.ToArray();
That gives 0, 2, 4.

Related

Confusing value's used in find Missing number between 1 - X

Hi guys im learning c# currently and Im trying to run threw some interview questions to try and understand them and learn in the process.
I found a question, How do you find the missing number in a given integer array of 1 to 100?
I think I get the General Idea of having to get the sum, Then the Sum of the Sequence then Minus X - Y;
But im confused about the code example below, Why is he using * (arr.Length + 2) When the Equation is n*(n+1)/2 I know its correct but shouldnt this be (arr.Length + 1) * (arr.Length) / 2 According tot he formula
Im terribly confused.
//array to find the missing number between 1 and 10
// Simplicity, We will take number 1 to 10 i where Number 5 is missing in the sequence.
int[] arr = { 1, 2, 3, 4, 6, 7, 8, 9, 10 };
int missingNumber,Totalsum;
// Accoreding to series rule, calculating sum of total numbers upto 10
//sum of first n natutal numbers=n*(n+1)/2
Totalsum = (arr.Length + 1) * (arr.Length + 2) / 2;
// Missing number is calculating.
foreach (int item in arr)
{
Totalsum = Totalsum - item;
}
missingNumber = Totalsum;
Console.WriteLine("missing number : {0}",missingNumber);
Not a Assignment. Just someone trying to learn programming by them selves looking up random questions to learn practically
Where i got the question
https://simpleprogrammer.com/programming-interview-questions/
The Explanation I found
https://www.interviewsansar.com/find-missing-number-between-1-to-n-in-array-in-c/
The comment gives the answer to your question:
// Accoreding to series rule, calculating sum of total numbers upto 10
//sum of first n natutal numbers=n*(n+1)/2
It's just that it's a number sequence that "should have 10 numbers but actually only has 9"
The formula needs n to be 10, but the array has a length of 9. 9+1 is n, 9+2 is n+1

Any combination of additions of a specified number set to reach a specific target value

I am looking for a way to get all possible combination of numbers to reach a specified target value.
The values of the number set can repeat.
For example:
Number set is 4, 5, 6, 7, 8
The value that I want to reach is 16.
So as result I would like to have something like:
4+4+4+4
4+4+8
5+5+6
...
Any solutions which I've found are only without repeatitions like here:
Efficient algorithm to find a combination, which summation is equal to a known number, in a set of number
Thanks in advance!
You can use the same recursive approach too. But don't remove used items from the set of possible items. If you want to distinguish between a+b+a and a+a+b variants - traverse all set, if not - only items from the current position.
function Partitions(Sum, A[], CurIdx, Result)
if Sum = 0
output Result
//all variants with permutations
for i = 0 to A.Length - 1
if A[i] <= Sum
Partitions(Sum - A[i], A[], i, Result + A[i])
//variants without permutations
for i = CurIdx to A.Length - 1
if A[i] <= Sum
Partitions(Sum - A[i], A[], i, Result + A[i])
// you don't need this, just for record:
//variant without repeats essentially does the next:
Partitions(Sum - A[i], A[].Remove i-th item, i, Result + A[i])
or (note i+1 start point for the next recursion level)
for i = CurIdx to A.Length - 1
if A[i] <= Sum
Partitions(Sum - A[i], A[], i + 1, Result + A[i])

C# formula to determine index

I have a maths issue within my program. I think the problem is simple but I'm not sure what terms to use, hence my own searches returned nothing useful.
I receive some values in a method, the only thing I know (in terms of logic) is the numbers will be something which can be duplicated.
In other words, the numbers I could receive are predictable and would be one of the following
1
2
4
16
256
65536
etc
I need to know at what index they appear at. In othewords, 1 is always at index 0, 2 at index 1, 4 at index 3, 16 is at index 4 etc.
I know I could write a big switch statement but I was hoping a formula would be tidier. Do you know if one exists or any clues as the names of the math forumula's I'm using.
The numbers you listed are powers of two. The inverse function of raising a number to a power is the logarithm, so that's what you use to go backwards from (using your terminology here) a number to an index.
var num = 256;
var ind = Math.Log(num, 2);
Above, ind is the base-2 logarithm of num. This code will work for any base; just substitute that base for 2. If you are only going to be working with powers of 2 then you can use a special-case solution that is faster based on the bitwise representation of your input; see What's the quickest way to compute log2 of an integer in C#?
Try
Math.Log(num, base)
where base is 2
MSDN: http://msdn.microsoft.com/en-us/library/hd50b6h5.aspx
Logarithm will return to You power of base from you number.
But it's in case if your number really are power of 2,
otherwise you have to understand exactly what you have, what you need
It also look like numbers was powered to 2 twice, so that try this:
private static int getIndexOfSeries(UInt64 aNum)
{
if (aNum == 1)
return 0;
else if (aNum == 2)
return 1;
else
{
int lNum = (int)Math.Log(aNum, 2);
return 1+(int)Math.Log(lNum, 2);
}
}
Result for UInt64[] Arr = new UInt64[] { 1, 2, 4, 16, 256, 65536, 4294967296 } is:
Num[0] = 1
Num[1] = 2
Num[2] = 4
Num[3] = 16
Num[4] = 256
Num[5] = 65536
Num[6] = 4294967296 //65536*65536
where [i] - index
You should calculate the base 2 logarithm of the number
Hint: For the results:
0 2
1 4
2 16
3 256
4 65536
5 4294967296
etc.
The formula is, for a give integer x:
Math.Pow(2, Math.Pow(2, x));
that is
2 to the power (2 to the power (x) )
Once the formula is known, one could solve it for x (I won't go through that since you already got an answer).

What algorithm suit me, with issue?

I have a Matrix [M x N], in each cell of matrix, there is an array [N](sorted from max to min).
I have to write a function that reconstruct this Matrix to one data-structure,
ordered from min to max?
With optimal memory and time.
My solution is not optimal and extremely highly costs (memory&time).
Solution:
Iterate over the matrix and pull each array to one Array: O(N^2 - memory&time)
after that sort this array O(N - memory&time).
What algorithm suits me best?
This answer might be a little bit off topic since it is using f# and not c#, however the algorithm could be reused but I thought it was faster to write it in f#. This is a sample solution where I merge all the results as described in my comment to the question:
let rec orderedMerge xs ys =
match xs,ys with
| [],l | l,[] -> l
| x::xs', y::ys' ->
if x < y then x :: (orderedMerge xs' ys)
else y :: (orderedMerge xs ys')
let rec orderNestedMerge xxs =
match xxs with
| x::[] -> x
| x::y::[] -> orderedMerge x y
| x::y::xxs' -> orderedMerge (orderedMerge x y) (orderNestedMerge xxs')
let rec orderNested2Merge xxxs =
match xxxs with
| x::[] -> orderNestedMerge x
| x::y::[] -> orderedMerge (orderNestedMerge x) (orderNestedMerge y)
| x::y::xxxs' -> orderedMerge (orderedMerge (orderNestedMerge x) (orderNestedMerge y)) (orderNested2Merge xxxs')
let l1 = [1;5;6;10]
let l2 = [2;3;9;11]
let l3 = [3;4;5;8]
let l4 = [2;8;9;12]
let m1 = [l1;l2]
let m2 = [[l1;l2];[l3;l4]]
let r1 = orderedMerge l1 l2
let r2 = orderNestedMerge m1
let r3 = orderNested2Merge m2
Results:
val m1 : int list list = [[1; 5; 6; 10]; [2; 3; 9; 11]]
val m2 : int list list list = [[[1; 5; 6; 10]; [2; 3; 9; 11]]; [[3; 4; 5; 8]; [2; 8; 9; 12]]]
val r1 : int list = [1; 2; 3; 5; 6; 9; 10; 11]
val r2 : int list = [1; 2; 3; 5; 6; 9; 10; 11]
val r3 : int list = [1; 2; 2; 3; 3; 4; 5; 5; 6; 8; 8; 9; 9; 10; 11; 12]
I haven't calculated how it perform but I think it is quire well. On a side note, I don't think you can implement a solution that has both optimal memory and time utilization, you have to focus one of them first and then make the other one as good as possible.
UPDATE:
One improvement you could do to this solution is to use tail recursion, it shouldn't be that hard to rewrite it to use tail recursion.
You are basically trying to implement merge sort, but with part of the sub cases already sorted. If you just recursively merge pairs of lists the way merge sort does, and assuming you actually meant that the length of the lists is approximately the same length as the length of a matrix side, then your run time is O(n^3 log(n^2)) rather than your original suggestion which is O(n^3 log(n^3)), or it's about 33% faster (I'm grossly misusing bigO notation here).
The algorithm you talk about cannot possibly have a time and space complexity of O(N^2). I've specified my analysis below:
Algorithm 1 - Complexity: O(MN^2 log (MN^2))
This is the algorithm you've described.
1) Iterate over the matrix and pull each array to one Array: It will take O(M*N^2) time to copy all the elements
2) After that sort this array. The fastest you could possibly sort is O(M*N^2 log (M*N^2)).
Thus, the overall time complexity will be O(M*N^2 log (M*N^2)).
Algorithm 2 - Complexity: O(MN^2 × log MN)
Adapted from Algorithm for n-way merge
Create a priority queue
Iterate through each array among the MxN arrays
enqueue the pair (nextNumberIn({i,j}th array), {i,j}) using the first value as priority key
While queue not empty
dequeue head (number, {i,j}) of queue
output number
if {i,j}th array not depleted
enqueue (nextNumberIn({i,j}th array), {i,j})
Since adding elements to a priority queue can be done in logarithmic time, item 2 is O(M*N × log M*N). Since (almost all) iterations of the while loop adds an element, the whole while-loop will be O(M*N^2 × log M*N), where M*N^2 is the total number of elements to sort.
Since the complexity for step 3 dominates, the overall time complexity will be O(M*N^2 × log M*N).
Space Complexity
For both the algorithms above, the space complexity will be minimum of O(M*N^2) to store the new array. In addition to that, algorithm #1 will require about O(log (M*N^2)) additional space for the sorting step, while algorithm #2 will require an additional space of O(M*N) for the priority queue.

Selecting a number from natural number < n excluding a possibility

Given n natural number starts from 0, and b which is a number in between 0 to n
I wish to randomly select a number excluding b.
Say n is 5
then The number to be selected is {0,1,2,3,4,5}
say b is 4,
then my random selection is from {0,1,2,3,5}
A way to do this is to do a while loop, until the random.nextInteger() does not find a 4.
Is there a easy to to do this other than using a while loop?
I would write a simple extension:
// N.B. : min is inclusive, max is exclusive; so range is: [min,max) - {toExclude}
public static int Next(this Random rand, int min, int max, int toExclude)
{
int v = rand.Next(min, max - 1);
if (v < toExclude)
return v;
return v + 1;
}
Usage:
var random = new Random();
var val = random.Next(0,6,4); // 6 because max is exclusive in C# random.Next()
Your approach is the best in my optinion. It is simple and elegant, and even for m=2 it is O(1) on average (The expected number of redraws is 1/2 + 1/4 + 1/8 + .... < 1).
If you want to avoid the worst case of infinite loop there is an alternative, though I doubt it will have real performance impact.
draw a random double in range [0,1]. let it be d. If d < b/m: draw a number in range [0,b) and return it.
Else (d > b/m) - draw a random number in range [b+1,m] and return it.
Note, it is indeed uniform distributed because:
There are m+1 numbers in range 0,...,m, but only m "valid" numbers (excluding b).
There are b numbers in range 0,1,...,b-1 - so the probability of the number being in this range assuming uniform distribution is b/m - which is exactly P(d < b/m).
In java it will look similar to this:
int m = 5, b = 4;
Random r = new Random();
double d = r.nextDouble();
if (d < ((double)b)/m) {
System.out.println(r.nextInt(b));
} else {
System.out.println(r.nextInt(m-b) + b + 1);
}
Here is another approach if you prefer:
import random
def random_unifrom(n,b):
assert b < n and n > 0 and b > 0
nMinusOneList = [i for i in range(n) if i != b]
lSize = len(nMinusOneList)
randIndex = random.randint(0, lSize-1)
return nMinusOneList[randIndex]
I wrote this in python just for simplicity.
creating the nMinusOneList has complexity of O(n).
returning the random index complexity depends on the random function you are using.
At the end, you loose nothing if you take this approach instead of a while loop, but even if you use the while loop approach, if the random function is random (!!) then you should not have a problem. However, my approach above excludes the number you do not need from the very beginning.
In C#, the one line I use in python might be a couple of lines which consists of a for loop on the range 0 to n, with a condition that the x (for loop index) does not equal to b, in building the list, and then you will have the list that excludes b.

Categories

Resources