C# char calculation problem - c#

Im trying to do a permutation. of five in this case, so 5,4,3,2,1 . Eventually I want it to permute up to 100 which can be stored in my intX class. the calculation is fine, but I want to add up all individual numbers of the output, using the script below.
so 5! = 5x4x3x2x1 = 120 ----> 1+2+0 = 3. BUT My script below gives the output 147:
120
1
2
0
147
What am I doing wrong? I allready tried all converts, I started with just using the string[pointer] thingy, I tried different arrays etc.. but it all keeps coming up with 147. Is it some kind of representation thing?
static void Main(string[] args)
{
IntX total=1;
IntX totalsum = 0;
int perm = 5;
for (int i = perm; i > 0; i--)
{
total = total * i;
}
Console.WriteLine(total);
string answerstring = Convert.ToString(total);
char[] answerArray = answerstring.ToArray();
for (int x = 0; x < answerArray.Length; x++)
{
totalsum += Convert.ToInt32(answerArray[x]);
Console.WriteLine(answerArray[x]);
}
Console.WriteLine(totalsum);
}

The problem is the way you are converting your answerArray elements back to numbers
Convert.ToInt32(answerArray[x])
The above line takes the char 1 and converts it to an int. This is not the same as parsing it as an int. 1 is ascii character 49 so internally the char has an int representation of 49 and so that is what it is converted to (since this is just trying to do a type conversion rather than any kind of processing)
Similarly 2 = 50 and 0 = 48 so you get the total of 147.
What you want to do is use Integer.Parse to parse strings as numbers. I believe it should implicitly convert the char to a string before parsing it.
So your loop would be:
for (int x = 0; x < answerArray.Length; x++)
{
totalsum += int.Parse(answerArray[x].ToString());
Console.WriteLine(answerArray[x]);
}
You can also do it the way others suggested with subtracting chars. This works because the ascii value of 1 is 1 higher than the ascii value for 0. 2 is 2 higher, etc.
Of course this only works with single digit chars. If you ever want to convert more than two digit numbers into int from a string you'll need int.parse.
For what its worth I suspect that the character subtraction method is the most efficient since it is effectively just doing some very simple type conversion and subtraction. The parse method is likely to do a lot more stuff and so be a bit more heavyweight. I dont' you will notice a performance difference though.

The problem lies in here:
for (int x = 0; x < answerArray.Length; x++)
{
//Casting char to int, not what you want!
//totalsum += Convert.ToInt32(answerArray[x]);
//Parsing char to int, what you do want!
totalsum += int.Parse(answerArray[x]);
Console.WriteLine(answerArray[x]);
}

Instead of converting to an integer (which will take the ASCII character value), try using answerArray[x] - '0'.

(int)'0' is not equal to 0. You should use ((int)answerArray[x] - (int)'0')

Why bother changing it to a char array? You already have the information that you need.
while (total > 0)
{
ones_digit = total % 10;
totalsum += ones_digit;
total -= ones_digit;
total /= 10;
}

Convert.ToInt32 returns the Unicode values of characters 1, 2 and 0 which are 49, 50 and 48. That's why the sum comes out as 147.

Related

Reverse double in c# without using string or array

