How to handle carry over when adding numbers? - c#

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"
}

Related

How do I make a round robin match schedule?

I am building a tournament schedule with round robin style match order. I have an algorithm set up to build the matches, however the match order is not what I am looking for. I am struggling to develop an algorithm that will build the matches in my desired order. See example below with a 6 team bracket. Each vertical line represents a row in the tournament. The far left number represents the base team seed and who they will play in each round.
Note: The only thing that is really important to me is that the 1 and 2 seed play in the last round of the tournament. And preferably that 1 v 6, 2 v 5, 3 v 4 happens in the first round of the tournament. All other matches aren't as important. Thank you in advance for any help you can provide.
1: 6 5 4 3 2
2: 5 4 3 6 1
3: 4 6 2 1 5
4: 3 2 1 5 6
5: 2 1 6 4 3
6: 1 3 5 2 4
Here is my current code:
int numTeams = teamList.Count;
int rounds = (numTeams - 1);
int halfSize = numTeams / 2;
List<Team> teams = new List<Team>();
teams.AddRange(teamList); // Copy all the elements.
teams.RemoveAt(0); // To exclude the first team.
int teamSize = teams.Count;
for (int round = 0; round < rounds; round++)
{
int teamIdx = round % teamSize;
Team baseTeam1 = teams[teamIdx];
Team baseTeam2 = teamList[0];
// save each team to a match
for (int idx = 1; idx < halfSize; idx++)
{
int firstTeamIdx = (round + idx) % teamSize;
int secondTeamIdx = (round + teamSize - idx) % teamSize;
Team subTeam1 = teams[firstTeamIdx];
Team subTeam2 = teams[secondTeamIdx];
// save each team to a match
}
}
Sometimes asking the question helps figure out the answer. As it turns out, my current algorithm was creating what I wanted, just in opposite order. What I did to fix was create a new varible inside the first for loop called actualRound:
int actualRound = rounds - round; // this will reverse the round order

Linear interpolation between two numbers with steps

I've a little trouble finding out how to linearly interpolate between two numbers with a defined number of intermediate steps.
Let's say I want to interpolate between 4 and 22 with 8 intermediate steps like so : Example
It's easy to figure out that it's x+2 here. But what if the starting value was 5 and the final value 532 with 12 intermediate steps? (In my special case I would need starting and ending value with 16 steps in between)
If you have two fence posts and you put k fence posts between them, you create k + 1 spaces. For instance:
| |
post1 post2
adding one posts creates two spaces
| | |
post1 post2
If you want those k + 1 spaces to be equal you can divide the total distance by k + 1 to get the distance between adjacent posts.
d = 22 - 4 = 18
k = 8
e = d / (k + 1) = 18 / 9 = 2
In your other case example, the answer is
d = 532 - 5 = 527
k = 12
e = d / (k + 1) = 527 / 13 ~ 40.5
I hesitate to produce two separate answers, but I feel this methodology is sufficiently unique from the other one. There's a useful function which may be exactly what you need which is appropriately called Mathf.Lerp().
var start = 5;
var end = 532;
var steps = 13;
for (int i = 0; i <= steps; i++) {
// The type conversion is necessary because both i and steps are integers
var value = Mathf.Lerp(start, end, i / (float)steps);
Debug.Log(value);
}
For actually doing the linear interpolation, use Mathf.MoveTowards().
For figuring out your maximum delta (i.e. the amount you want it to move each step), take the difference, and then divide it by the number of desired steps.
var start = 4;
var end = 22;
var distance = end - start;
var steps = 9; // Your example technically has 9 steps, not 8
var delta = distance / steps;
Note that this conveniently assumes your distance is a clean multiple of steps. If you don't know this is the case and it's important that you never exceed that number of steps, you may want to explicitly check for it. Here's a crude example for an integer. Floating point methods may be more complicated:
if (distance % delta > 0) { delta += 1; }

Specific Combinations in C#, unable to grasp it

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;
}

How to get the size of a number in .net?

