Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
Question:
Have the function ClosestEnemy(arr) take the array of numbers stored in arr and from the position in the array where a 1 is, return the number of spaces either left or right you must move to reach an enemy which is represented by a 2. For example: if arr is [0, 0, 1, 0, 0, 2, 0, 2] then your program should return 3 because the closest enemy (2) is 3 spaces away from the 1. The array will contain any number of 0's and 2's, but only a single 1. It may not contain any 2's at all as well, where in that case your program should return a 0.
My problem Console.Readline() and return.I dont know proper use.
I get to this errors, I put a comment line on the code
CS1503 C# Argument 1: cannot convert from 'int' to 'int[]'
CS0165 C# Use of unassigned local variable 'result'
examples:
Input: new int[] {1, 0, 0, 0, 2, 2, 2}
Output: 4
Input: new int[] {2, 0, 0, 0, 2, 2, 1, 0}
Output: 1
public static int ClosestEnemy1(int[] arr)
{
int result;
int counterright = 0;
int counterleft = 0;
int locationleft = 0;
int location1 = 0;
int locationright = 0;
int rightclosest;
int leftclosest;
int i;
// code goes here
for(i = 0; i < arr.Length; i++)
{
if (arr[i] == 1)
{
location1 = i;//1'in konumu belirlendi
}
}
//sağa kontrol et
while (arr[i]!= '\0' )//saga bak
{
i = location1;
i++;
if (arr[i] == 2)
{
counterright = 1;
locationright = i;
break;
}
}
for (i = location1; i >= 0; i--)
{
if (arr[i] == 2)
{
counterleft = 1;
locationleft = i;
break;
}
}
if(counterright == 0 && counterleft == 0)
{
result=0;
}
if(counterright == 0 && counterleft == 1)
{
result = location1 - locationleft;
}
if(counterright == 1 && counterleft == 0)
{
result = locationright - location1;
}
if(counterright == 1 && counterleft == 1)
{
leftclosest = location1 - locationleft;
rightclosest = locationright - location1;
if (leftclosest > rightclosest)
{
result = leftclosest;
}
else
{
result= rightclosest;
}
}
return result; //it's error!!!!!!!
}
static void Main()
{
// keep this function call here
Console.WriteLine(ClosestEnemy1(Convert.ToInt32(Console.ReadLine())));//it's errorr!!!!
}
Try these corrections in your code:
1) chnage input type to string : public static int ClosestEnemy1(string inputString)
, make sure you leave the comment for user to enter input like this: 1, 0, 0, 0, 2, 2, 2
2) inside the function make int arr[] by String.Split():
string[] stringNumbers = inputString .Split(',');
int[] arr = Array.ConvertAll(stringNumbers, s => int.Parse(s));
3) change this line :
int result=0; to assign the default value to result .
4) assign i=0 or what you think better before while, becuse the last assigned value for i is 7 and it will has an error.
//sağa kontrol et
i = 0;
while (arr[i] != '\0')//saga bak
5) in the main() function after you get console result, put a Console.ReadKey(); to you see the result.
I am trying to work through a scenario I haven't seen before and am struggling to come up with an algorithm to implement this properly. Part of my problem is a hazy recollection of the proper terminology. I believe what I am needing is a variation of the standard "combination" problem, but I could well be off there.
The Scenario
Given an example string "100" (let's call it x), produce all combinations of x that swap out one of those 0 (zero) characters for a o (lower-case o). So, for the simple example of "100", I would expect this output:
"100"
"10o"
"1o0"
"1oo"
This would need to support varying length strings with varying numbers of 0 characters, but assume there would never be more than 5 instances of 0.
I have this very simple algorithm that works for my sample of "100" but falls apart for anything longer/more complicated:
public IEnumerable<string> Combinations(string input)
{
char[] buffer = new char[input.Length];
for(int i = 0; i != buffer.Length; ++i)
{
buffer[i] = input[i];
}
//return the original input
yield return new string(buffer);
//look for 0's and replace them
for(int i = 0; i != buffer.Length; ++i)
{
if (input[i] == '0')
{
buffer[i] = 'o';
yield return new string(buffer);
buffer[i] = '0';
}
}
//handle the replace-all scenario
yield return input.Replace("0", "o");
}
I have a nagging feeling that recursion could be my friend here, but I am struggling to figure out how to incorporate the conditional logic I need here.
Your guess was correct; recursion is your friend for this challenge. Here is a simple solution:
public static IEnumerable<string> Combinations(string input)
{
int firstZero = input.IndexOf('0'); // Get index of first '0'
if (firstZero == -1) // Base case: no further combinations
return new string[] { input };
string prefix = input.Substring(0, firstZero); // Substring preceding '0'
string suffix = input.Substring(firstZero + 1); // Substring succeeding '0'
// e.g. Suppose input was "fr0d00"
// Prefix is "fr"; suffix is "d00"
// Recursion: Generate all combinations of suffix
// e.g. "d00", "d0o", "do0", "doo"
var recursiveCombinations = Combinations(suffix);
// Return sequence in which each string is a concatenation of the
// prefix, either '0' or 'o', and one of the recursively-found suffixes
return
from chr in "0o" // char sequence equivalent to: new [] { '0', 'o' }
from recSuffix in recursiveCombinations
select prefix + chr + recSuffix;
}
This works for me:
public IEnumerable<string> Combinations(string input)
{
var head = input[0] == '0' //Do I have a `0`?
? new [] { "0", "o" } //If so output both `"0"` & `"o"`
: new [] { input[0].ToString() }; //Otherwise output the current character
var tails = input.Length > 1 //Is there any more string?
? Combinations(input.Substring(1)) //Yes, recursively compute
: new[] { "" }; //Otherwise, output empty string
//Now, join it up and return
return
from h in head
from t in tails
select h + t;
}
You don't need recursion here, you can enumerate your patterns and treat them as binary numbers. For example, if you have three zeros in your string, you get:
0 000 ....0..0....0...
1 001 ....0..0....o...
2 010 ....0..o....0...
3 011 ....0..o....o...
4 100 ....o..0....0...
5 101 ....o..0....o...
6 110 ....o..o....0...
7 111 ....o..o....o...
You can implement that with bitwise operators or by treating the chars that you want to replace like an odometer.
Below is an implementation in C. I'm not familiar with C# and from the other answers I see that C# already has suitable standard classes to implement what you want. (Although I'm surprised that so many peolpe propose recursion here.)
So this is more an explanation or illustration of my comment to the question than an implementation advice for your problem.
int binrep(char str[])
{
int zero[40]; // indices of zeros
int nzero = 0; // number of zeros in string
int ncombo = 1; // number of result strings
int i, j;
for (i = 0; str[i]; i++) {
if (str[i] == '0') {
zero[nzero++] = i;
ncombo <<= 1;
}
}
for (i = 0; i < ncombo; i++) {
for (j = 0; j < nzero; j++) {
str[zero[j]] = ((i >> j) & 1) ? 'o' : '0';
}
printf("%s\n", str); // should yield here
}
return ncombo;
}
Here's a solution using recursion, and your buffer array:
private static void Main(string[] args)
{
var a = Combinations("100");
var b = Combinations("10000");
}
public static IEnumerable<string> Combinations(string input)
{
var combinations = new List<string>();
combinations.Add(input);
for (int i = 0; i < input.Length; i++)
{
char[] buffer= input.ToArray();
if (buffer[i] == '0')
{
buffer[i] = 'o';
combinations.Add(new string(buffer));
combinations = combinations.Concat(Combinations(new string(buffer))).ToList();
}
}
return combinations.Distinct();
}
The method adds the raw input as the first result. After that, we replace in a loop the 0s we see as a o and call our method back with that new input, which will cover the case of multiple 0s.
Finally, we end up with a couple duplicates, so we use Distinct.
I know that the earlier answers are better. But I don't want my code to go to waste. :)
My approach for this combinatorics problem would be to take advantage of how binary numbers work. My algorithm would be as follows:
List<string> ZeroCombiner(string str)
{
// Get number of zeros.
var n = str.Count(c => c == '0');
var limit = (int)Math.Pow(2, n);
// Create strings of '0' and 'o' based on binary numbers from 0 to 2^n.
var binaryStrings = new List<string>();
for (int i = 0; i < limit; ++i )
{
binaryStrings.Add(Binary(i, n + 1));
}
// Replace each zero with respect to each binary string.
var result = new List<string>();
foreach (var binaryString in binaryStrings)
{
var zeroCounter = 0;
var combinedString = string.Empty;
for (int i = 0; i < str.Length; ++i )
{
if (str[i] == '0')
{
combinedString += binaryString[zeroCounter];
++zeroCounter;
}
else
combinedString += str[i];
}
result.Add(combinedString);
}
return result;
}
string Binary(int i, int n)
{
string result = string.Empty;
while (n != 0)
{
result = result + (i % 2 == 0 ? '0' : 'o');
i = i / 2;
--n;
}
return result;
}
I've been given the assignment to write an algorithm in C# that checks the validity of a Canadian Social Insurance Number (SIN). Here are the steps to validate a SIN.
Given an example Number: 123 456 782
Remove the check digit (the last digit): 123456782
Extract the even digits (2,4,6,8th digith): 12345678
Double them:
2 4 6 8
| | | |
v v v v
4 8 12 16
Add the digits together: 4+8+1+2+1+6 = 22
Add the Odd placed digits: 1+3+5+7 = 16
Total : 38
Validity Algorithm
If the total is a multiple of 10, the check digit should be zero.
Otherwise, Subtract the Total from the next highest multiple of 10 (40 in this case)
The check digit for this SIN must be equal to the difference of the number and the totals from earlier (in this case, 40-38 = 2; check digit is 2, so the number is valid)
I'm lost on how to actually implement this in C#, how do I do this?
This is a nice problem to solve. This should be more efficient than converting to string and parsing back to integer. This solution will work on .NET 3.5 and later.
public static IEnumerable<int> ToDigitEnumerable(this int number)
{
IList<int> digits = new List<int>();
while(number > 0)
{
digits.Add(number%10);
number = number/10;
}
//digits are currently backwards, reverse the order
return digits.Reverse();
}
public static bool IsCanadianSocialInsuranceNumber(int number)
{
var digits = number.ToDigitEnumerable();
if (digits.Count() != 9) return false;
//The left side of the addition is adding all even indexes (except the last digit).
//We are adding even indexes since .NET uses base 0 for indexes
//The right side of the addition, multiplies the odd index's value by 2, then breaks each result into
//individual digits, then adds them together
var total = digits.Where((value, index) => index%2 == 0 && index != 8).Sum()
+ digits.Where((value, index) => index%2 != 0).Select(v => v*2)
.SelectMany(v => v.ToDigitEnumerable()).Sum();
//The final modulous 10 operator is to handle the scenarios where the total
//is divisble by 10, in those cases, the check sum should be 0, not 10
var checkDigit = (10 - (total%10)) % 10;
return digits.Last() == checkDigit;
}
One problem with this solution is that it assumes that number, represented as an integer, is 9 digits (can't start with a 0). If the number can start with a 0, then it has to be represented as a string (or converted to a string and padding with zeros). The logic to test will remain mostly intact, but the parts that assume integers will need to be swapped out with strings, and then you'll have to do parsing.
The specification you were given makes things a bit more complicated than they need to be: it's actually equivalent and simpler to just add the last digit into the checksum and make sure the checksum's last digit is 0.
The usual trouble new programmers have is "how do I get each digit?" Here's how:
In integer types, % 10 will delete everything but the last digit of the number: 123 % 10 == 3, and / 10 will delete the last digit of the number: 123 / 10 == 12.
In strings, str[i] - '0' will give you the digit at index i. The characters for digits are stored as special numbers: '0' is stored as 48 and '9' is stored as 57. If you subtract 48, you'll have the actual digit as a number. You don't really need to memorize "subtract 48", of course: if you just subtract '0', it will do the same thing: '8' - '0' == 8
Here are two efficient methods. One takes an int and checks the checksum of the SIN. One takes a string and checks both the format (must be "ddd ddd ddd") and the checksum of the SIN; though it's pretty efficient, it is a bit ugly and repetitive.
// Checks that the given int is a valid Canadian Social Insurance Number
// according to both range (000 000 000 to 999 999 998) and checksum.
public static bool IsValidSIN(int sin) {
if (sin < 0 || sin > 999999998) return false;
int checksum = 0;
for (int i = 4; i != 0; i--) {
checksum += sin % 10;
sin /= 10;
int addend = 2*(sin % 10); if (addend >= 10) addend -= 9;
checksum += addend;
sin /= 10;
}
return (checksum + sin) % 10 == 0;
}
// Checks that the given string is a valid Canadian Social Insurance Number
// according to both format ("ddd ddd ddd") and checksum.
// Implementation note: uses an admittedly ugly and repetitive parser.
public static bool IsValidSIN(string sin) {
if (sin.Length != 11) return false;
int checksum, addend;
checksum = sin[0] - '0';
if (checksum < 0 || checksum > 9) return false;
addend = 2*(sin[1] - '0'); if (addend >= 10) addend -= 9;
if (addend < 0 || addend > 9) return false;
checksum += addend;
addend = sin[2] - '0';
if (addend < 0 || addend > 9) return false;
checksum += addend;
if (sin[3] != ' ') return false;
addend = 2*(sin[4] - '0'); if (addend >= 10) addend -= 9;
if (addend < 0 || addend > 9) return false;
checksum += addend;
addend = sin[5] - '0';
if (addend < 0 || addend > 9) return false;
checksum += addend;
addend = 2*(sin[6] - '0'); if (addend >= 10) addend -= 9;
if (addend < 0 || addend > 9) return false;
checksum += addend;
if (sin[7] != ' ') return false;
addend = sin[8] - '0';
if (addend < 0 || addend > 9) return false;
checksum += addend;
addend = 2*(sin[9] - '0'); if (addend >= 10) addend -= 9;
if (addend < 0 || addend > 9) return false;
checksum += addend;
addend = sin[10] - '0';
if (addend < 0 || addend > 9) return false;
return (checksum + addend) % 10 == 0;
}
I don't know C# but here is a solution in Python. Maybe you can learn from it the method of how to implement it in C#.
def check(SIN):
SIN = ''.join(SIN.split(' '))
if len(SIN) != 9:
raise ValueError("A Canadian SIN must be 9 digits long")
check_digit = int(SIN[-1])
even_digits = [int(SIN[i]) for i in range(1,8,2)]
odd_digits = [int(SIN[i]) for i in range(0,8,2)]
total = sum(i/10 + i%10 for i in map(lambda x: 2*x, even_digits)) + sum(odd_digits)
if total%10 == 0:
return check_digit == 0
else:
return ((total/10)+1)*10 - total == check_digit
if __name__ == '__main__':
for SIN in ['123 456 782',
'123 456 789',
'046 454 286']:
print '%s is %sa valid Canadian SIN' % (SIN, '' if check(SIN) else 'NOT ')
which outputs:
123 456 782 is a valid Canadian SIN
123 456 789 is NOT a valid Canadian SIN
046 454 286 is a valid Canadian SIN
Search on the internet for "Luhn algorithm". You'll find a lot of examples.
The crux of the program is that you need to have some way of iterating over each integer in the SIN.
Since the easiest way is to convert the integer to a string for manipulation operations and back to an integer for addition/multiplication operations, I used the following approach:
The Program:
public class Program
{
static void Main(string[] args)
{
int sn = 123456782;
int[] Digits;
int AddedResult = 0;
string s = sn.ToString();
string sa = s.Substring(s.Length - 1, 1);
int checkDigit = Convert.ToInt32(sn.ToString().Substring(s.Length - 1, 1));
//get the last digit.
if (IsValidLength(sn))
{
sn = RemoveLastDigit(sn);
Digits = ExtractEvenDigits(sn);
Digits = DoubleDigits(Digits);
AddedResult = AddedEvenDigits(Digits);
AddedResult += AddOddDigits(sn);
if (IsValidSN(AddedResult, checkDigit))
{
Console.WriteLine("The number is valid");
}
else
{
Console.WriteLine("The Number is not valid");
}
}
else
{
Console.WriteLine("NotValidLength");
}
Console.Read();
}
public static bool IsValidSN(int AddedResult, int checkDigit)
{
return ((AddedResult % 10 == 0 && checkDigit == 0) || IsValidDifference(AddedResult, checkDigit));
}
public static bool IsValidDifference(int AddedResult, int checkDigit)
{
int nextHighestTens = AddedResult;
while (nextHighestTens % 10 != 0)
{
nextHighestTens++;
}
return ((nextHighestTens - AddedResult) == checkDigit);
}
public static int AddOddDigits(int sn)
{
string s = sn.ToString();
int i = 1;
int addedResult = 0;
foreach (char c in s)
{
if (i % 2 != 0)
{
addedResult += Convert.ToInt32(c.ToString());
}
i++;
}
return addedResult;
}
public static int AddedEvenDigits(int[] Digits)
{
int addedEvenDigits = 0;
string s = "";
for (int i = 0; i < Digits.Length; i++) //extract each digit. For example 12 is extracted as 1 and 2
{
s += Digits[i].ToString();
}
for (int i = 0; i < s.Length; i++) //now add all extracted digits
{
addedEvenDigits += Convert.ToInt32(s[i].ToString());
}
return addedEvenDigits;
}
public static int[] DoubleDigits(int[] Digits)
{
int[] doubledDigits = new int[Digits.Count()];
for (int i = 0; i < Digits.Length; i++)
{
doubledDigits[i] = Digits[i] * 2;
}
return doubledDigits;
}
public static int[] ExtractEvenDigits(int sn)
{
int[] EvenDigits = new int[4];
string s = sn.ToString(); //12345678
int j = 0;
for (int i = 1; i < s.Length; i += 2)
{
EvenDigits[j] = Convert.ToInt32(s[i].ToString());
j++;
}
return EvenDigits;
}
public static int RemoveLastDigit(int sn)
{
string s = sn.ToString();
return Convert.ToInt32(s.Substring(0, s.Count() - 1));
}
public static bool IsValidLength(int sn)
{
return (sn > 9999999 && sn < 1000000000);
}
}
I wrote this in about 20 minutes, so it's not really worthy to turn in. I plan on improving it as an exercise, and I wrote some unit tests for it (that I plan on making better).
[TestFixture]
public class SINTests
{
private int SinNumber = 123456782;
[Test]
public void TestValidNumber()
{
Assert.IsTrue(Program.IsValidLength(SinNumber));
}
[Test]
public void TestRemoveLastDigit()
{
Assert.AreEqual(12345678, Program.RemoveLastDigit(SinNumber));
}
[Test]
public void TestExtractEvenDigit()
{
int sn = 12345678;
int[] array = new int[] { 2,4,6,8 };
Assert.AreEqual(array, Program.ExtractEvenDigits(sn));
}
[Test]
public void TestAddOddDigits()
{
int sn = 12345678;
int result = 1 + 3 + 5 + 7;
Assert.AreEqual(result, Program.AddOddDigits(sn));
}
[Test]
public void TestDoubleEvenDigits()
{
int sn = 12345678;
int[] original = new int[] { 2, 4, 6, 8 };
int[] array = new int[] { 4, 8, 12, 16 };
Assert.AreEqual(array, Program.DoubleDigits(original));
}
[Test]
public void TestOddDigits()
{
int sn = 12345678;
Assert.AreEqual(16, Program.AddOddDigits(sn));
}
}
Since a string can be construed as an Array of Characters1, the operations that work on a string also need to be aware of the fact that Converting a character to an integer is different than converting a string to an integer. For instance:
Char c = '2';
int cInt = Convert.ToInt32(c); // returns 50
string s = c.ToString();
int sInt = Convert.ToInt32(s) //returns 2;
1Technically, a string is not an array of Characters in C# (though it is in C and C++), but because you can access the components of a string through an indexer, it can be treated like an array of characters.
I also recently coded this into an application. Before calling this, the string sSIN has already been checked through regex for being a 9-digit number.
public static bool IsCanadianSocialInsuranceNumber(string sSIN)
{
int iChecksum = 0;
int iDigit = 0;
for (int i = 0; i < sSIN.Length; i++)
{
// even number else odd
if (((i+1) % 2) == 0)
{
iDigit = int.Parse(sSIN.Substring(i, 1))*2;
iChecksum += (iDigit < 10) ? iDigit : iDigit - 9;
}
else
{
iChecksum += int.Parse(sSIN.Substring(i, 1));
}
}
return ((iChecksum % 10) == 0) ? true : false;
}
Here's a very simple way:
int test = 123456782;
if(test > 100000000 && test < 999999999)
{
int check = test % 10;
string temp = "";
foreach(char c in test.ToString().Substring(0, 8))
{
//The character codes for digits follow the same odd/even pattern as the digits.
//This code puts each digit or its value times 2, into a string and sums the digits
//after instead of keeping 2 separate totals
if(c % 2 == 1)
{
temp += c;
}
else
{
temp += (int.Parse(c.ToString()) * 2).ToString();
}
}
int temp2 = temp.Sum((x => int.Parse(x.ToString())));
//no need to compare the sum to the next 10, the modulus of 10 will work for this
int temp2mod = temp2 % 10;
if((temp2mod == 0 && temp2mod == check) || (10 - temp2mod == check))
return true;
}
return false;
public bool ValidateSIN(string sin)
{
if ((int)Char.GetNumericValue(sin[0]) == 0)
{
return false;
}
else
{
string evenString = "";
int totalOfEvens = 0;
int totalOfOdds = 0;
int total, nextMultipleOfTen, remainder;
int checkDigit = (int)Char.GetNumericValue(sin[8]);
// multiply each even number of the input string by 2
// get the resulting numbers into a string so the chars
// can be manipulated as individual digits
for (int i = 1; i <= 7; i += 2)
{
evenString += (Char.GetNumericValue(sin[i]) * 2);
}
// add the individual digits of the products from the above loop
foreach (char c in evenString)
{
totalOfEvens += (int)Char.GetNumericValue(c);
}
// get the odd numbers of the input string, minus the last number,
// and add them together
for (int i = 0; i <= 6; i += 2)
{
totalOfOdds += (int)Char.GetNumericValue(sin[i]);
}
total = totalOfEvens + totalOfOdds;
// take the quotient of total divided by 10 and add 1 to get the next multiple of ten
nextMultipleOfTen = (Math.DivRem(total, 10, out remainder) + 1) * 10;
if ((total % 10 == 0 && checkDigit == 0) || (checkDigit == nextMultipleOfTen - total))
{
return true;
}
else
{
return false;
}
}
}
Fastest method I've tried so far. No LINQ, no if/else, no odd/even checks, only 1 loop to get an array of integers from the string.
Caveat: no guards - input is assumed to be a string of 9 numbers.
public static bool IsValidSin(string input)
{
int[] luhnMap = { 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 };
int[] ints = new int[9];
for (int i = 0; i < 9; i++)
{
ints[i] = int.Parse(input[i].ToString());
}
int check = ints[0] + luhnMap[ints[1]] + ints[2] + luhnMap[ints[3]] + ints[4] + luhnMap[ints[5]] + ints[6] + luhnMap[ints[7]] + ints[8];
return (check % 10) == 0;
}
How do you convert a numerical number to an Excel column name in C# without using automation getting the value directly from Excel.
Excel 2007 has a possible range of 1 to 16384, which is the number of columns that it supports. The resulting values should be in the form of excel column names, e.g. A, AA, AAA etc.
Here's how I do it:
private string GetExcelColumnName(int columnNumber)
{
string columnName = "";
while (columnNumber > 0)
{
int modulo = (columnNumber - 1) % 26;
columnName = Convert.ToChar('A' + modulo) + columnName;
columnNumber = (columnNumber - modulo) / 26;
}
return columnName;
}
If anyone needs to do this in Excel without VBA, here is a way:
=SUBSTITUTE(ADDRESS(1;colNum;4);"1";"")
where colNum is the column number
And in VBA:
Function GetColumnName(colNum As Integer) As String
Dim d As Integer
Dim m As Integer
Dim name As String
d = colNum
name = ""
Do While (d > 0)
m = (d - 1) Mod 26
name = Chr(65 + m) + name
d = Int((d - m) / 26)
Loop
GetColumnName = name
End Function
You might need conversion both ways, e.g from Excel column adress like AAZ to integer and from any integer to Excel. The two methods below will do just that. Assumes 1 based indexing, first element in your "arrays" are element number 1.
No limits on size here, so you can use adresses like ERROR and that would be column number 2613824 ...
public static string ColumnAdress(int col)
{
if (col <= 26) {
return Convert.ToChar(col + 64).ToString();
}
int div = col / 26;
int mod = col % 26;
if (mod == 0) {mod = 26;div--;}
return ColumnAdress(div) + ColumnAdress(mod);
}
public static int ColumnNumber(string colAdress)
{
int[] digits = new int[colAdress.Length];
for (int i = 0; i < colAdress.Length; ++i)
{
digits[i] = Convert.ToInt32(colAdress[i]) - 64;
}
int mul=1;int res=0;
for (int pos = digits.Length - 1; pos >= 0; --pos)
{
res += digits[pos] * mul;
mul *= 26;
}
return res;
}
Sorry, this is Python instead of C#, but at least the results are correct:
def ColIdxToXlName(idx):
if idx < 1:
raise ValueError("Index is too small")
result = ""
while True:
if idx > 26:
idx, r = divmod(idx - 1, 26)
result = chr(r + ord('A')) + result
else:
return chr(idx + ord('A') - 1) + result
for i in xrange(1, 1024):
print "%4d : %s" % (i, ColIdxToXlName(i))
I discovered an error in my first post, so I decided to sit down and do the the math. What I found is that the number system used to identify Excel columns is not a base 26 system, as another person posted. Consider the following in base 10. You can also do this with the letters of the alphabet.
Space:.........................S1, S2, S3 : S1, S2, S3
....................................0, 00, 000 :.. A, AA, AAA
....................................1, 01, 001 :.. B, AB, AAB
.................................... …, …, … :.. …, …, …
....................................9, 99, 999 :.. Z, ZZ, ZZZ
Total states in space: 10, 100, 1000 : 26, 676, 17576
Total States:...............1110................18278
Excel numbers columns in the individual alphabetical spaces using base 26. You can see that in general, the state space progression is a, a^2, a^3, … for some base a, and the total number of states is a + a^2 + a^3 + … .
Suppose you want to find the total number of states A in the first N spaces. The formula for doing so is A = (a)(a^N - 1 )/(a-1). This is important because we need to find the space N that corresponds to our index K. If I want to find out where K lies in the number system I need to replace A with K and solve for N. The solution is N = log{base a} (A (a-1)/a +1). If I use the example of a = 10 and K = 192, I know that N = 2.23804… . This tells me that K lies at the beginning of the third space since it is a little greater than two.
The next step is to find exactly how far in the current space we are. To find this, subtract from K the A generated using the floor of N. In this example, the floor of N is two. So, A = (10)(10^2 – 1)/(10-1) = 110, as is expected when you combine the states of the first two spaces. This needs to be subtracted from K because these first 110 states would have already been accounted for in the first two spaces. This leaves us with 82 states. So, in this number system, the representation of 192 in base 10 is 082.
The C# code using a base index of zero is
private string ExcelColumnIndexToName(int Index)
{
string range = string.Empty;
if (Index < 0 ) return range;
int a = 26;
int x = (int)Math.Floor(Math.Log((Index) * (a - 1) / a + 1, a));
Index -= (int)(Math.Pow(a, x) - 1) * a / (a - 1);
for (int i = x+1; Index + i > 0; i--)
{
range = ((char)(65 + Index % a)).ToString() + range;
Index /= a;
}
return range;
}
//Old Post
A zero-based solution in C#.
private string ExcelColumnIndexToName(int Index)
{
string range = "";
if (Index < 0 ) return range;
for(int i=1;Index + i > 0;i=0)
{
range = ((char)(65 + Index % 26)).ToString() + range;
Index /= 26;
}
if (range.Length > 1) range = ((char)((int)range[0] - 1)).ToString() + range.Substring(1);
return range;
}
This answer is in javaScript:
function getCharFromNumber(columnNumber){
var dividend = columnNumber;
var columnName = "";
var modulo;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
columnName = String.fromCharCode(65 + modulo).toString() + columnName;
dividend = parseInt((dividend - modulo) / 26);
}
return columnName;
}
Easy with recursion.
public static string GetStandardExcelColumnName(int columnNumberOneBased)
{
int baseValue = Convert.ToInt32('A');
int columnNumberZeroBased = columnNumberOneBased - 1;
string ret = "";
if (columnNumberOneBased > 26)
{
ret = GetStandardExcelColumnName(columnNumberZeroBased / 26) ;
}
return ret + Convert.ToChar(baseValue + (columnNumberZeroBased % 26) );
}
I'm surprised all of the solutions so far contain either iteration or recursion.
Here's my solution that runs in constant time (no loops). This solution works for all possible Excel columns and checks that the input can be turned into an Excel column. Possible columns are in the range [A, XFD] or [1, 16384]. (This is dependent on your version of Excel)
private static string Turn(uint col)
{
if (col < 1 || col > 16384) //Excel columns are one-based (one = 'A')
throw new ArgumentException("col must be >= 1 and <= 16384");
if (col <= 26) //one character
return ((char)(col + 'A' - 1)).ToString();
else if (col <= 702) //two characters
{
char firstChar = (char)((int)((col - 1) / 26) + 'A' - 1);
char secondChar = (char)(col % 26 + 'A' - 1);
if (secondChar == '#') //Excel is one-based, but modulo operations are zero-based
secondChar = 'Z'; //convert one-based to zero-based
return string.Format("{0}{1}", firstChar, secondChar);
}
else //three characters
{
char firstChar = (char)((int)((col - 1) / 702) + 'A' - 1);
char secondChar = (char)((col - 1) / 26 % 26 + 'A' - 1);
char thirdChar = (char)(col % 26 + 'A' - 1);
if (thirdChar == '#') //Excel is one-based, but modulo operations are zero-based
thirdChar = 'Z'; //convert one-based to zero-based
return string.Format("{0}{1}{2}", firstChar, secondChar, thirdChar);
}
}
Same implementation in Java
public String getExcelColumnName (int columnNumber)
{
int dividend = columnNumber;
int i;
String columnName = "";
int modulo;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
i = 65 + modulo;
columnName = new Character((char)i).toString() + columnName;
dividend = (int)((dividend - modulo) / 26);
}
return columnName;
}
int nCol = 127;
string sChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string sCol = "";
while (nCol >= 26)
{
int nChar = nCol % 26;
nCol = (nCol - nChar) / 26;
// You could do some trick with using nChar as offset from 'A', but I am lazy to do it right now.
sCol = sChars[nChar] + sCol;
}
sCol = sChars[nCol] + sCol;
Update: Peter's comment is right. That's what I get for writing code in the browser. :-) My solution was not compiling, it was missing the left-most letter and it was building the string in reverse order - all now fixed.
Bugs aside, the algorithm is basically converting a number from base 10 to base 26.
Update 2: Joel Coehoorn is right - the code above will return AB for 27. If it was real base 26 number, AA would be equal to A and the next number after Z would be BA.
int nCol = 127;
string sChars = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string sCol = "";
while (nCol > 26)
{
int nChar = nCol % 26;
if (nChar == 0)
nChar = 26;
nCol = (nCol - nChar) / 26;
sCol = sChars[nChar] + sCol;
}
if (nCol != 0)
sCol = sChars[nCol] + sCol;
..And converted to php:
function GetExcelColumnName($columnNumber) {
$columnName = '';
while ($columnNumber > 0) {
$modulo = ($columnNumber - 1) % 26;
$columnName = chr(65 + $modulo) . $columnName;
$columnNumber = (int)(($columnNumber - $modulo) / 26);
}
return $columnName;
}
Just throwing in a simple two-line C# implementation using recursion, because all the answers here seem far more complicated than necessary.
/// <summary>
/// Gets the column letter(s) corresponding to the given column number.
/// </summary>
/// <param name="column">The one-based column index. Must be greater than zero.</param>
/// <returns>The desired column letter, or an empty string if the column number was invalid.</returns>
public static string GetColumnLetter(int column) {
if (column < 1) return String.Empty;
return GetColumnLetter((column - 1) / 26) + (char)('A' + (column - 1) % 26);
}
Although there are already a bunch of valid answers1, none get into the theory behind it.
Excel column names are bijective base-26 representations of their number. This is quite different than an ordinary base 26 (there is no leading zero), and I really recommend reading the Wikipedia entry to grasp the differences. For example, the decimal value 702 (decomposed in 26*26 + 26) is represented in "ordinary" base 26 by 110 (i.e. 1x26^2 + 1x26^1 + 0x26^0) and in bijective base-26 by ZZ (i.e. 26x26^1 + 26x26^0).
Differences aside, bijective numeration is a positional notation, and as such we can perform conversions using an iterative (or recursive) algorithm which on each iteration finds the digit of the next position (similarly to an ordinary base conversion algorithm).
The general formula to get the digit at the last position (the one indexed 0) of the bijective base-k representation of a decimal number m is (f being the ceiling function minus 1):
m - (f(m / k) * k)
The digit at the next position (i.e. the one indexed 1) is found by applying the same formula to the result of f(m / k). We know that for the last digit (i.e. the one with the highest index) f(m / k) is 0.
This forms the basis for an iteration that finds each successive digit in bijective base-k of a decimal number. In pseudo-code it would look like this (digit() maps a decimal integer to its representation in the bijective base -- e.g. digit(1) would return A in bijective base-26):
fun conv(m)
q = f(m / k)
a = m - (q * k)
if (q == 0)
return digit(a)
else
return conv(q) + digit(a);
So we can translate this to C#2 to get a generic3 "conversion to bijective base-k" ToBijective() routine:
class BijectiveNumeration {
private int baseK;
private Func<int, char> getDigit;
public BijectiveNumeration(int baseK, Func<int, char> getDigit) {
this.baseK = baseK;
this.getDigit = getDigit;
}
public string ToBijective(double decimalValue) {
double q = f(decimalValue / baseK);
double a = decimalValue - (q * baseK);
return ((q > 0) ? ToBijective(q) : "") + getDigit((int)a);
}
private static double f(double i) {
return (Math.Ceiling(i) - 1);
}
}
Now for conversion to bijective base-26 (our "Excel column name" use case):
static void Main(string[] args)
{
BijectiveNumeration bijBase26 = new BijectiveNumeration(
26,
(value) => Convert.ToChar('A' + (value - 1))
);
Console.WriteLine(bijBase26.ToBijective(1)); // prints "A"
Console.WriteLine(bijBase26.ToBijective(26)); // prints "Z"
Console.WriteLine(bijBase26.ToBijective(27)); // prints "AA"
Console.WriteLine(bijBase26.ToBijective(702)); // prints "ZZ"
Console.WriteLine(bijBase26.ToBijective(16384)); // prints "XFD"
}
Excel's maximum column index is 16384 / XFD, but this code will convert any positive number.
As an added bonus, we can now easily convert to any bijective base. For example for bijective base-10:
static void Main(string[] args)
{
BijectiveNumeration bijBase10 = new BijectiveNumeration(
10,
(value) => value < 10 ? Convert.ToChar('0'+value) : 'A'
);
Console.WriteLine(bijBase10.ToBijective(1)); // prints "1"
Console.WriteLine(bijBase10.ToBijective(10)); // prints "A"
Console.WriteLine(bijBase10.ToBijective(123)); // prints "123"
Console.WriteLine(bijBase10.ToBijective(20)); // prints "1A"
Console.WriteLine(bijBase10.ToBijective(100)); // prints "9A"
Console.WriteLine(bijBase10.ToBijective(101)); // prints "A1"
Console.WriteLine(bijBase10.ToBijective(2010)); // prints "19AA"
}
1 This generic answer can eventually be reduced to the other, correct, specific answers, but I find it hard to fully grasp the logic of the solutions without the formal theory behind bijective numeration in general. It also proves its correctness nicely. Additionally, several similar questions link back to this one, some being language-agnostic or more generic. That's why I thought the addition of this answer was warranted, and that this question was a good place to put it.
2 C# disclaimer: I implemented an example in C# because this is what is asked here, but I have never learned nor used the language. I have verified it does compile and run, but please adapt it to fit the language best practices / general conventions, if necessary.
3 This example only aims to be correct and understandable ; it could and should be optimized would performance matter (e.g. with tail-recursion -- but that seems to require trampolining in C#), and made safer (e.g. by validating parameters).
I wanted to throw in my static class I use, for interoping between col index and col Label. I use a modified accepted answer for my ColumnLabel Method
public static class Extensions
{
public static string ColumnLabel(this int col)
{
var dividend = col;
var columnLabel = string.Empty;
int modulo;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
columnLabel = Convert.ToChar(65 + modulo).ToString() + columnLabel;
dividend = (int)((dividend - modulo) / 26);
}
return columnLabel;
}
public static int ColumnIndex(this string colLabel)
{
// "AD" (1 * 26^1) + (4 * 26^0) ...
var colIndex = 0;
for(int ind = 0, pow = colLabel.Count()-1; ind < colLabel.Count(); ++ind, --pow)
{
var cVal = Convert.ToInt32(colLabel[ind]) - 64; //col A is index 1
colIndex += cVal * ((int)Math.Pow(26, pow));
}
return colIndex;
}
}
Use this like...
30.ColumnLabel(); // "AD"
"AD".ColumnIndex(); // 30
private String getColumn(int c) {
String s = "";
do {
s = (char)('A' + (c % 26)) + s;
c /= 26;
} while (c-- > 0);
return s;
}
Its not exactly base 26, there is no 0 in the system. If there was, 'Z' would be followed by 'BA' not by 'AA'.
if you just want it for a cell formula without code, here's a formula for it:
IF(COLUMN()>=26,CHAR(ROUND(COLUMN()/26,1)+64)&CHAR(MOD(COLUMN(),26)+64),CHAR(COLUMN()+64))
In Delphi (Pascal):
function GetExcelColumnName(columnNumber: integer): string;
var
dividend, modulo: integer;
begin
Result := '';
dividend := columnNumber;
while dividend > 0 do begin
modulo := (dividend - 1) mod 26;
Result := Chr(65 + modulo) + Result;
dividend := (dividend - modulo) div 26;
end;
end;
A little late to the game, but here's the code I use (in C#):
private static readonly string _Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static int ColumnNameParse(string value)
{
// assumes value.Length is [1,3]
// assumes value is uppercase
var digits = value.PadLeft(3).Select(x => _Alphabet.IndexOf(x));
return digits.Aggregate(0, (current, index) => (current * 26) + (index + 1));
}
In perl, for an input of 1 (A), 27 (AA), etc.
sub excel_colname {
my ($idx) = #_; # one-based column number
--$idx; # zero-based column index
my $name = "";
while ($idx >= 0) {
$name .= chr(ord("A") + ($idx % 26));
$idx = int($idx / 26) - 1;
}
return scalar reverse $name;
}
Though I am late to the game, Graham's answer is far from being optimal. Particularly, you don't have to use the modulo, call ToString() and apply (int) cast. Considering that in most cases in C# world you would start numbering from 0, here is my revision:
public static string GetColumnName(int index) // zero-based
{
const byte BASE = 'Z' - 'A' + 1;
string name = String.Empty;
do
{
name = Convert.ToChar('A' + index % BASE) + name;
index = index / BASE - 1;
}
while (index >= 0);
return name;
}
More than 30 solutions already, but here's my one-line C# solution...
public string IntToExcelColumn(int i)
{
return ((i<16926? "" : ((char)((((i/26)-1)%26)+65)).ToString()) + (i<2730? "" : ((char)((((i/26)-1)%26)+65)).ToString()) + (i<26? "" : ((char)((((i/26)-1)%26)+65)).ToString()) + ((char)((i%26)+65)));
}
After looking at all the supplied Versions here, I decided to do one myself, using recursion.
Here is my vb.net Version:
Function CL(ByVal x As Integer) As String
If x >= 1 And x <= 26 Then
CL = Chr(x + 64)
Else
CL = CL((x - x Mod 26) / 26) & Chr((x Mod 26) + 1 + 64)
End If
End Function
Refining the original solution (in C#):
public static class ExcelHelper
{
private static Dictionary<UInt16, String> l_DictionaryOfColumns;
public static ExcelHelper() {
l_DictionaryOfColumns = new Dictionary<ushort, string>(256);
}
public static String GetExcelColumnName(UInt16 l_Column)
{
UInt16 l_ColumnCopy = l_Column;
String l_Chars = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String l_rVal = "";
UInt16 l_Char;
if (l_DictionaryOfColumns.ContainsKey(l_Column) == true)
{
l_rVal = l_DictionaryOfColumns[l_Column];
}
else
{
while (l_ColumnCopy > 26)
{
l_Char = l_ColumnCopy % 26;
if (l_Char == 0)
l_Char = 26;
l_ColumnCopy = (l_ColumnCopy - l_Char) / 26;
l_rVal = l_Chars[l_Char] + l_rVal;
}
if (l_ColumnCopy != 0)
l_rVal = l_Chars[l_ColumnCopy] + l_rVal;
l_DictionaryOfColumns.ContainsKey(l_Column) = l_rVal;
}
return l_rVal;
}
}
Here is an Actionscript version:
private var columnNumbers:Array = ['A', 'B', 'C', 'D', 'E', 'F' , 'G', 'H', 'I', 'J', 'K' ,'L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
private function getExcelColumnName(columnNumber:int) : String{
var dividend:int = columnNumber;
var columnName:String = "";
var modulo:int;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
columnName = columnNumbers[modulo] + columnName;
dividend = int((dividend - modulo) / 26);
}
return columnName;
}
JavaScript Solution
/**
* Calculate the column letter abbreviation from a 1 based index
* #param {Number} value
* #returns {string}
*/
getColumnFromIndex = function (value) {
var base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
var remainder, result = "";
do {
remainder = value % 26;
result = base[(remainder || 26) - 1] + result;
value = Math.floor(value / 26);
} while (value > 0);
return result;
};
These my codes to convert specific number (index start from 1) to Excel Column.
public static string NumberToExcelColumn(uint number)
{
uint originalNumber = number;
uint numChars = 1;
while (Math.Pow(26, numChars) < number)
{
numChars++;
if (Math.Pow(26, numChars) + 26 >= number)
{
break;
}
}
string toRet = "";
uint lastValue = 0;
do
{
number -= lastValue;
double powerVal = Math.Pow(26, numChars - 1);
byte thisCharIdx = (byte)Math.Truncate((columnNumber - 1) / powerVal);
lastValue = (int)powerVal * thisCharIdx;
if (numChars - 2 >= 0)
{
double powerVal_next = Math.Pow(26, numChars - 2);
byte thisCharIdx_next = (byte)Math.Truncate((columnNumber - lastValue - 1) / powerVal_next);
int lastValue_next = (int)Math.Pow(26, numChars - 2) * thisCharIdx_next;
if (thisCharIdx_next == 0 && lastValue_next == 0 && powerVal_next == 26)
{
thisCharIdx--;
lastValue = (int)powerVal * thisCharIdx;
}
}
toRet += (char)((byte)'A' + thisCharIdx + ((numChars > 1) ? -1 : 0));
numChars--;
} while (numChars > 0);
return toRet;
}
My Unit Test:
[TestMethod]
public void Test()
{
Assert.AreEqual("A", NumberToExcelColumn(1));
Assert.AreEqual("Z", NumberToExcelColumn(26));
Assert.AreEqual("AA", NumberToExcelColumn(27));
Assert.AreEqual("AO", NumberToExcelColumn(41));
Assert.AreEqual("AZ", NumberToExcelColumn(52));
Assert.AreEqual("BA", NumberToExcelColumn(53));
Assert.AreEqual("ZZ", NumberToExcelColumn(702));
Assert.AreEqual("AAA", NumberToExcelColumn(703));
Assert.AreEqual("ABC", NumberToExcelColumn(731));
Assert.AreEqual("ACQ", NumberToExcelColumn(771));
Assert.AreEqual("AYZ", NumberToExcelColumn(1352));
Assert.AreEqual("AZA", NumberToExcelColumn(1353));
Assert.AreEqual("AZB", NumberToExcelColumn(1354));
Assert.AreEqual("BAA", NumberToExcelColumn(1379));
Assert.AreEqual("CNU", NumberToExcelColumn(2413));
Assert.AreEqual("GCM", NumberToExcelColumn(4823));
Assert.AreEqual("MSR", NumberToExcelColumn(9300));
Assert.AreEqual("OMB", NumberToExcelColumn(10480));
Assert.AreEqual("ULV", NumberToExcelColumn(14530));
Assert.AreEqual("XFD", NumberToExcelColumn(16384));
}
Sorry, this is Python instead of C#, but at least the results are correct:
def excel_column_number_to_name(column_number):
output = ""
index = column_number-1
while index >= 0:
character = chr((index%26)+ord('A'))
output = output + character
index = index/26 - 1
return output[::-1]
for i in xrange(1, 1024):
print "%4d : %s" % (i, excel_column_number_to_name(i))
Passed these test cases:
Column Number: 494286 => ABCDZ
Column Number: 27 => AA
Column Number: 52 => AZ
For what it is worth, here is Graham's code in Powershell:
function ConvertTo-ExcelColumnID {
param (
[parameter(Position = 0,
HelpMessage = "A 1-based index to convert to an excel column ID. e.g. 2 => 'B', 29 => 'AC'",
Mandatory = $true)]
[int]$index
);
[string]$result = '';
if ($index -le 0 ) {
return $result;
}
while ($index -gt 0) {
[int]$modulo = ($index - 1) % 26;
$character = [char]($modulo + [int][char]'A');
$result = $character + $result;
[int]$index = ($index - $modulo) / 26;
}
return $result;
}
Another VBA way
Public Function GetColumnName(TargetCell As Range) As String
GetColumnName = Split(CStr(TargetCell.Cells(1, 1).Address), "$")(1)
End Function
Here's my super late implementation in PHP. This one's recursive. I wrote it just before I found this post. I wanted to see if others had solved this problem already...
public function GetColumn($intNumber, $strCol = null) {
if ($intNumber > 0) {
$intRem = ($intNumber - 1) % 26;
$strCol = $this->GetColumn(intval(($intNumber - $intRem) / 26), sprintf('%s%s', chr(65 + $intRem), $strCol));
}
return $strCol;
}