I know such questions have been asked before, but all of them use strings.
Most common answers to such questions are :
convert to string and take number.Length - 1. However I don't want to use strings.
Divide by 10, but this only works for whole numbers. If I have 1.12 and I divide it by 10 I dont get 2.
Turn the number into array and then reverse it. Which is the same as using a string but more work and its not what I am looking for.
So my question is if I have input like 1.12 I want 21.1 but without using any strings. I want to take the 2 and save it as a number and then take the rest and add the dot.
I want a mathematical solution to the problem.
I will provide you with some test cases so you better understand my problem.
23.45 => 54.32
0.50 => 05.0 => 5
4.3445242 => 2425443.4
232 => 232
123 => 321
And I dont want strings or arrays because when you say "I dont want strings" there is always someone who says " turn the number into array and then reverse it". Nah... I want to use only calculations, if-else and cycles (for,while,do while)
A relatively ugly way would be essentially promote that double into long and remember the decimal point. Then reverse the long, then divide it by total number of digits minus originl decimal point. Also, if you want to handle negative numbers, you would have to store the sign and Math.Abs the src double you start mucking around with it.
private double Reverse(double src)
{
double dst = 0;
int decPoint = 0;
while (src - (long)src > 0)
{
src = src * 10;
decPoint++;
}
int totalDigits = 0;
while (src > 0)
{
int d = (int)src % 10;
dst = dst * 10 + d;
src = (long)(src / 10);
totalDigits++;
}
if (decPoint > 0)
{
int reversedDecPoint = totalDigits - decPoint;
for (int i = 0; i < reversedDecPoint; i++) dst = dst / 10;
}
return dst;
}

Do we need to subtract Convert.ToInt32(o) with 48 every time? When there is a need to minus and when its not?

int num = Convert.ToInt32(Console.ReadLine());
With above code I am getting the correct integer value and I am able to do operation on this number and getting the correct result.
But with this below code why Convert.ToInt32(o) method is not converting it to integer value. Why we need to minus with 48.
int[] numarr = number.ToString().Select(o => Convert.ToInt32(o)-48).ToArray();
If I am not subtracting with 48 I am not getting the correct integer value.
Please can anyone explain why this is? Is it required to do every time? Because somewhere else I calculated result without subtracting 48 and I got a correct result.
I am doing a program to print number of occurrences in a number.
Here is my code:
Console.WriteLine("Enter the number:");
int number = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter the number to search:");
int searchnumber = Convert.ToInt32(Console.ReadLine());
int cnt = 0;
int[] numarr = number.ToString().Select(o => Convert.ToInt32(o)-48).ToArray();
for (int i = 0; i < numarr.Length; i++)
{
Console.WriteLine(numarr[i]);
}
for (int i = 0; i < numarr.Length; i++)
{
if (numarr[i] == searchnumber)
{
cnt++;
}
}
Console.WriteLine("Number of occurence of given number is:{0}", cnt);
Because you are converting the number to a string, the integers you retrieve are actually Unicode code points of the characters in the string. According to the ASCII code table, the 0 character starts at position 48.
So you actually found a workaround to convert characters to their integer representation. If you just want to get the number in a less hacky way, you could use this answer, which uses the modulus operator. Or char.ToNumericValue on your original string, as Time Schmelter proposed in a comment.

How to get count of numbers in int and how to split a number without making a string

