The objective of this code is to add all the integers in a whole number into one value (e.g "2013" => 6),
In c# I have written the code so it outputs the number to its corresponding ASCII value one at a time, but I am at a loss at how to convert it back into its number value.
Note that I am new at C#
string Year;
int Total = 0;
int Adding = 0;
int Adding2 = 0;
Console.WriteLine("Write The year you want converted");
Year = Console.ReadLine();
for (int i = 0; i < Year.Length; i++)
{
Adding2 = Year[i];
Adding = Convert.ToInt32(Adding2);
Total = Adding + Total;
Console.WriteLine(Total);
}
You should sum values, not ascii codes:
...
for (int i = 0; i < Year.Length; i++)
{
Adding2 = Year[i];
Adding = Adding2 - '0';
Total = Adding + Total;
}
Console.WriteLine(Total);
In general case, you can use char.GetNumericValue():
// double: some characters have fractional values: '⅝'
double Total = 0.0;
foreach (char c in Year) {
double value = char.GetNumericValue(c);
// If character has value (e.g. 'A' doesn't have)
if (value != -1)
Total += value;
}
Console.WriteLine(Total);
Related
I try to write program that check the ratio between odd and even
digits in a given number. I've had some problems with this code:
static void Main(string[] args)
{
int countEven = 0 ;
int countOdd = 0 ;
Console.WriteLine("insert a number");
int num = int.Parse(Console.ReadLine());
int length = num.GetLength;
for (int i = 0;i<length ; i++)
{
if((num/10)%2) == 0)
int countEven++;
}
}
any ideas?
The problem is that int does not have a length, only the string representation of it has one.As an alternative to m.rogalski answer, you can treat the input as a string to get all the digits one by one. Once you have a digit, then parsing it to int and checking if it is even or odd is trivial.Would be something like this:
int countEven = 0;
int countOdd = 0;
Console.WriteLine("insert a number");
string inputString = Console.ReadLine();
for (int i = 0; i < inputString.Length; i++)
{
if ((int.Parse(inputString[i].ToString()) % 2) == 0)
countEven++;
else
countOdd++;
}
Linq approach
Console.WriteLine("insert a number");
string num = Console.ReadLine(); // check for valid number here?
int countEven = num.Select(x => x - '0').Count(x => x % 2 == 0);
int countOdd = num.Select(x => x - '0').Count(x => x % 2 != 0);
Let's assume your input is : 123456
Now all you have to do is to get the modulo from the division by ten : int m = num % 10;
After that just check if bool isEven = m % 2 == 0;
On the end you have to just divide your input number by 10 and repeat the whole process till the end of numbers.
int a = 123456, oddCounter = 0, evenCounter = 0;
do
{
int m = a % 10;
switch(m % 2)
{
case 0:
evenCounter++;
break;
default: // case 1:
oddCounter++;
break;
}
//bool isEven = m % 2 == 0;
}while( ( a /= 10 ) != 0 );
Online example
Made a small change to your code and it works perfectly
int countEven = 0;
int countOdd = 0;
Console.WriteLine( "insert a number" );
char[] nums = Console.ReadLine().ToCharArray();
for ( int i = 0; i < nums.Length; i++ )
{
if ( int.Parse( nums[i].ToString() ) % 2 == 0 )
{
countEven++;
}
else
{
countOdd++;
}
}
Console.WriteLine($"{countEven} even numbers \n{countOdd} odd numbers");
Console.ReadKey();
What I do is get each number as a a character in an array char[] and I loop through this array and check if its even or not.
If the Input number is a 32-bit integer (user pick the length of the number)
if asked:
The number of even digits in the input number
Product of odd digits in the input number
The sum of all digits of the input number
private void button1_Click(object sender, EventArgs e) {
int num = ConvertToInt32(textBox1.Text);
int len_num = textBox1.Text.Length;
int[] arn = new int[len_num];
int cEv = 0; pOd = 0; s = 0;
for (int i = len_num-1; i >= 0; i--) { // loop until integer length is got down to 1
arn[i] = broj % 10; //using the mod we put the last digit into a declared array
if (arn[i] % 2 == 0) { // then check, is current digit even or odd
cEv++; // count even digits
} else { // or odd
if (pOd == 0) pOd++; // avoid product with zero
pOd *= arn [i]; // and multiply odd digits
}
num /= 10; // we divide by 10 until it's length is get to 1(len_num-1)
s += arn [i]; // sum of all digits
}
// and at last showing it in labels...
label2.Text = "a) The even digits count is: " + Convert.ToString(cEv);
label3.Text = "b) The product of odd digits is: " + Convert.ToString(pOd);
label4.Text = "c) The sum of all digits in this number is: " + Convert.ToString(s);
}
All we need in the interface is the textbox for entering the number, the button for the tasks, and labels to show obtained results. Of course, we have the same result if we use a classic form for the for loop like for (int i = 0; and <= len_num-1; i++) - because the essence is to count the even or odd digits rather than the sequence of the digits entry into the array
static void Main(string args[]) {
WriteLine("Please enter a number...");
var num = ReadLine();
// Check if input is a number
if (!long.TryParse(num, out _)) {
WriteLine("NaN!");
return;
}
var evenChars = 0;
var oddChars = 0;
// Convert string to char array, rid of any non-numeric characters (e.g.: -)
num.ToCharArray().Where(c => char.IsDigit(c)).ToList().ForEach(c => {
byte.TryParse(c.ToString(), out var b);
if (b % 2 == 0)
evenChars++;
else
oddChars++;
});
// Continue with code
}
EDIT:
You could also do this with a helper (local) function within the method body:
static void Main(string args[]) {
WriteLine("Please enter a number...");
var num = ReadLine();
// Check if input is a number
if (!long.TryParse(num, out _)) {
WriteLine("NaN!");
return;
}
var evenChars = 0;
var oddChars = 0;
// Convert string to char array, rid of any non-numeric characters (e.g.: -)
num.ToCharArray().Where(c => char.IsDigit(c)).ToList().ForEach(c => {
byte.TryParse(c.ToString(), out var b);
if (b % 2 == 0)
evenChars++;
else
oddChars++;
// Alternative method:
IsEven(b) ? evenChars++ : oddChars++;
});
// Continue with code
bool IsEven(byte b) => b % 2 == 0;
}
Why am I using a byte?
Dealing with numbers, it is ideal to use datatypes that don't take up as much RAM.
Granted, not as much an issue nowadays with multiple 100s of gigabytes possible, however, it is something not to be neglected.
An integer takes up 32 bits (4 bytes) of RAM, whereas a byte takes up a single byte (8 bits).
Imagine you're processing 1 mio. single-digit numbers, and assigning them each to integers. You're using 4 MiB of RAM, whereas the byte would only use up 1 MiB for 1 mio. numbers.
And seeming as a single-digit number (as is used in this case) can only go up to 9 (0-9), you're wasting a potential of 28 bits of memory (2^28) - whereas a byte can only go up to 255 (0-255), you're only wasting a measly four bits (2^4) of memory.
I want to add up all numbers in a string, I am sure this can be done easy with a for loop.
I have:
int numbers = 1234512345;
for (int i = 0 ; i numbers.Length ; i++)
{
int total;
total = int [i];
}
But it won't work for a reason, I am puzzled a lot.
For one, the "string" you're trying to iterate over is an int. You probably meant something along the lines of
string numbers = "1234512345"
After that, there are several ways to do this, my favorite personally is iterating over each character of the string, using a TryParse on it (this eliminates any issues if the string happens to be alphanumeric) and totaling the result. See below:
static void Main(string[] args) {
string numbers = "1234512345";
int total = 0;
int num; // out result
for (int i = 0; i < numbers.Length; i++) {
int.TryParse(numbers[i].ToString(), out num);
total += num; // will equal 30
}
Console.WriteLine(total);
total = 0;
string alphanumeric = "1#23451!23cf47c";
for (int i = 0; i < alphanumeric.Length; i++) {
int.TryParse(alphanumeric[i].ToString(), out num);
total += num; // will equal 32, non-numeric characters are ignored
}
Console.WriteLine(total);
Console.ReadLine();
}
Like others have posted though, there are several ways to go about this, it's about personal preference most of all.
this should do what you want
int total = 0;
foreach(char numchar in numbers)
{
total += (int)char.GetNumericValue(numchar);
}
EDIT:
1 line solution:
int total = numbers.Sum(x=> (int)char.GetNumericValue(x));
PS: Why the downvotes?
I want to get a number of a string, and separate the string and the number, and then, do a loop and call a method the number of times the string says.
The string has to have this structure: "ABJ3" (Only one number accepted and 3 characters before it)
This is my code, but it repeat hundred of times, I don't know why
int veces = 0;
for (int i = 0; i < m.Length; i++)
{
if (Char.IsDigit(m[i]))
veces = Convert.ToInt32(m[i]);
}
if (m.Length == 4)
{
for (int i = 0; i <= veces; i++)
{
m = m.Substring(0, 3);
operaciones(m, u, t);
Thread.Sleep(100);
}
}
operaciones(m,u,t);
if (u.Length >= 14)
{
u = u.Substring(0, 15);
}
Some help please?
You have to convert your m[i] ToString() right now you are sending the char value to Convert.ToInt32 and that is a much higher value (9 = 57 for example)
char t = '9';
int te = Convert.ToInt32(t.ToString());
Console.WriteLine(te);
This gives us a result of 9 but
char t = '9';
int te = Convert.ToInt32(t);
Console.WriteLine(te);
Gives us a result of 57
So you need to change
veces = Convert.ToInt32(m[i]);
to
veces = Convert.ToInt32(m[i].ToString());
Hope it helped.
Best regards //KH.
You cannot convert the digits like this. You're overwriting them and taking only the last one. Moreover, you're taking its ASCII code, not digit value. You have to extract all digits first then convert them:
int position = 0;
int veces = 0;
string temp = ""
for (int i = 0; i < m.Length; i++) {
if (Char.IsDigit(m[i]))
position = i;
else
break;
}
veces = Convert.ToInt32(m.SubString(0, i + 1));
Alternatively, you can use regex instead.
This is a problem statement.
Consider a number 2345. If you multiply its digits then you get the number 120. Now if you again multiply digits of 120 then you will get number 0 which is a one digit number. If I add digits of 2345 then I will get 14. If I add digits of 14 then I will get 5 which is a one digit number.
Thus any number can be converted into two one digit numbers in some number of steps. You can see 2345 is converted to 0 by using multiplication of digits in 2 steps and it is converted to 5 by using addition of digits in 2 steps. Now consider any number N. Let us say that it can be converted by multiplying digits to a one digit number d1 in n1 steps and by adding digits to one digit number d2 in n2 steps.
Your task is to find smallest number greater than N and less than 1000000000 which can be converted by multiplying its digits to d1 in less than or equal to n1 steps and by adding its digits to d2 in less than or equal to n2 steps.
How to solve it in C#...
I think you're simply approaching / interpreting the problem incorrectly; here's a stab in the dark:
using System;
using System.Diagnostics;
static class Program
{
static void Main()
{
// check our math first!
// You can see 2345 is converted to 0 by using multiplication of digits in 2 steps
int value, steps;
value = MultiplyToOneDigit(2345, out steps);
Debug.Assert(value == 0);
Debug.Assert(steps == 2);
// and it is converted to 5 by using addition of digits in 2 steps
value = SumToOneDigit(2345, out steps);
Debug.Assert(value == 5);
Debug.Assert(steps == 2);
// this bit is any random number
var rand = new Random();
for (int i = 0; i < 10; i++)
{
int N = rand.Next(0, MAX);
int result = Execute(N);
Console.WriteLine("For N={0}, our answer is {1}", N, result);
}
}
const int MAX = 1000000000;
//Now consider any number N.
static int Execute(int N)
{
// Let us say that it can be converted by multiplying digits to a one digit number d1 in n1
// steps and by adding digits to one digit number d2 in n2 steps.
int n1, n2;
int d1 = MultiplyToOneDigit(N, out n1),
d2 = SumToOneDigit(N, out n2);
// Your task is to find smallest number greater than N and less than 1000000000
for (int i = N + 1; i < MAX; i++)
{
int value, steps;
// which can be converted by multiplying its digits to d1 in less than or equal to n1 steps
value = MultiplyToOneDigit(i, out steps);
if (value != d1 || steps > n1) continue; // no good
// and by adding its digits to d2 in less than or equal to n2 steps.
value = SumToOneDigit(i, out steps);
if(value != d2 || steps > n2) continue; // no good
return i;
}
return -1; // no answer
}
static int MultiplyToOneDigit(int value, out int steps)
{
steps = 0;
while (value > 10)
{
value = MultiplyDigits(value);
steps++;
}
return value;
}
static int SumToOneDigit(int value, out int steps)
{
steps = 0;
while (value > 10)
{
value = SumDigits(value);
steps++;
}
return value;
}
static int MultiplyDigits(int value)
{
int acc = 1;
while (value > 0)
{
acc *= value % 10;
value /= 10;
}
return acc;
}
static int SumDigits(int value)
{
int total = 0;
while (value > 0)
{
total += value % 10;
value /= 10;
}
return total;
}
}
There are two memory problems I can see; the first is the generation of lots of strings - you might want to approach that something like:
static int SumDigits(int value)
{
int total = 0;
while (value > 0)
{
total += value % 10;
value /= 10;
}
return total;
}
(which is completely untested)
The second problem is the huge list; you don't need to store (in lstString) every value just to find a minimum. Just keep track of the best you've done so far. Or if you need the data for every value, then: don't store them as a string. Indeed, the i can be implied anyway (from the position in the list/array), so all you would really need would be an int[] of the cnt values for every value. And int[1000000000] is 4GB just by itself, so would require the large-array support in recent .NET versions (<gcAllowVeryLargeObjects>). But much better would be: just don't store it.
But it's throwing System.OutOfMemoryException .
That simply mean you're running out of memory. Your limit is 1,000,000,000 or roughly 1G. Times 4 bytes for a string reference that's already too large for a 32 bit system. Even without the actual strings.
You can store your answers more compactly in an int[] array but that would still show the same problem.
So, lower your limit or compile and run on a 64 bit PC.
A for effort :)
Now doing together. You can of course do refactoring.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _17082903_smallest_greatest_number
{
class Program
{
static void Main(string[] args)
{
int N = 2344;
int n1 = 0;
int n2 = 0;
int d1 = SumDigits(N, ref n1);
int d2 = ProductDigits(N, ref n2);
bool sumFound = false, productFound = false;
for (int i = N + 1; i < 1000000000; i++)
{
if (!sumFound)
{
int stepsForSum = 0;
var res = SumDigits(i, ref stepsForSum);
if (res == d1 && stepsForSum <= n1)
{
Console.WriteLine("the smallest number for sum is: " + i);
Console.WriteLine(string.Format("sum result is {0} in {1} steps only", res, stepsForSum));
sumFound = true;
}
stepsForSum = 0;
}
if (!productFound)
{
int stepsForProduct = 0;
var res2 = ProductDigits(i, ref stepsForProduct);
if (res2 == d2 && stepsForProduct <= n2)
{
Console.WriteLine("the smallest number for product is: " + i);
Console.WriteLine(string.Format("product result is {0} in {1} steps only", res2, stepsForProduct));
productFound = true;
}
stepsForProduct = 0;
}
if (productFound && sumFound)
{
break;
}
}
}
static int SumDigits(int value, ref int numOfSteps)
{
int total = 0;
while (value > 0)
{
total += value % 10;
value /= 10;
}
numOfSteps++;
if (total < 10)
{
return total;
}
else
{
return SumDigits(total, ref numOfSteps);
}
}
static int ProductDigits(int value, ref int numOfSteps)
{
int total = 1;
while (value > 0)
{
total *= value % 10;
value /= 10;
}
numOfSteps++;
if (total < 10)
{
return total;
}
else
{
return ProductDigits(total, ref numOfSteps);
}
}
}
}
I want to make a method that takes a variable of type int or long and returns an array of ints or longs, with each array item being a group of 3 digits. For example:
int[] i = splitNumber(100000);
// Outputs { 100, 000 }
int[] j = splitNumber(12345);
// Outputs { 12, 345 }
int[] k = splitNumber(12345678);
// Outputs { 12, 345, 678 }
// Et cetera
I know how to get the last n digits of a number using the modulo operator, but I have no idea how to get the first n digits, which is the only way to make this method that I can think of. Help please!
Without converting to string:
int[] splitNumber(int value)
{
Stack<int> q = new Stack<int>();
do
{
q.Push(value%1000);
value /= 1000;
} while (value>0);
return q.ToArray();
}
This is simple integer arithmetic; first take the modulo to get the right-most decimals, then divide to throw away the decimals you already added. I used the Stack to avoid reversing a list.
Edit: Using log to get the length was suggested in the comments. It could make for slightly shorter code, but in my opinion it is not better code, because the intent is less clear when reading it. Also, it might be less performant due to the extra Math function calls. Anyways; here it is:
int[] splitNumber(int value)
{
int length = (int) (1 + Math.Log(value, 1000));
var result = from n in Enumerable.Range(1,length)
select ((int)(value / Math.Pow(1000,length-n))) % 1000;
return result.ToArray();
}
By converting into a string and then into int array
int number = 1000000;
string parts = number.ToString("N0", new NumberFormatInfo()
{
NumberGroupSizes = new[] { 3 },
NumberGroupSeparator = "."
});
By using Maths,
public static int[] splitNumberIntoGroupOfDigits(int number)
{
var numberOfDigits = Math.Floor(Math.Log10(number) + 1); // compute number of digits
var intArray = new int[Convert.ToInt32(numberOfDigits / 3)]; // we know the size of array
var lastIndex = intArray.Length -1; // start filling array from the end
while (number != 0)
{
var lastSet = number % 1000;
number = number / 1000;
if (lastSet == 0)
{
intArray[lastIndex] = 0; // set of zeros
--lastIndex;
}
else if (number == 0)
{
intArray[lastIndex] = lastSet; // this could be your last set
--lastIndex;
}
else
{
intArray[lastIndex] = lastSet;
--lastIndex;
}
}
return intArray;
}
Try converting it to string first and do the parsing then convert it back to number again
Convert to string
Get length
If length modulus 3 == 0
String substring it into ints every 3
else if
Find remainder such as one or two left over
Substring remainder off of front of string
Then substring by 3 for the rest
You can first find out how large the number is, then use division to get the first digits, and modulo to keep the rest:
int number = 12345678;
int len = 1;
int div = 1;
while (number >= div * 1000) {
len++;
div *= 1000;
}
int[] result = new int[len];
for (int i = 0; i < result.Length; i++) {
result[i] = number / div;
number %= div;
div /= 1000;
}
You can use this with the System.Linq namespace from .NET 3.5 and above:
int[] splitNumber(long value)
{
LinkedList<int> results = new LinkedList<int>();
do
{
int current = (int) (value % 1000);
results.AddFirst(current);
value /= 1000;
} while (value > 0);
return results.ToArray();// Extension method
}
I use LinkedList<int> to avoid having to Reverse a list before returning. You could also use Stack<int> for the same purpose, which would only require .NET 2.0:
int[] splitNumber(long value)
{
Stack<int> results = new Stack<int>();
do
{
int current = (int) (value % 1000);
results.Push(current);
value /= 1000;
} while (value > 0);
return results.ToArray();
}