Convert oct to dex integer - c#

Incorrectly converts a number
In the program you need to convert from octal number system to decimal
"a" is a integer class field that uses the GetDex() method
Construct - this.a = a;
public int GetDex()
{
int res = 0;
int exp = 1;
for (int i = Convert.ToString(a).Length - 1; i >= 0; i--)
{
res += exp * Convert.ToInt32(Convert.ToString(a)[i]);
exp *= 8;
}
return res;
}

The problem is in the
Convert.ToInt32(Convert.ToString(a)[i])
fragment. You actually add ascii codes, not digits. To get digit integer 5 from character '5' just subtract '0':
(Convert.ToString(a)[i] - '0')
Your code corrected:
public int GetDex()
{
int res = 0;
int exp = 1;
for (int i = Convert.ToString(a).Length - 1; i >= 0; i--)
{
//DONE: you should add digits, not ascii codes: - '0'
res += exp * (Convert.ToString(a)[i] - '0');
exp *= 8;
}
return res;
}
You can put it compact with a help of Linq:
public int GetDex() => a
.ToString()
.Aggregate(0, (s, i) => s * 8 + i - '0');

Related

Custom number system in C# [duplicate]

This question already has answers here:
How to convert a column number (e.g. 127) into an Excel column (e.g. AA)
(60 answers)
Closed 5 years ago.
I have a requirement for a custom number system in C# which goes as following:
A - 1
B - 2
...
Z - 26
AA - 27
AB - 28
I've made a function that converts from arbitrary strings to numbers like this:
private const int Min = 'A';
private const int Max = 'Z';
private const int Base = Max - Min + 1;
private static int GetCharValue(char c)
{
if (c < Min || c > Max)
throw new ArgumentOutOfRangeException(nameof(c), c, $"Character needs to be between '{Min}' and '{Max}', was '{c}'.");
return c - Min + 1;
}
public static int GetStringValue(string s)
{
char[] chars = s.ToCharArray();
int[] values = new int[chars.Length];
for (var i = 0; i < chars.Length; i++)
{
values[i] = GetCharValue(chars[i]);
}
int position = 1;
int value = 0;
for (var i = values.Length - 1; i >= 0; i--)
{
value += position * values[i];
position *= Base;
}
return value;
}
I've tested it to be working for up to AAA (not rigorously, just skimming over the output of printing them all). However, I can't for the life of me figure out how to write the reverse function. In other words, I need 1 to return A, 26 to return Z and 27 to return AA. The "problem" is that this number system has no 0, so it doesn't easily convert to any base. For instance, if A was 0, then AA would also be 0, but it's not. So how do I solve this?
you can simply generate it like this....
public static IEnumerable<string> generate()
{
long n = -1;
while (true) yield return toBase26(++n);
}
public static string toBase26(long i)
{
if (i == 0) return ""; i--;
return toBase26(i / 26) + (char)('A' + i % 26);
}
public static void BuildQuery()
{
IEnumerable<string> lstExcelCols = generate();
try
{
string s = lstExcelCols.ElementAtOrDefault(1) ;
}
catch (Exception exc)
{
}
}

Reorder digits in integer using C#