I have a number like 601511616
If all number's length is multiple of 3, how can a split the number into an array without making a string
Also, how can I count numbers in the int without making a string?
Edit: Is there a way to simply split the number, knowing it's always in a multiple of 3... good output should look like this: {616,511,601}
You can use i % 10 in order to get the last digit of integer.
Then, you can use division by 10 for removing the last digit.
1234567 % 10 = 7
1234567 / 10 = 123456
Here is the code sample:
int value = 601511616;
List<int> digits = new List<int>();
while (value > 0)
{
digits.Add(value % 10);
value /= 10;
}
// digits is [6,1,6,1,1,5,1,0,6] now
digits.Reverse(); // Values has been inserted from least significant to the most
// digits is [6,0,1,5,1,1,6,1,6] now
Console.WriteLine("Count of digits: {0}", digits.Count); // Outputs "9"
for (int i = 0; i < digits.Count; i++) // Outputs "601,511,616"
{
Console.Write("{0}", digits[i]);
if (i > 0 && i % 3 == 0) Console.Write(","); // Insert comma after every 3 digits
}
IDEOne working demonstration of List and division approach.
Actually, if you don't need to split it up but only need to output in 3-digit groups, then there is a very convenient and proper way to do this with formatting.
It will work as well :)
int value = 601511616;
Console.WriteLine("{0:N0}", value); // 601,511,616
Console.WriteLine("{0:N2}", value); // 601,511,616.00
IDEOne working demonstration of formatting approach.
I can't understand your question regarding how to split a number into an array without making a string - sorry. But I can understand the question about getting the count of numbers in an int.
Here's your answer to that question.
Math.Floor(Math.Log10(601511616) + 1) = 9
Edit:
Here's the answer to your first question..
var n = 601511616;
var nArray = new int[3];
for (int i = 0, numMod = n; i < 3; numMod /= 1000, i++)
nArray[i] = numMod%1000;
Please keep in mind there's no safety in this operation.
Edit#3
Still not perfect, but a better example.
var n = 601511616;
var nLength = (int)Math.Floor(Math.Log10(n) + 1)/ 3;
var nArray = new int[nLength];
for (int i = 0, numMod = n; i < nLength; numMod /= 1000, i++)
nArray[i] = numMod%1000;
Edit#3:
IDEOne example http://ideone.com/SSz3Ni
the output is exactly as the edit approved by the poster suggested.
{ 616, 511, 601 }
Using Log10 to calculate the number of digits is easy, but it involves floating-point operations which is very slow and sometimes incorrect due to rounding errors. You can use this way without calculating the value size first. It doesn't care if the number of digits is a multiple of 3 or not.
int value = 601511616;
List<int> list = new List<int>();
while (value > 0) // main part to split the number
{
int t = value % 1000;
value /= 1000;
list.Add(t);
}
// Convert back to an array only if it's necessary, otherwise use List<T> directly
int[] splitted = list.ToArray();
This will store the splitted numbers in reverse order, i.e. 601511616 will become {616, 511, 601}. If you want the numbers in original order, simply iterate the array backwards. Alternatively use Array.Reverse or a Stack
Since you already know they are in multiples of 3, you can just use the extracting each digit method but use 1000 instead of 10. Here is the example
a = 601511616
b = []
while(a):
b.append(a%1000)
a = a//1000
print(b)
#[616, 511, 601]

Finding number of digits of a number in C#

