Specific Combinations in C#, unable to grasp it - c#

I've been looking into combinations lately, I've tried various 3rd party solutions, and tried to get my head around it myself. Without success I might add.
I need to generate a 13 length string with all possible combinations of say.. int 0-2, I.E
0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 2
0 0 0 0 0 0 0 0 0 0 0 1 0
...
2 2 2 2 2 2 2 2 2 2 2 2 2
You probably get the drill, I'm aware I could just wrap this up in loops if I wanted a dirty solution. Any guidance or pointers are appreciated.

I'd be happy to write the code for you, but it seems like you are looking for intuition into the problem. So maybe this feels more like a "teach a man to fish" moment.
So let me ask you a few questions:
Let's generalize the problem to strings of length N. What does the N=1 case look like? It's
0
1
2
And what does the N=2 case look like? It's
00
01
02
10
11
12
20
21
22
I wonder if you can see how, given the N=1 case, we can easily derive (aka generate) the N=2 case in a very mechanical fashion. Now if you see the pattern for this specific case, can you say what the pattern is for the general case? i.e. If you happened to already have in your hand the answer for strings of length N, and I asked you to provide me with the answer for strings of length N+1 could you do so? If so you have the very definition of a recursive algorithm.
PS I think I'd call these combinations rather than permutations.

I can't help thinking of this as just adding number in a N-based numeric system (in your example a 3-base system).
I would write one method (if not already there in the framework or a library) that would allow you to switch bases. I.E:
String transformNumberFrom10BaseToXBase(int number, int base)
then just write a for loop (sorry, pseudo-c-like-code :) ):
for (int i = 0; i < base ^ 13; i++) {
print transformNumberFrom10BaseToXBase(i, base)
}
Ok, hope that helps or give you an idea on how to solve it :)

I've written quickly function that returns list of permutations, so if you have not time to write your own method, you can use it. length is permutation length, max is maximum number (in your case, it would be 2)
static List<int[]> getPermutationList(int length, int max)
{
List<int[]> perm_list = new List<int[]>();
int[] perm = new int[length];
for (int i = 0; i < length; ++i)
perm[i] = 0;
while(true)
{
for (int i = length - 1; ; --i)
{
if (i == -1)
return perm_list;
if (perm[i] < max)
{
perm[i]++;
for (int j = i + 1; j < length; ++j)
perm[j] = 0;
break;
}
}
int[] perm_copy = new int[length];
for (int i = 0; i < length; ++i)
{
perm_copy[i] = perm[i];
}
perm_list.Add(perm_copy);
}
return perm_list;
}

Related

Display rows of a 2d array in reverse order

I'm working on an app that is a "poor man's matrix" ie. 1 and 0 fall down the screen.
So far I have managed to get the 2d array to display one row on 1st user input, 2 rows on 2nd user input, 3 rows on 3rd user input etc.
The problem is, that the 1st row always stays at the top and I can't get the "drop-down" effect. It always appends an additional row of 1 and 0 bellow the previous row/row on user input.
Example - how it works so far:
my 2d array:
1 0 1 0 1 1 1 (1st row)
0 1 0 1 0 1 0 (2nd row)
0 0 1 0 1 0 1 (3rd row)
1 0 0 1 0 1 0 (4th row)
1st user input (Console.ReadKey();):
1 0 1 0 1 1 1 (1st row)
2cnd user input (Console.ReadKey();):
1 0 1 0 1 1 1 (1st row)
0 1 0 1 0 1 0 (2nd row)
3rd user input:
1 0 1 0 1 1 1 (1st row)
0 1 0 1 0 1 0 (2nd row)
0 0 1 0 1 0 1 (3rd row)
etc.
What I would like to achive is something similar but in "reverse" order.
Example - what I would like to achive:
1st user input:
1 0 1 0 1 1 1 (1st row)
2cnd user input:
0 1 0 1 0 1 0 (2nd row)
1 0 1 0 1 1 1 (1st row)
3rd user input:
0 0 1 0 1 0 1 (3rd row)
0 1 0 1 0 1 0 (2nd row)
1 0 1 0 1 1 1 (1st row)
So, to summerise, I would like to modify my existing code, so that the 1st row is always added last. Or possible start reading from the end of the array - last row. I have tried this, but I constantly get outOfRange error...
Any help would be welcome.
The code that just adds additional rows below an existing one:
public static int row = 0;
static void PrintRelevantLines()
{
Console.Clear();
if (rowl <= pnms.GetLength(0) - 1)
{
for (int i = 0; i <= row; i++)
{
for (int j = 0; j <= pnms.GetLength(1) - 1; j++)
{
Console.Write(pnms[i, j]);
}
Console.WriteLine();
}
}
row += 1;
}
Edit: The anwser I requested was
for (int i = row; i >= 0; i--;)
which was provided by: Pranav Hosangadi
But I accepted the anwser from Caius Jard, as he went over and beyond what I asked for.
Thank you.
Here you go; this is a matrix effect:
int width = 60; //draw 60 columns
int height = 20; //draw 20 rows
var chars = "1234567890-=qwertyuiop[]asdfghjkl;'#zxcvbnm,./!\"£$%^&*()_+QWERTYUIOP{}ASDFGHJKL:#~ZXCVBNM<>?".ToCharArray(); //create an array of chars to randomly choose and pump onto screen
var r = new Random(); //make only one Random. Never make a Random in a loop
while (true) //forever
{
int randCol = r.Next(0, width); //pick which column we will draw now
for (int i = 0; i < height; i++) { //for every row from top to bottom
Console.SetCursorPosition(randCol, i); //put the cursor there
Console.Write(chars[r.Next(chars.Length)]); //pump a random char
Thread.Sleep(200); //it's a bit fast otherwise
}
}
I haven't out and out given the solution for your exercise, because it looks like a homework (and I don't do homework), but I hope you can step through this and look at how it's working, and make the adaptations that you need to your program to get the result you're after
Perhaps, for example, you can keep your lines in a 2D buffer, and you can decide on a column randomly (like I did), and you can render it down the screen row by row, by reading down the column (or up), writing to the screen, the same column as you selected from the buffer, then select another column
Perhaps you can periodically insert lines into the buffer (scrolling new data through it).
Perhaps also, yoou can write the char first in white, then later overwrite it in grey just before you write the new char in white (the effect is hard to see when the screen has filled up)
Then you can write multiple chars at different offsets at the same time..
..then you can give it to the peeps at codegolf.se.com and they'll write you a version in like, 15 chars of 05AB1E or something