I want to ask how I can reorder the digits in an Int32 so they result in the biggest possible number.
Here is an example which visualizes what I am trying to do:
2927466 -> 9766422
12492771 -> 97742211
I want to perform the ordering of the digits without using the System.Linq namespace and without converting the integer into a string value.
This is what I got so far:
public static int ReorderInt32Digits(int v)
{
int n = Math.Abs(v);
int l = ((int)Math.Log10(n > 0 ? n : 1)) + 1;
int[] d = new int[l];
for (int i = 0; i < l; i++)
{
d[(l - i) - 1] = n % 10;
n /= 10;
}
if (v < 0)
d[0] *= -1;
Array.Sort(d);
Array.Reverse(d);
int h = 0;
for (int i = 0; i < d.Length; i++)
{
int index = d.Length - i - 1;
h += ((int)Math.Pow(10, index)) * d[i];
}
return h;
}
This algorithm works flawlessly but I think it is not very efficient.
I would like to know if there is a way to do the same thing more efficiently and how I could improve my algorithm.
You can use this code:
var digit = 2927466;
String.Join("", digit.ToString().ToCharArray().OrderBy(x => x));
Or
var res = String.Join("", digit.ToString().ToCharArray().OrderByDescending(x => x) );
Not that my answer may or may not be more "efficient", but when I read your code you calculated how many digits there are in your number so you can determine how large to make your array, and then you calculated how to turn your array back into a sorted integer.
It would seem to me that you would want to write your own code that did the sorting part without using built in functionality, which is what my sample does. Plus, I've added the ability to sort in ascending or descending order, which is easy to add in your code too.
UPDATED
The original algorithm sorted the digits, now it sorts the digits so that the end result is the largest or smallest depending on the second parameter passed in. However, when dealing with a negative number the second parameter is treated as opposite.
using System;
public class Program
{
public static void Main()
{
int number1 = 2927466;
int number2 = 12492771;
int number3 = -39284925;
Console.WriteLine(OrderDigits(number1, false));
Console.WriteLine(OrderDigits(number2, true));
Console.WriteLine(OrderDigits(number3, false));
}
private static int OrderDigits(int number, bool asc)
{
// Extract each digit into an array
int[] digits = new int[(int)Math.Floor(Math.Log10(Math.Abs(number)) + 1)];
for (int i = 0; i < digits.Length; i++)
{
digits[i] = number % 10;
number /= 10;
}
// Order the digits
for (int i = 0; i < digits.Length; i++)
{
for (int j = i + 1; j < digits.Length; j++)
{
if ((!asc && digits[j] > digits[i]) ||
(asc && digits[j] < digits[i]))
{
int temp = digits[i];
digits[i] = digits[j];
digits[j] = temp;
}
}
}
// Turn the array of digits back into an integer
int result = 0;
for (int i = digits.Length - 1; i >= 0; i--)
{
result += digits[i] * (int)Math.Pow(10, digits.Length - 1 - i);
}
return result;
}
}
Results:
9766422
11224779
-22345899
See working example here... https://dotnetfiddle.net/RWA4XV
public static int ReorderInt32Digits(int v)
{
var nums = Math.Abs(v).ToString().ToCharArray();
Array.Sort(nums);
bool neg = (v < 0);
if(!neg)
{
Array.Reverse(nums);
}
return int.Parse(new string(nums)) * (neg ? -1 : 1);
}
This code fragment below extracts the digits from variable v. You can modify it to store the digits in an array and sort/reverse.
int v = 2345;
while (v > 0) {
int digit = v % 10;
v = v / 10;
Console.WriteLine(digit);
}
You can use similar logic to reconstruct the number from (sorted) digits: Multiply by 10 and add next digit.
I'm posting this second answer because I think I got the most efficient algorithm of all (thanks for the help Atul) :)
void Main()
{
Console.WriteLine (ReorderInt32Digits2(2927466));
Console.WriteLine (ReorderInt32Digits2(12492771));
Console.WriteLine (ReorderInt32Digits2(-1024));
}
public static int ReorderInt32Digits2(int v)
{
bool neg = (v < 0);
int mult = neg ? -1 : 1;
int result = 0;
var counts = GetDigitCounts(v);
for (int i = 0; i < 10; i++)
{
int idx = neg ? 9 - i : i;
for (int j = 0; j < counts[idx]; j++)
{
result += idx * mult;
mult *= 10;
}
}
return result;
}
// From Atul Sikaria's answer
public static int[] GetDigitCounts(int n)
{
int v = Math.Abs(n);
var result = new int[10];
while (v > 0) {
int digit = v % 10;
v = v / 10;
result[digit]++;
}
return result;
}