I want with a given double number to return its "size" (known as |number|, or number of digit without the numbers after the dot), for example:
12.324654 -> 2
12 -> 2
0.99 -> 0
1.01 -> 1
901 -> 3
-0.99 -> 0
-9.999 -> 1
There must be a function is .net that I dont familiar with that does it..
Thanks.
Try log10(max(abs(number), 0.5)) + 1 rounded down.
Or, in actual C# syntax:
(int)(Math.Log10(Math.Max(Math.Abs(number), 0.5)) + 1)
OK, how does that work?
At first of all, p = log10(x) is the base-10 logarithm of x; that is to say, the value such that 10 raised to the p-th power (or 1 followed by p zeros) equals x. The logarithm essentially measures the length of the number, except that it's a smooth function of x:
(Note that, in languages that don't provide a base-10 logarithm function, we can always calculate it as log10(x) = log(x) / log(10), where log() is the logarithm function in any base.)
For example, we have
log10(1) = 0.0
log10(10) = 1.0
log10(100) = 2.0
log10(1000) = 3.0
but also e.g.:
log10(5) = 0.69897
log10(50) = 1.69897
log10(500) = 2.69897
log10(5000) = 3.69897
In general, n ≤ log10(x) < n+1 whenever 10n ≤ x < 10n+1.
Looking at the values above, it should be easy enough to see that, to get the number of base-10 digits in a whole number, we should round its base-10 logarithm down to the nearest whole number and add 1 (because we want the length of 10 to be 2, not 1).
However, there are a few more edge cases to consider:
First, the original questioner wanted the length of −x to equal the length of x. The logarithm is only defined for positive numbers, so we replace x by its absolute value to make it always positive.
Second, the original questioner also wanted the length of numbers between 0 and 1 to be zero. The logarithm, however, can take arbitrarily large negative values:
log10(0.1) = −1.0
log10(0.01) = −2.0
log10(0.001) = −3.0
log10(0.0001) = −4.0
and indeed, log10(0) = −∞. To satisfy this requirement, we simply make sure that the number whose length we calculate can never go below 0.5 by using the maximum of it and 0.5 as the input to log10(). (We could use any number between 0.1 and 1 as the cutoff, but 0.5 happens to be a nice round binary fraction.)
Also, we have to make sure to add +1 to the logarithm before rounding it, so that the number that we round is always non-negative. That's because (int) in C# actually rounds negative numbers up towards zero. For example, since log10(0.5) &approx; −0.3, the expression (int)Math.Log10(0.5) + 1 (rounding before addition) would evaluate to 0+1 = 1  rather than the expected 0.
((int)Math.Abs(12.324654)).ToString().Length
Math.Abs will convert to positive number (don't want to count the negative sign)
(int) will drop the digits following the decimal point
ToString() converts to a string ===> "12"
Length tells you how many characters there are
there is an edge case where (int)( some number ) == 0, where the length is going to give you 1-- you may not want this, so be aware of the possibility
now, what you COULD do is make this an extention method....
public static class Utils
{
public static int Size(this double n)
{
int i = (int)Math.Abs(n);
if ( i == 0 ) return 0;
return i.ToString().Length;
}
}
12.324654.Size() == 2;
You could do something like below to account for your 0 digits returning zero length
private static int CountAbsoluteDigits(double p) {
int absolute = (int)Math.Abs(p);
if (0 == absolute)
return 0;
else
return absolute.ToString().Length;
}
...
var length = CountAbsoluteDigits(12.324654);
This is the output I got with the numbers you supplied..
12.324654 -> 2
12 -> 2
0.99 -> 0
1.01 -> 1
901 -> 3
-0.99 -> 0
-9.999 -> 1
Stealing Quintin's format:
private static int CountAbsoluteDigits(double p) {
int ip = (int)p;
int answer = 0;
while (ip!=0) {
answer++;
ip/=10;
}
return answer;
}
No trick (e.g., abs(), if) required in this.
Courtsey Muad'Dib
int GetLength(double value){
return ((int)Math.Abs(value*10d)).ToString().Length - 1
}
Converting to integer and converting the result to a string will only work if the value is within the range of an int. If you need values above 2 billion, you'll either need to work with logs, or deal convert the double to a string.
static int GetLength(double d)
{
d = Math.Abs(d);
if (d < 1.0) return 0;
if (double.IsInfinity(d)) return int.MaxValue;
if (double.IsNaN(d)) return 0;
return (int)Math.Floor(Math.Log10(d)) + 1;
}
static int GetLength2(double d)
{
d = Math.Abs(d);
if (d < 1.0) return 0;
if (double.IsInfinity(d)) return int.MaxValue;
if (double.IsNaN(d)) return 0;
string s = d.ToString("E"); // returns a string in the format "1.012435E+001"
return int.Parse(s.Substring(s.Length - 3)) + 1;
}
static void Test(double d) { Debug.WriteLine(d + " -> " + GetLength(d) + ", " + GetLength2(d)); }
static void Main(string[] args)
{
Test(0);
Test(0.125);
Test(0.25);
Test(0.5);
Test(1);
Test(2);
Test(10);
Test(10.5);
Test(10.25);
Test(10.1243542354235623542345234523452354);
Test(999999);
Test(1000000);
Test(1000001);
Test(999999.111);
Test(1000000.111);
Test(1000001.111);
Test(double.MaxValue);
Test(double.MinValue);
Test(double.PositiveInfinity);
Test(double.NegativeInfinity);
Test(double.NaN);
Test(double.Epsilon);
}
Results:
0 -> 0, 0
0.125 -> 0, 0
0.25 -> 0, 0
0.5 -> 0, 0
1 -> 1, 1
2 -> 1, 1
10 -> 2, 2
10.5 -> 2, 2
10.25 -> 2, 2
10.1243542354236 -> 2, 2
999999 -> 6, 6
1000000 -> 7, 7
1000001 -> 7, 7
999999.111 -> 6, 6
1000000.111 -> 7, 7
1000001.111 -> 7, 7
1.79769313486232E+308 -> 309, 309
-1.79769313486232E+308 -> 309, 309
Infinity -> 2147483647, 2147483647
-Infinity -> 2147483647, 2147483647
NaN -> 0, 0
4.94065645841247E-324 -> 0, 0

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