I need to be able to attach an integer number to another integer as a decimal part, for example:
For numbers 12345 and 12345678 I would want to get: 12345,12345678
Note: The numbers' length is variable.
I have tried casting numbers to string to measure their length and then divide them accordingly but there must be a more efficient and fast way than this.
var left = 12345;
var right = 12345678;
var total = left + (right / Math.Pow(10, Math.Floor(Math.Log10(right)) + 1));
A very quick and dirty approach, with no error checking at all
var total = Double.Parse(string.Concat(left, ",", right));
Based on https://stackoverflow.com/a/2506541/1803777, more performance can be obtained without usage of logarithm function.
public static decimal GetDivider(int i)
{
if (i < 10) return 10m;
if (i < 100) return 100m;
if (i < 1000) return 1000m;
if (i < 10000) return 10000m;
if (i < 100000) return 100000m;
if (i < 1000000) return 1000000m;
if (i < 10000000) return 10000000m;
if (i < 100000000) return 100000000m;
if (i < 1000000000) return 1000000000m;
throw new ArgumentOutOfRangeException();
}
int a = 12345;
int b = 12345678;
decimal x = a + b / GetDivider(b);
try counting using the following:
Math.Floor(Math.Log10(n) + 1);
then continue just as you stated.
Source: How can I get a count of the total number of digits in a number?
Related
Hi I am sick of searching I could not find the exact code for my question.
I need to code the sum of the odd numbers from 1 to 100
and sum of the even numbers from 2 to 100.
This is what i have so far.
Thank you so much
// 1) using for statement to Sum Up a Range of values using Interactive
Console.WriteLine(" Sum Up a Range of values entered by User ");
Console.WriteLine();
// 2) Declare the Variables to be used in the Project
string strFromNumber, strToNumber;
int fromNumber, toNumber;
int sum = 0;
int i, even = 0, odd = 0;
int[] array = new int[10];
// 3) Prompt the User to Enter the From Number to Sum From
Console.Write("Enter the From Number to Sum From: ");
strFromNumber = Console.ReadLine();
fromNumber = Convert.ToInt32(strFromNumber);
// 4) Prompt the User to Enter the To Number to Sum To
Console.Write("Enter the To Number to Sum To: ");
strToNumber = Console.ReadLine();
toNumber = Convert.ToInt32(strToNumber);
// 5) Use for statement to Sum up the Range of Numbers
for (i = fromNumber; i <= toNumber; ++i)
{
sum += i;
}
if //(array[i] % 2 == 0) //here if condition to check number
{ // is divided by 2 or not
even = even + array[i]; //here sum of even numbers will be stored in even
}
else
{
odd = odd + array[i]; //here sum of odd numbers will be stored in odd.
}
Console.WriteLine("The Sum of Values from {0} till {1} = {2}",
fromNumber, toNumber, sum);
Console.ReadLine();
There is no need to write the complex code which you have written.
Problem is to calculate the sum of arithmetic progression. The formula to find the sum of an arithmetic progression is Sn = n/2[2a + (n − 1) × d] where, a = first term of arithmetic progression, n = number of terms in the arithmetic progression and d = common difference.
So in case of odd numbers its a = 1, n = 50 and d = 2
and in case of even numbers its a = 2, n = 50 and d = 2
and if you try to normalize these above formulas, it will be more easy based on your problem.
the sum of the first n odd numbers is Sn= n^2
the sum of the first n even numbers is n(n+1).
and obviously, it's very simple to loop from ( 1 to 99 with an increment of 2 ) and ( 2 to 100 with an increment of 2 )
In the simplest case, you can try looping in fromNumber .. toNumber range while adding
number either to even or to odd sum:
// long : since sum of int's can be large (beyond int.MaxValue) let's use long
long evenSum = 0;
long oddSum = 0;
for (int number = fromNumber; number <= toNumber; ++number) {
if (number % 2 == 0)
evenSum += number;
else
oddSum += number;
}
Console.WriteLine($"The Sum of Values from {fromNumber} till {toNumber}");
Console.WriteLine($"is {evenSum + oddSum}: {evenSum} (even) + {oddSum} (odd).");
Note, that you can compute both sums in one go with a help of arithmetics progression:
private static (long even, long odd) ComputeSums(long from, long to) {
if (to < from)
return (0, 0); // Or throw ArgumentOutOfRangeException
long total = (to + from) * (to - from + 1) / 2;
from = from / 2 * 2 + 1;
to = (to + 1) / 2 * 2 - 1;
long odd = (to + from) / 2 * ((to - from) / 2 + 1);
return (total - odd, odd);
}
Then
(long evenSum, long oddSum) = ComputeSums(fromNumber, toNumber);
Console.WriteLine($"The Sum of Values from {fromNumber} till {toNumber}");
Console.WriteLine($"is {evenSum + oddSum}: {evenSum} (even) + {oddSum} (odd).");
From the code snippet you shared, it seems like the user gives the range on which the sum is calculated. Adding to #vivek-nuna's answer,
Let's say the sum of the first N odd numbers is given by, f(n) = n^2 and
the sum of the first N even numbers is given by, g(n) = n(n + 1).
So the sum of odd numbers from (l, r) = f(r) - f(l - 1).
Similarly, the sum of even numbers from (l, r) = g(r) - g(l - 1).
Hope this helps.
I need to divide a variable distance in a very specific way. The spacing for the divisions must be 40 units minimum, and 80 units maximum.
I've tried several different various of this code but I am struggling to wrap my head around how to include the min/max variable in my division.
double totaldist = X;
double division = totaldist / 80;
double roundup = Math.Ceiling(division);
double space = totaldist / roundup;
double increment = 0;
while (increment < totaldist)
{
increment = increment + space;
}
The attached code is obviously short of what I want to accomplish, I'm not sure how to bridge the gap. Thank you
So all you have to do is loop over all the possible divisors and pick the best one. The simplest way to accomplish this is as follows:
public static int remainder(int totalDist)
{
double minRemainder = (totalDist % 40) / 40;
int bestDivision = 40;
for (var i = 40; i <= 80; i++)
{
double cRemainder = (totalDist % i) / i;
if (totalDist % i == 0) return i;
else if (cRemainder < minRemainder) { minRemainder = cRemainder; bestDivision = i; }
}
return bestDivision;
}
This will always return the closest result. Even if there is no real solution, it will still provide an approximate answer as a fallback.
I'd test every divisor for mod 0 (no remainder)
int d = 420;
int s = 40;
for(; s <= 80; s++){
if(d%s==0)
break;
}
if(s==81)
Console.Write("There is no suitable divisor");
else
Console.Write($"{d} divides into {s} segments of {d/s} with no remainder");
If you want to minimise the segment length (greater number of segments) start at 80 and work towards 40 in the loop instead - set your d to 480, start at 80 and you should get "80 segments of length 6" rather than "40 segments of length 12"
You can even get cute with your loop and have no body:
for(; s <= 80 && d%s > 0; s++){ }
But it's not quite so readable/self explanatory
I have a function (some kind of rotation) for argument i in [1001..999999] range:
int a = ((i - 1) % (1000000 - 1000) + 1001)
As you can see
i = 1001 a = 2001
...
i = 5000 a = 6000
...
i = 999999 a = 1999
I want to inverse this function, i.e. to have i = f(a), such that if, say, a = 6000 is given I want to have 5000 as a return etc. Unfortunately, I've experienced a problem with inversing % (modulo operation). Are there any suggestions in rotating numbers or reversing the above formula?
As you can see, since (1000000 - 1000) is quite greate a value, you get for (i - 1) % (1000000 - 1000) just two cases
i - 1 if i < 999001
i - 1 - 999001 if i >= 999001
And in order to inverse the formula, you have to analyze just these two cases only and you'll get as easy as
if (a > 2000)
return a - 1000;
else
return a + 998000;
Test
for (int i = 1001; i <= 999999; ++i) {
// forward, the formula from the question
int a = ((i - 1) % (1000000 - 1000) + 1001);
// ...and inverse one
int r = (a > 2000) ? a - 1000 : a + 998000;
// do we have reversed value != initial one?
if (r != i) {
// this will never happen
Console.Write("Counter example {0}", i);
break;
}
}
TLDR: Codility "Challenge" - my results: Where is the error?
Short Description (Full Description): Given an Array, split the array into two (Upper and lower parts) and give the minimum difference between two possible parts in absolute value.
My thought process is:
create an "Upper" and "Lower" bucket for sums.
In one pass of the array, we get a sum for the "Upper" bucket.
Then, one array value at a time, move the numbers into lower (Upper-n, Lower+n).
At each step, get the difference (Abs(Upper-lower))
Monitor lowest "Minimum"
Submitted Code:
public int solution(int[] A)
{
// Quick results:
if (A == null) return -1;
if (A.Length == 0) return -1; // Can't split
if (A.Length == 1) return -1; // Can't split
if (A.Length == 2) return Math.Abs(A[0] - A[1]); // Only one way to split
// Hold above/below/result...
long lower = 0;
long upper = 0;
var min = long.MaxValue;
// Pass#1: Sum All to get "Upper"
for (long i = 0; i < A.Length; i++) upper += A[i];
// Pass#2:
// foreach in array
// ... Shift number from upper to lower
// ... Calculate new difference/minimum
for (var i = 0; i < A.Length; i++)
{
lower += A[i];
upper -= A[i];
var diff = Math.Abs(upper - lower);
min = Math.Min(min, diff);
if (diff == 0) return 0;
}
return (int) min;
}
Out of 13 test cases, the only one that Codility fails me on is: "Small Numbers". it says "Wrong answer, expected 20 got 0". It doesn't show the test data it uses, so I'm left guessing as to "Why".
Where is my error? I think I've stared at it too much, but I can't seem to figure out what case would "break" my function.
Edit: Fixed translation. Submitted code to Codility uses a Foreach, and the code I have here is a For. Corrected the variables in the loop.
The problem is that you didn't take into account one of the rules: 0 < P < N.
Your second loop is assuming 0 < P <= N.
Assume this input:
10, 10, -20
Your code would return 0 but 40 would be correct.
Fix:
Change your second loop header to
for (var i = 0; i < A.Length - 1; i++)
Proof
So I have pow - a list containing numbers. I have to examine other numbers like this: Get all the digits and sum the numbers from pow having the same index as the certain digit.
So if I check number 4552 I need to get pow[4]+pow[5]+pow[5]+pow[2]. Because I'm a noob I try to convert the number to string, get the characters with loop and then convert back to int to get the index. So the code is as follows for getting the sums between 4550 and 4559:
for (int i = 4550; i < 4560; i++)
{
int sum = 0;
for (int j = 0; j < i.ToString().Length; j++)
{
sum += pows[Convert.ToInt32(i.ToString()[j])]; //here is the error - index was out of range
//do something with sum (like store it in another list)
}
}
So what is wrong with that?
EDIT: To avoid confusion... pow has 10 elements, from indexes 0-9.
SOLUTION: The issue with my code was that I got the character code not the digit itself, thanks Steve Lillis. Though the solution provided by Dmitry Bychenko is far more superior to my attempt. Thank you all.
What you're looking for is similar to a digital root:
Modulus (% in C#) is easier and faster than conversion to string:
public static int DigitalRootIndex(IList<int> list, int value) {
if (value < 0)
value = -value;
int result = 0;
// for value == 4552
// result == list[4] + list[5] + list[5] + list[2]
while (value > 0) {
int index = value % 10;
result += list[index];
value /= 10;
}
return result;
}
...
int test = DigitalRootIndex(pow, 4552);
This bit of code gets a single character such as '4' which is character code 59:
c = i.ToString()[j]
Then this bit of code turns that char into an integer. It doesn't parse it like you're expecting, so the result for '4' is 59, not 4:
Convert.ToInt32(c)
Do this instead:
int.Parse(c.ToString())
Something like this (quick and dirty try)?
int currentDigit;
int sum;
for (int i = 4550; i < 4560; i++)
{
sum = 0;
currentDigit = i;
while (currentDigit > 0)
{
if (pow.Count > (currentDigit % 10))
{
sum += pow[((currentDigit % 10))];
}
}
}
Note that lists have zero based index so when you do pow[1], you are actually accessing second element in the list. Is that what you want?