Program should give to a word special numerical value (but…)

There's a program I wrote in C, it works perfectly. When I tried to translate it into the language C# it was not compiling. The problem was that C# doesn't know the meaning of scanf ("%19s" , string1); like in C.
I changed scanf to:
string read;
do
{
read = Console.ReadLine();
}
while (read.Length <= 19);
it couldn't work properly. then i tried: to change it into:
string string1Input = Console.ReadLine();
It was working better but if statements were not checked because I was getting all "sum"-s equaled to 0.
This is the program written translated into C#:
public static class GlobalMembersAnbanisRicxvitiMnishvneloba
{
static int Main()
{
string string1 = new string(new char[20]);
sbyte a = (sbyte)'a';
sbyte b = (sbyte)'b';
sbyte g = (sbyte)'g';
sbyte X = (sbyte)'X';
sbyte i = (sbyte)'i';
sbyte H = (sbyte)'H';
sbyte V = (sbyte)'V';
etc..
int rigi;
int sum = 0;
int sum2 = 0;
int sum3 = 0;
Console.Write(" my word is:\n");
string string1Input = Console.ReadLine();
for (rigi = 0; string1[rigi] != '\0'; rigi++)
{
if (string1[rigi] == a)
{
sum3 = sum3 + 1;
sum2 = sum2 + 1;
sum = sum + 1;
}
else
if (string1[rigi] == b)
{
sum3 = sum3 + 3;
sum2 = sum2 + 2;
sum = sum + 2;
}
etc...
} /* end for*/
if (string1[rigi-1]==i)
{
sum=sum-10; sum2=sum2-10; sum3=sum3-55;
}
Console.Write("sum is:");
Console.Write("{0:D}\n", sum);
Console.Write("sum2 is:");
Console.Write("{0:D}\n", sum2);
Console.Write("sum");
Console.Write("{0:D}\n", sum3);
return 0;
}
}
The idea of the prog is:
Program gives a numerical meaning to each of the letter of a word we type and adds this numbers to each other.
Question II: how to make
if (string1[rigi-1]==i)
{
sum=sum-10; sum2=sum2-10; sum3=sum3-55;
}
work?
There is no end caracter string in C#, like in C. In fact, string in C, and string in C# are two totally different things, and are not used the same way.
So for loop over a string, the good way is to use a foreach loop.
Change
for (rigi = 0; string1[rigi] != '\0'; rigi++)
By
foreach(var oneCaracter in string1Input)
Then string1[rigi] must become oneCaracter
And sbyte must become char
Sample correction:
char a = 'a';
int sum = 0;
int sum2 = 0;
int sum3 = 0;
string string1Input = Console.ReadLine();
foreach(char oneCaracter in string1Input)
{
if (oneCaracter == a)
{
sum3 = sum3 + 1;
sum2 = sum2 + 1;
sum = sum + 1;
}
}
if (string1Input[string1Input.Length - 1] == i)
{
sum = sum - 10; sum2 = sum2-10; sum3 = sum3-55;
}

Special Counters