I'm trying to write a piece of code in C# to find the number digits of a integer number, the code works perfectly for all numbers (negative and positive) but I have problem with 10, 100,1000 and so on, it shows one less digits than the numbers' actual number of digits. like 1 for 10 and 2 for 100..
long i = 0;
double n;
Console.Write("N? ");
n = Convert.ToInt64(Console.ReadLine());
do
{
n = n / 10;
i++;
}
while(Math.Abs(n) > 1);
Console.WriteLine(i);
Your while condition is Math.Abs(n) > 1, but in the case of 10, you are only greater than 1 the first time. You could change this check to be >=1 and that should fix your problem.
do
{
n = n / 10;
i++;
}
while(Math.Abs(n) >= 1);
Use char.IsDigit:
string input = Console.ReadLine();
int numOfDigits = input.Count(char.IsDigit);
What's wrong with:
Math.Abs(n).ToString(NumberFormatInfo.InvariantInfo).Length;
Indeed, converting a number to a string is computationally expensive compared to some arithmetic, but it is hard to deal with negative nubers, overflow,...
You need to use Math.Abs to make sure the sign is not counted, and it is a safe option to use NumberFormatInfo.InvariantInfo so that for instance certain cultures that use spaces and accents, do not alter the behavior.
public static int NumDigits(int value, double #base)
{
if(#base == 1 || #base <= 0 || value == 0)
{
throw new Exception();
}
double rawlog = Math.Log(Math.Abs(value), #base);
return rawlog - (rawlog % 1);
}
This NumDigits function is designed to find the number of digits for a value in any base. It also includes error handling for invalid input. The # with the base variable is to make it a verbatim variable (because base is a keyword).
Console.ReadLine().Replace(",", String.Empty).Length;
this will count all the char in a string
int amount = 0;
string input = Console.ReadLine();
char[] chars = input.ToArray();
foreach (char c in chars)
{
amount++;
}
Console.WriteLine(amount.ToString());
Console.ReadKey();

What is the sum of the digits of the number 2^1000?

This is a problem from Project Euler, and this question includes some source code, so consider this your spoiler alert, in case you are interested in solving it yourself. It is discouraged to distribute solutions to the problems, and that isn't what I want. I just need a little nudge and guidance in the right direction, in good faith.
The problem reads as follows:
2^15 = 32768 and the sum of its digits is 3 + 2 + 7 + 6 + 8 = 26.
What is the sum of the digits of the number 2^1000?
I understand the premise and math of the problem, but I've only started practicing C# a week ago, so my programming is shaky at best.
I know that int, long and double are hopelessly inadequate for holding the 300+ (base 10) digits of 2^1000 precisely, so some strategy is needed. My strategy was to set a calculation which gets the digits one by one, and hope that the compiler could figure out how to calculate each digit without some error like overflow:
using System;
using System.IO;
using System.Windows.Forms;
namespace euler016
{
class DigitSum
{
// sum all the (base 10) digits of 2^powerOfTwo
[STAThread]
static void Main(string[] args)
{
int powerOfTwo = 1000;
int sum = 0;
// iterate through each (base 10) digit of 2^powerOfTwo, from right to left
for (int digit = 0; Math.Pow(10, digit) < Math.Pow(2, powerOfTwo); digit++)
{
// add next rightmost digit to sum
sum += (int)((Math.Pow(2, powerOfTwo) / Math.Pow(10, digit) % 10));
}
// write output to console, and save solution to clipboard
Console.Write("Power of two: {0} Sum of digits: {1}\n", powerOfTwo, sum);
Clipboard.SetText(sum.ToString());
Console.WriteLine("Answer copied to clipboard. Press any key to exit.");
Console.ReadKey();
}
}
}
It seems to work perfectly for powerOfTwo < 34. My calculator ran out of significant digits above that, so I couldn't test higher powers. But tracing the program, it looks like no overflow is occurring: the number of digits calculated gradually increases as powerOfTwo = 1000 increases, and the sum of digits also (on average) increases with increasing powerOfTwo.
For the actual calculation I am supposed to perform, I get the output:
Power of two: 1000 Sum of digits: 1189
But 1189 isn't the right answer. What is wrong with my program? I am open to any and all constructive criticisms.
For calculating the values of such big numbers you not only need to be a good programmer but also a good mathematician. Here is a hint for you,
there's familiar formula ax = ex ln a , or if you prefer, ax = 10x log a.
More specific to your problem
21000 Find the common (base 10) log of 2, and multiply it by 1000; this is the power of 10. If you get something like 1053.142 (53.142 = log 2 value * 1000) - which you most likely will - then that is 1053 x 100.142; just evaluate 100.142 and you will get a number between 1 and 10; and multiply that by 1053, But this 1053 will not be useful as 53 zero sum will be zero only.
For log calculation in C#
Math.Log(num, base);
For more accuracy you can use, Log and Pow function of Big Integer.
Now rest programming help I believe you can have from your side.
Normal int can't help you with such a large number. Not even long. They are never designed to handle numbers such huge. int can store around 10 digits (exact max: 2,147,483,647) and long for around 19 digits (exact max: 9,223,372,036,854,775,807). However, A quick calculation from built-in Windows calculator tells me 2^1000 is a number of more than 300 digits.
(side note: the exact value can be obtained from int.MAX_VALUE and long.MAX_VALUE respectively)
As you want precise sum of digits, even float or double types won't work because they only store significant digits for few to some tens of digits. (7 digit for float, 15-16 digits for double). Read here for more information about floating point representation, double precision
However, C# provides a built-in arithmetic
BigInteger for arbitrary precision, which should suit your (testing) needs. i.e. can do arithmetic in any number of digits (Theoretically of course. In practice it is limited by memory of your physical machine really, and takes time too depending on your CPU power)
Back to your code, I think the problem is here
Math.Pow(2, powerOfTwo)
This overflows the calculation. Well, not really, but it is the double precision is not precisely representing the actual value of the result, as I said.
A solution without using the BigInteger class is to store each digit in it's own int and then do the multiplication manually.
static void Problem16()
{
int[] digits = new int[350];
//we're doing multiplication so start with a value of 1
digits[0] = 1;
//2^1000 so we'll be multiplying 1000 times
for (int i = 0; i < 1000; i++)
{
//run down the entire array multiplying each digit by 2
for (int j = digits.Length - 2; j >= 0; j--)
{
//multiply
digits[j] *= 2;
//carry
digits[j + 1] += digits[j] / 10;
//reduce
digits[j] %= 10;
}
}
//now just collect the result
long result = 0;
for (int i = 0; i < digits.Length; i++)
{
result += digits[i];
}
Console.WriteLine(result);
Console.ReadKey();
}
I used bitwise shifting to left. Then converting to array and summing its elements. My end result is 1366, Do not forget to add reference to System.Numerics;
BigInteger i = 1;
i = i << 1000;
char[] myBigInt = i.ToString().ToCharArray();
long sum = long.Parse(myBigInt[0].ToString());
for (int a = 0; a < myBigInt.Length - 1; a++)
{
sum += long.Parse(myBigInt[a + 1].ToString());
}
Console.WriteLine(sum);
since the question is c# specific using a bigInt might do the job. in java and python too it works but in languages like c and c++ where the facility is not available you have to take a array and do multiplication. take a big digit in array and multiply it with 2. that would be simple and will help in improving your logical skill. and coming to project Euler. there is a problem in which you have to find 100! you might want to apply the same logic for that too.
Try using BigInteger type , 2^100 will end up to a a very large number for even double to handle.
BigInteger bi= new BigInteger("2");
bi=bi.pow(1000);
// System.out.println("Val:"+bi.toString());
String stringArr[]=bi.toString().split("");
int sum=0;
for (String string : stringArr)
{ if(!string.isEmpty()) sum+=Integer.parseInt(string); }
System.out.println("Sum:"+sum);
------------------------------------------------------------------------
output :=> Sum:1366
Here's my solution in JavaScript
(function (exponent) {
const num = BigInt(Math.pow(2, exponent))
let arr = num.toString().split('')
arr.slice(arr.length - 1)
const result = arr.reduce((r,c)=> parseInt(r)+parseInt(c))
console.log(result)
})(1000)
This is not a serious answer—just an observation.
Although it is a good challenge to try to beat Project Euler using only one programming language, I believe the site aims to further the horizons of all programmers who attempt it. In other words, consider using a different programming language.
A Common Lisp solution to the problem could be as simple as
(defun sum_digits (x)
(if (= x 0)
0
(+ (mod x 10) (sum_digits (truncate (/ x 10))))))
(print (sum_digits (expt 2 1000)))
main()
{
char c[60];
int k=0;
while(k<=59)
{
c[k]='0';
k++;
}
c[59]='2';
int n=1;
while(n<=999)
{
k=0;
while(k<=59)
{
c[k]=(c[k]*2)-48;
k++;
}
k=0;
while(k<=59)
{
if(c[k]>57){ c[k-1]+=1;c[k]-=10; }
k++;
}
if(c[0]>57)
{
k=0;
while(k<=59)
{
c[k]=c[k]/2;
k++;
}
printf("%s",c);
exit(0);
}
n++;
}
printf("%s",c);
}
Python makes it very simple to compute this with an oneliner:
print sum(int(digit) for digit in str(2**1000))
or alternatively with map:
print sum(map(int,str(2**1000)))

Categories