Interview questions

One of the basics of Computer Science is knowing how numbers are represented in 2’s complement. Imagine that you write down all numbers between A and B inclusive in 2’s complement representation using 32 bits. How many 1’s will you write down in all ?
Input:
The first line contains the number of test cases T (<=1000). Each of the next T lines contains two integers A and B.
Output:
Output T lines, one corresponding to each test case.
Constraints:
-2^31 <= A <= B <= 2^31 - 1
Sample Input:
-2 0
-3 4
-1 4
Sample Output:
63
99
37
Explanation:
For the first case, -2 contains 31 1’s followed by a 0, -1 contains 32 1’s and 0 contains 0 1’s. Thus the total is 63.
For the second case, the answer is 31 + 31 + 32 + 0 + 1 + 1 + 2 + 1 = 99
for (int i=1; i<line[0]; i++)
{
int numOf1s = 0;
for (int j=line[i].A; j<=line[i].B; j++)
{
for (unsigned int n=j; n>0; n>>=1)
numOf1s += n & 1;
}
printf("%d\n",numOf1s);
}

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).

How to handle carry over when adding numbers?

I am working on a piece of C# code that is adding digits that are stored in singly linked list. I have created a buffer singly linked list that contains 11 11 8 . the final list has to look like 1 2 9 . Each element that is bigger than 10 has to pass a carry over to the next digit and the result of the %10 is passed to the final list that will create 1 2 9.
How can I handle the carry over from each digit starting on the left to the right?
I have created the following logic, but obviously I am ignoring something.
for (int i = 0; i < bufferList.Size(); i++)
{
int mostLeftValue = Convert.ToInt32(bufferList.GetValue(i));
if (mostLeftValue >=10 && i + 1 < bufferList.Size())
{
int nextLeftValue = Convert.ToInt32(bufferList.GetValue(i + 1))+1;
int modedNextValue = nextLeftValue % 10;
finalList.InsertAtTail(modedNextValue);
}
int moddedValue = mostLeftValue %10 ;
finalList.InsertAtFront(moddedValue);
It doesn't look like you're carrying anything over from one value to the next. Also, you're adding to both ends of the output list, which seems suspect.
Here's an implementation for a simple List<int> - it basically does what you do when you add two numbers by hand, just without actually adding. Take the current number, add the carried number, store the "units", carry the "tens" over to the next column.
Number 11 11 8
Carry 0 ┌─ 1 ┌─ 1 ┌─ 0
Sum 11 │ 12 │ 9 │
Store 1 │ 2 │ 9 │ stop
Carry over 1 ─┘ 1 ─┘ 0 ─┘
You should be able to modify it for a linked list ([i] -> .GetValue(i), .Add -> .InsertAtTail, .Count -> .Size() or similar):
int carry = 0;
for (int i = 0; i < input.Count; i++)
{
int sum = carry + input[i]; // add previous carry
output.Add(sum % 10); // store the "units"
carry = sum / 10; // carry the "tens"
}
while (carry > 0) // anything left carried?
{
output.Add(carry % 10); // store the "units"
carry = carry / 10; // carry the "tens"
}

Generate N random and unique numbers within a range

What is an efficient way of generating N unique numbers within a given range using C#? For example, generate 6 unique numbers between 1 and 50. A lazy way would be to simply use Random.Next() in a loop and store that number in an array/list, then repeat and check if it already exists or not etc.. Is there a better way to generate a group of random, but unique, numbers?
To add more context, I would like to select N random items from a collection, using their index.
thanks
Take an array of 50 elements: {1, 2, 3, .... 50}
Shuffle the array using any of the standard algorithms of randomly shuffling arrays. The first six elements of the modified array is what you are looking for. HTH
For 6-from-50, I'm not too sure I'd worry about efficiency since the chance of a duplicate is relatively low (30% overall, from my back-of-the-envelope calculations). You could quite easily just remember the previous numbers you'd generated and throw them away, something like (pseudo-code):
n[0] = rnd(50)
for each i in 1..5:
n[i] = n[0]
while n[1] == n[0]:
n[1] = rnd(50)
while n[2] == any of (n[0], n[1]):
n[2] = rnd(50)
while n[3] == any of (n[0], n[1], n[2]):
n[3] = rnd(50)
while n[4] == any of (n[0], n[1], n[2], n[3]):
n[4] = rnd(50)
while n[5] == any of (n[0], n[1], n[2], n[3], n[4]):
n[5] = rnd(50)
However, this will break down as you move from 6-from-50 to 48-from-50, or 6-from-6, since the duplicates start getting far more probable. That's because the pool of available numbers gets smaller and you end up throwing away more and more.
For a very efficient solution that gives you a subset of your values with zero possibility of duplicates (and no unnecessary up-front sorting), Fisher-Yates is the way to go.
dim n[50] // gives n[0] through n[9]
for each i in 0..49:
n[i] = i // initialise them to their indexes
nsize = 50 // starting pool size
do 6 times:
i = rnd(nsize) // give a number between 0 and nsize-1
print n[i]
nsize = nsize - 1 // these two lines effectively remove the used number
n[i] = n[nsize]
By simply selecting a random number from the pool, replacing it with the top number from that pool, then reducing the size of the pool, you get a shuffle without having to worry about a large number of swaps up front.
This is important if the number is high in that it doesn't introduce an unnecessary startup delay.
For example, examine the following bench-check, choosing 10-from-10:
<------ n[] ------>
0 1 2 3 4 5 6 7 8 9 nsize rnd(nsize) output
------------------- ----- ---------- ------
0 1 2 3 4 5 6 7 8 9 10 4 4
0 1 2 3 9 5 6 7 8 9 7 7
0 1 2 3 9 5 6 8 8 2 2
0 1 8 3 9 5 6 7 6 6
0 1 8 3 9 5 6 0 0
5 1 8 3 9 5 2 8
5 1 9 3 4 1 1
5 3 9 3 0 5
9 3 2 1 3
9 1 0 9
You can see the pool reducing as you go and, because you're always replacing the used one with an unused one, you'll never have a repeat.
Using the results returned from that as indexes into your collection will guarantee that no duplicate items will be selected.
var random = new Random();
var intArray = Enumerable.Range(0, 4).OrderBy(t => random.Next()).ToArray();
This array will contain 5 random numbers from 0 to 4.
or
var intArray = Enumerable.Range(0, 10).OrderBy(t => random.Next()).Take(5).ToArray();
This array will contain 5 random numbers between 0 to 10.
int firstNumber = intArray[0];
int secondNumber = intArray[1];
int thirdNumber = intArray[2];
int fourthNumber = intArray[3];
int fifthNumber = intArray[4];
For large sets of unique numbers, put them in an List..
Random random = new Random();
List<int> uniqueInts = new List<int>(10000);
List<int> ranInts = new List<int>(500);
for (int i = 1; i < 10000; i++) { uniqueInts.Add(i); }
for (int i = 1; i < 500; i++)
{
int index = random.Next(uniqueInts.Count) + 1;
ranInts.Add(uniqueInts[index]);
uniqueInts.RemoveAt(index);
}
Then randomly generate a number from 1 to myInts.Count. Store the myInt value and remove it from the List. No need to shuffle the list nor look to see if the value already exists.
instead of using List use Dictionary!!
In case it helps anyone else, I prefer allocating the minimum number of items necessary. Below, I make use of a HashSet, which ensures that new items are unique. This should work with very large collections as well, up to the limits of what HashSet plays nice with.
public static IEnumerable<int> GetRandomNumbers(int numValues, int maxVal)
{
var rand = new Random();
var yieldedValues = new HashSet<int>();
int counter = 0;
while (counter < numValues)
{
var r = rand.Next(maxVal);
if (yieldedValues.Add(r))
{
counter++;
yield return r;
}
}
}
generate unique random nos from 1 to 40 :
output confirmed :
class Program
{
static int[] a = new int[40];
static Random r = new Random();
static bool b;
static void Main(string[] args)
{
int t;
for (int i = 0; i < 20; i++)
{
lab: t = r.Next(1, 40);
for(int j=0;j<20;j++)
{
if (a[j] == t)
{
goto lab;
}
}
a[i] = t;
Console.WriteLine(a[i]);
}
Console.Read();
}
}
sample output :
7
38
14
18
13
29
28
26
22
8
24
19
35
39
33
32
20
2
15
37

Categories

Resources