I`m trying to create a special counter in C# ... I mean the counter will be consisting of characters not numbers.
I have a char[] of size 3:
char[] str = new char[strSize];
int i = 0;
int tmpSize = strSize - 1;
int curr;
while(!isEqual(str,finalStr,strSize))
{
str[strSize] = element[i % element.Length];
i++;
if (str[strSize] == element[element.Length - 1])
{
int j = strSize - 1;
if (j > 0)
{
j--;
int tmpCntr = j+1;
curr = getCurrentID(str[tmpCntr]);
str[tmpCntr] = element[(curr + 1) % element.Length];
while (str[tmpCntr] == element[0] && (i % element.Length > 0) && tmpCntr < 0)
{
tmpCntr--;
curr = getCurrentID(str[tmpCntr]);
str[tmpCntr] = element[(curr + 1) % element.Length];
}
}
}
}
if the strSize < 3 the application works fine and gives accurate output. If the strSize >= 3, the application goes in infinite loop!
Need help.
if this is hard this way, I would need a way to create a numerical counter and I`ll work on it to suite my application.
You haven't shown what half of your methods or parameters are.
Personally I would take a different approach. I would use an iterator block to make it easy to return an IEnumerable<string>, and internally just keep an integer counter. Then you just need to write a method to convert a counter value and "alphabet of digits" into a string. Something like this:
public static IEnumerable<string> Counter(string digits, int digitCount)
{
long max = (long) Math.Pow(digits.Length, digitCount);
for (long i = 0; i < max; i++)
{
yield return ConvertToString(i, digits, digitCount);
}
}
Another alternative is to do the same thing with LINQ, if a range of int is enough:
public static IEnumerable<string> Counter(string digits, int digitCount)
{
int max = (int) Math.Pow(digits.Length, digitCount);
return Enumerable.Range(0, max)
.Select(i => ConvertToString(i, digits, digitCount));
}
In either case, you just iterate over the returned sequence to get appropriate counter values.
With those in place, you just need to implement ConvertToString - which would probably be something like this:
public static string ConvertToString(long value, string digits, int digitCount)
{
char[] chars = new char[digitCount];
for (int i = digitCount - 1 ; i >= 0; i--)
{
chars[i] = digits[(int)(value % digits.Length)];
value = value / digits.Length;
}
return new string(chars);
}
Here's a test program showing it all working:
using System;
using System.Collections.Generic;
using System.Linq;
class Test
{
static void Main()
{
// Show the first 10 values
foreach (string value in Counter("ABCD", 3).Take(10))
{
Console.WriteLine(value);
}
}
public static IEnumerable<string> Counter(string digits, int digitCount)
{
long max = (long) Math.Pow(digits.Length, digitCount);
for (long i = 0; i < max; i++)
{
yield return ConvertToString(i, digits, digitCount);
}
}
public static string ConvertToString(long value,
string digits,
int digitCount)
{
char[] chars = new char[digitCount];
for (int i = digitCount - 1 ; i >= 0; i--)
{
chars[i] = digits[(int)(value % digits.Length)];
value = value / digits.Length;
}
return new string(chars);
}
}
Output:
AAA
AAB
AAC
AAD
ABA
ABB
ABC
ABD
ACA
ACB

Sum of digits in C#

What's the fastest and easiest to read implementation of calculating the sum of digits?
I.e. Given the number: 17463 = 1 + 7 + 4 + 6 + 3 = 21
You could do it arithmetically, without using a string:
sum = 0;
while (n != 0) {
sum += n % 10;
n /= 10;
}
I use
int result = 17463.ToString().Sum(c => c - '0');
It uses only 1 line of code.
For integer numbers, Greg Hewgill has most of the answer, but forgets to account for the n < 0. The sum of the digits of -1234 should still be 10, not -10.
n = Math.Abs(n);
sum = 0;
while (n != 0) {
sum += n % 10;
n /= 10;
}
It the number is a floating point number, a different approach should be taken, and chaowman's solution will completely fail when it hits the decimal point.
public static int SumDigits(int value)
{
int sum = 0;
while (value != 0)
{
int rem;
value = Math.DivRem(value, 10, out rem);
sum += rem;
}
return sum;
}
int num = 12346;
int sum = 0;
for (int n = num; n > 0; sum += n % 10, n /= 10) ;
I like the chaowman's response, but would do one change
int result = 17463.ToString().Sum(c => Convert.ToInt32(c));
I'm not even sure the c - '0', syntax would work? (substracting two characters should give a character as a result I think?)
I think it's the most readable version (using of the word sum in combination with the lambda expression showing that you'll do it for every char). But indeed, I don't think it will be the fastest.
I thought I'd just post this for completion's sake:
If you need a recursive sum of digits, e.g: 17463 -> 1 + 7 + 4 + 6 + 3 = 21 -> 2 + 1 = 3
then the best solution would be
int result = input % 9;
return (result == 0 && input > 0) ? 9 : result;
int n = 17463; int sum = 0;
for (int i = n; i > 0; i = i / 10)
{
sum = sum + i % 10;
}
Console.WriteLine(sum);
Console.ReadLine();
I would suggest that the easiest to read implementation would be something like:
public int sum(int number)
{
int ret = 0;
foreach (char c in Math.Abs(number).ToString())
ret += c - '0';
return ret;
}
This works, and is quite easy to read. BTW: Convert.ToInt32('3') gives 51, not 3. Convert.ToInt32('3' - '0') gives 3.
I would assume that the fastest implementation is Greg Hewgill's arithmetric solution.
private static int getDigitSum(int ds)
{
int dssum = 0;
while (ds > 0)
{
dssum += ds % 10;
ds /= 10;
if (dssum > 9)
{
dssum -= 9;
}
}
return dssum;
}
This is to provide the sum of digits between 0-9
public static int SumDigits1(int n)
{
int sum = 0;
int rem;
while (n != 0)
{
n = Math.DivRem(n, 10, out rem);
sum += rem;
}
return sum;
}
public static int SumDigits2(int n)
{
int sum = 0;
int rem;
for (sum = 0; n != 0; sum += rem)
n = Math.DivRem(n, 10, out rem);
return sum;
}
public static int SumDigits3(int n)
{
int sum = 0;
while (n != 0)
{
sum += n % 10;
n /= 10;
}
return sum;
}
Complete code in: https://dotnetfiddle.net/lwKHyA
int j, k = 1234;
for(j=0;j+=k%10,k/=10;);
A while back, I had to find the digit sum of something. I used Muhammad Hasan Khan's code, however it kept returning the right number as a recurring decimal, i.e. when the digit sum was 4, i'd get 4.44444444444444 etc.
Hence I edited it, getting the digit sum correct each time with this code:
double a, n, sumD;
for (n = a; n > 0; sumD += n % 10, n /= 10);
int sumI = (int)Math.Floor(sumD);
where a is the number whose digit sum you want, n is a double used for this process, sumD is the digit sum in double and sumI is the digit sum in integer, so the correct digit sum.
static int SumOfDigits(int num)
{
string stringNum = num.ToString();
int sum = 0;
for (int i = 0; i < stringNum.Length; i++)
{
sum+= int.Parse(Convert.ToString(stringNum[i]));
}
return sum;
}
If one wants to perform specific operations like add odd numbers/even numbers only, add numbers with odd index/even index only, then following code suits best. In this example, I have added odd numbers from the input number.
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Please Input number");
Console.WriteLine(GetSum(Console.ReadLine()));
}
public static int GetSum(string num){
int summ = 0;
for(int i=0; i < num.Length; i++){
int currentNum;
if(int.TryParse(num[i].ToString(),out currentNum)){
if(currentNum % 2 == 1){
summ += currentNum;
}
}
}
return summ;
}
}
The simplest and easiest way would be using loops to find sum of digits.
int sum = 0;
int n = 1234;
while(n > 0)
{
sum += n%10;
n /= 10;
}
#include <stdio.h>
int main (void) {
int sum = 0;
int n;
printf("Enter ir num ");
scanf("%i", &n);
while (n > 0) {
sum += n % 10;
n /= 10;
}
printf("Sum of digits is %i\n", sum);
return 0;
}
Surprised nobody considered the Substring method. Don't know whether its more efficient or not. For anyone who knows how to use this method, its quite intuitive for cases like this.
string number = "17463";
int sum = 0;
String singleDigit = "";
for (int i = 0; i < number.Length; i++)
{
singleDigit = number.Substring(i, 1);
sum = sum + int.Parse(singleDigit);
}
Console.WriteLine(sum);
Console.ReadLine();

Categories