how do I perform mathematical functions that may exceed LONG_MAX - max

how do I perform ( A div B ) mod C where I am calculating A in one function,B in another function,and C is say ( 10 pow 9 plus 7 ) but both A and B may be greater than C,or INT_MAX

if the only problem is the size of the numbers you can use long. if the number may be larger then long.MAX_VALUE then you need some function to calculate using strings, or use two or more long types, and make your own functions. for example, the plus function will get two long types, check if the sum of them is smaller then one of them(meaning they went over the MAX_SIZE), then return an array of long, containing to numbers, one for the carry bit, and one for the sum.
here is an example in c#, but it's easy to translate it to c++
public static string sum(long a, long b)
{
string sum;
if (a + b > a && a + b > b)
{
sum = (a + b).ToString();
}
else
{
string aStr = a.ToString();
string bStr = b.ToString();
if (bStr.Length > aStr.Length)
{
string tmp = aStr;
aStr = bStr;
bStr = tmp;
}
sum = new string('0', aStr.Length + bStr.Length);
char[] arr = sum.ToCharArray();
for (int i = 0; i < bStr.Length; i++)
{
int loc = sum.Length - 1 - i;
arr[loc] += (char)(aStr[aStr.Length - 1 - i] + bStr[bStr.Length - 1 - i] - '0' * 2);
if (arr[loc] > '9')
{
arr[loc - 1] = '1';
arr[loc] = (char)(arr[loc] - '9' - 1);
}
}
for (int i = bStr.Length ; i < aStr.Length; i++)
{
int loc = sum.Length - 1 - i;
arr[loc] += (char)(aStr[aStr.Length - 1 - i] - '0');
if (arr[loc] > '9')
{
arr[loc - 1] = '1';
arr[loc] = (char)(arr[loc] - '9' - 1);
}
}
sum = new string(arr);
}
return sum;
}
}

Related

Divide a large number represented in string by 2 , add 1 or substract 1 [duplicate]

This question already has answers here:
minimum number of steps to reduce number to 1
(10 answers)
Closed 6 years ago.
I am working on a code challenge now. My solution got "time exceed" even I have optimized it. I am seeking for help about more efficient solution or optimizing my solution a step more.
The description of the problem is :
Write a function which takes a positive integer as a string and returns the minimum number of operations needed to transform the number to 1. The number is up to 309 digits long, so there won't too many character than you can express in that many digits.
The transform process is limited to three operations:
1. Add 1
2. Subtract 1
3. Divide the number by 2 (only even number allow here)
My idea is to use DFS to traverse all possible solution with memorization to speed it up. But it does exceed the time limitation. The problem can not use dp because dp require a very large array to memorize. Below is my code:
private static int dfs(String num, int step,Map<String,Integer> memory){
if(num.equals("1")){
return step;
}
Integer size = memory.get(num);
if(size != null && size < step){
return Integer.MAX_VALUE;
}
memory.put(num, step);
int min = Integer.MAX_VALUE;
int lastDigit = num.charAt(num.length() - 1) - '0';
if(lastDigit % 2 == 0){
min = Math.min(min, dfs(divideBy2(num), step + 1, memory));
}else{
min = Math.min(min, dfs(divideBy2(num), step + 2, memory));
min = Math.min(min, dfs(divideBy2(plusOne(num)), step + 2, memory));
}
return min;
}
private static String plusOne(String num){
StringBuilder sb = new StringBuilder();
int carry = 1;
for(int i = num.length() - 1; i >=0; i--){
int d = (carry + num.charAt(i) - '0') % 10;
carry = (carry + num.charAt(i) - '0') / 10;
sb.insert(0, d);
}
if(carry == 1){
sb.insert(0, carry);
}
return sb.toString();
}
private static String divideBy2(String num){
StringBuilder sb = new StringBuilder();
int x = 0;
for(int i = 0; i < num.length(); i++){
int d = (x * 10 + num.charAt(i) - '0') / 2 ;
x = (num.charAt(i) - '0') % 2 ;
if( i > 0 || (i == 0 && d != 0))
sb.append(d);
}
return sb.toString();
}
Note: After test several cases: I got some sense but can not generalize the rule.
If the current number is odd. we got two choices here: plus 1 or subtract 1. The number after the operation can be divided by 2 more times, the steps will be shorter.
Update: Hi, guys, I work all the night and find a solution to pass the test. The idea is divide the problem into 2 sub-problem: 1. if the number is even, just divide it by two. 2. if the number is odd, choose the way let the number has more tailing zeros in its bit representation. I will explain more about the odd situation: if the number is odd, the last two bit can be "01" or "11". When it is "01", decrease it by 1 , which let the last two bit become to "00". If it is "11", increase it by 1, which generate "00". By doing this, the next even number generated by the odd number can be divided more times, which is really fast in practice. Below is my code, if you have some questions about the implementation, feel free to send me a message:
public static int answer(String n) {
// Your code goes here.
int count = 0;
while(!n.equals("1")){
if((n.charAt(n.length() - 1) - '0') % 2 == 0){
n = divideBy2(n);
}else if(n.equals("3") || lastTwoBit(n)){
n = subtractOne(n);
}else{
n = plusOne(n);
}
count++;
}
return count;
}
private static boolean lastTwoBit(String num){
int n = -1;
if(num.length() == 1){
n = Integer.valueOf(num);
}else{
n = Integer.valueOf(num.substring(num.length() - 2, num.length()));
}
if(((n >>> 1) & 1) == 0){
return true;
}
return false;
}
private static String subtractOne(String num){
if(num.equals("1")){
return "0";
}
StringBuilder sb = new StringBuilder();
int carry = -1;
for(int i = num.length() - 1; i >= 0; i--){
int d = carry + num.charAt(i) - '0';
if(d < 0){
carry = -1;
sb.insert(0, '9');
}else if((d == 0 && i != 0) || d > 0){
carry = 0;
sb.insert(0, d );
}
}
return sb.toString();
}
private static String plusOne(String num){
StringBuilder sb = new StringBuilder();
int carry = 1;
int i = 0;
for(i = num.length() - 1; i >=0; i--){
if(carry == 0){
break;
}
int d = (carry + num.charAt(i) - '0') % 10;
carry = (carry + num.charAt(i) - '0') / 10;
sb.insert(0, d);
}
if(carry ==0){
sb.insert(0, num.substring(0, i + 1));
}
if(carry == 1){
sb.insert(0, carry);
}
return sb.toString();
}
private static String divideBy2(String num){
StringBuilder sb = new StringBuilder();
int x = 0;
for(int i = 0; i < num.length(); i++){
int d = (x * 10 + num.charAt(i) - '0') / 2 ;
x = (num.charAt(i) - '0') % 2 ;
if( i > 0 || (i == 0 && d != 0))
sb.append(d);
}
return sb.toString();
}
While not at 1...
if Odd... Subtract 1 => even
if Even.. Divide by 2.
just sum the ops and return.
e.g. 5593
5593 -1 = 5592 /2 = 2796 /2 = 1398 /2 = 699 -1 = 698 /2 = 349 -1 = 348 /2 = 174 /2 = 87 -1 = 86 /2 = 43 -1 = 42 /2 = 21 -1 = 20 /2 = 10 /2 = 5 -1 = 4 /2 = 2 /2 = 1
19 Operations -///-/-//-/-/-//-//
Edit: Time complexity is O(logN) for we divide the number by two / subtract and then divide.
and Space is O(1)
public int make1(string s)
{
int n = 0;
while(s != "1")
{
switch(s[s.Length-1])
{
case '0':
case '2':
case '4':
case '6':
case '8':
s = div2(s);
++n;
break;
case '1':
case '3':
case '5':
case '7':
case '9':
s = minus1(s);
s = div2(s);
n += 2;
}
}
return n;
}

FInd all lists of 4 positive integers whose sum is 100

I'd like to generate a list of all possible lists of 4 positive integers whose sum equals 100, exactly. (The summands do not need to be unique.)
Possible example snippet:
[
// Using (1+1+1+97)
[1,1,1,97],
[1,1,97,1],
[1,97,1,1],
[97,1,1,1],
// Using (2+1+1+96)
[2,1,1,96],
[2,1,96,1],
[2,96,1,1],
[96,2,1,1],
[1,2,1,96],
[1,2,96,1],
[1,96,2,1],
[96,1,2,1],
[1,1,2,96],
[1,1,96,2],
[1,96,1,2],
[96,1,1,2],
// Using (2+2+1+95), etc...
]
What's an efficient way of doing this? (Pseudo-code or advice is fine.)
Here's a generic solution for any number of parts:
// create(100, 4) returns the 156849 solutions
Iterable<List<int>> create(int max, int parts) sync* {
assert(max >= parts);
if (parts == 1) {
yield [max];
} else {
for (int i = max - parts + 1; i > 0; i--) {
yield* create(max - i, parts - 1).map((e) => e.toList()..add(i));
}
}
}
And a more optimized solution for 4 numbers:
// create(100) returns the 156849 solutions
Iterable<List<int>> create(int max) sync* {
for (int a = 1; a <= max - 3; a++) { // -3 because b/c/d are >= 1
for (int b = 1; b <= max - a; b++) {
for (int c = 1; c <= max - a - b - 1; c++) { // -1 because d is >=1
yield [a, b, c, max - a - b - c];
}
}
}
}
I think it is best to start with a solution and then change the solution to other valid solutions. I assume 0 is not a valid number.
Lets start at [97,1,1,1]
then we substract one from 97, leaving 96.
we have [96,1,1,1] leaving 1. So we have a question that gives us the partial answer:
"generate a list of all possible lists of 3 positive integers whose sum equals 4"
then we substract one from 96,
"generate a list of all possible lists of 3 positive integers whose sum equals 5"
then we substract one from 95,
"generate a list of all possible lists of 3 positive integers whose sum equals 6"
etc. etc.
because the bunch of questions really looks much like the original question we can re-do the trick to go from 3 places to 2 places.
[2,1,1] (leaving 1) => "generate a list of all possible lists of 2 positive integers whose sum equals 3" which is easy to write.
Now you can simply write a nice recursive formula.
Iterative and recursive solutions:
(Try it on DartPad
void main() {
List<List<int>> resultList1 = <List<int>>[];
for(int i1 = 1; i1 < 98; i1++) {
for(int i2 = 1; (i1 + i2) < 99; i2++) {
for(int i3 = 1; (i1 + i2 + i3) < 100; i3++) {
for(int i4 = 1; (i1 + i2 + i3 + i4) <= 100; i4++) {
if((i1 + i2 + i3 +i4) == 100) {
resultList1.add([i1, i2, i3, i4]);
}
}
}
}
}
// print(resultList1);
print(resultList1.length);
final int elementCount = 4;
final int target = 100;
final List<List<int>> resultList2 = <List<int>>[];
sum(elementCount, target, resultList2, [0, 0, 0, 0], 0);
// print(result);
print(resultList2.length);
}
void sum(int elementCount, int target, List<List<int>> result, List<int> values,
int curPos) {
for (int i = values[curPos] + 1; i <= target - curPos; i++) {
// debugging only
// if(curPos == 0) {
// print(i);
// }
// end debugging only
values[curPos] = i;
if (curPos == elementCount - 1) {
if (values.reduce((int a, int b) => a + b) == 100) {
// print(values);
result.add(values.toList());
}
} else {
sum(elementCount, target, result, values, curPos + 1);
}
for(int j = curPos + 1; j < values.length; j++) {
values[j] = 0;
}
}
}
The result contains 156849 elements from [1,1,1,97] to [97,1,1,1].
The recursive version supports variable number of elements and variable sum target value. For example by calling it like:
final int elementCount = 3;
final int target = 50;
final List<List<int>> resultList2 = <List<int>>[];
sum(elementCount, target, resultList2, [0, 0, 0], 0);
I think the most straightforward way is to use 3 loops.
resultList = []
for a from 1 to 97:
for b from 1 to 97:
for c from 1 to 97:
d = 100-a-b-c
if d > 0:
resultList.append([a,b,c,d])
recursive approach:
MakeSum(Sum, NItems, ResultList)
if NItems = 1
output ResultList + [Sum]
else
for i = 1 to Sum - NItems + 1
MakeSum(Sum - i, NItems - 1, ResultList + [i])
Here is a simple solution in Python that produces all possible results in lexicographic order:
resultList = []
for a in xrange(1,98):
for b in xrange(1,98):
for c in xrange(1,98):
d = 100 - a - b - c
if d > 0 and a <= b <= c <= d:
resultList.append([a,b,c,d])
The result list has 7153 entries, beginning with [1,1,1,97] and ending with [25,25,25,25]. You can run the program at http://ideone.com/8m7b1h.

Clean algorithm to get Excel column letters from column index [duplicate]

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;
}

Maximum product prefix string

The following is a demo question from a coding interview site called codility:
A prefix of a string S is any leading contiguous part of S. For example, "c" and "cod" are prefixes of the string "codility". For simplicity, we require prefixes to be non-empty.
The product of prefix P of string S is the number of occurrences of P multiplied by the length of P. More precisely, if prefix P consists of K characters and P occurs exactly T times in S, then the product equals K * T.
For example, S = "abababa" has the following prefixes:
"a", whose product equals 1 * 4 = 4,
"ab", whose product equals 2 * 3 = 6,
"aba", whose product equals 3 * 3 = 9,
"abab", whose product equals 4 * 2 = 8,
"ababa", whose product equals 5 * 2 = 10,
"ababab", whose product equals 6 * 1 = 6,
"abababa", whose product equals 7 * 1 = 7.
The longest prefix is identical to the original string. The goal is to choose such a prefix as maximizes the value of the product. In above example the maximal product is 10.
Below is my poor solution in Java requiring O(N^2) time. It is apparently possible to do this in O(N). I was thinking Kadanes algorithm. But I can't think of any way that I can encode some information at each step that lets me find the running max. Can any one think of an O(N) algorithm for this?
import java.util.HashMap;
class Solution {
public int solution(String S) {
int N = S.length();
if(N<1 || N>300000){
System.out.println("Invalid length");
return(-1);
}
HashMap<String,Integer> prefixes = new HashMap<String,Integer>();
for(int i=0; i<N; i++){
String keystr = "";
for(int j=i; j>=0; j--) {
keystr += S.charAt(j);
if(!prefixes.containsKey(keystr))
prefixes.put(keystr,keystr.length());
else{
int newval = prefixes.get(keystr)+keystr.length();
if(newval > 1000000000)return 1000000000;
prefixes.put(keystr,newval);
}
}
}
int maax1 = 0;
for(int val : prefixes.values())
if(val>maax1)
maax1 = val;
return maax1;
}
}
Here's a O(n log n) version based on suffix arrays. There are O(n) construction algorithms for suffix arrays, I just don't have the patience to code them.
Example output (this output isn't O(n), but it's only to show that we can indeed compute all the scores):
4*1 a
3*3 aba
2*5 ababa
1*7 abababa
3*2 ab
2*4 abab
1*6 ababab
Basically you have to reverse the string, and compute the suffix array (SA) and the longest common prefix (LCP).
Then you have traverse the SA array backwards looking for LCPs that match the entire suffix (prefix in the original string). If there's a match, increment the counter, otherwise reset it to 1. Each suffix (prefix) receive a "score" (SCR) that corresponds to the number of times it appears in the original string.
#include <iostream>
#include <cstring>
#include <string>
#define MAX 10050
using namespace std;
int RA[MAX], tempRA[MAX];
int SA[MAX], tempSA[MAX];
int C[MAX];
int Phi[MAX], PLCP[MAX], LCP[MAX];
int SCR[MAX];
void suffix_sort(int n, int k) {
memset(C, 0, sizeof C);
for (int i = 0; i < n; i++)
C[i + k < n ? RA[i + k] : 0]++;
int sum = 0;
for (int i = 0; i < max(256, n); i++) {
int t = C[i];
C[i] = sum;
sum += t;
}
for (int i = 0; i < n; i++)
tempSA[C[SA[i] + k < n ? RA[SA[i] + k] : 0]++] = SA[i];
memcpy(SA, tempSA, n*sizeof(int));
}
void suffix_array(string &s) {
int n = s.size();
for (int i = 0; i < n; i++)
RA[i] = s[i] - 1;
for (int i = 0; i < n; i++)
SA[i] = i;
for (int k = 1; k < n; k *= 2) {
suffix_sort(n, k);
suffix_sort(n, 0);
int r = tempRA[SA[0]] = 0;
for (int i = 1; i < n; i++) {
int s1 = SA[i], s2 = SA[i-1];
bool equal = true;
equal &= RA[s1] == RA[s2];
equal &= RA[s1+k] == RA[s2+k];
tempRA[SA[i]] = equal ? r : ++r;
}
memcpy(RA, tempRA, n*sizeof(int));
}
}
void lcp(string &s) {
int n = s.size();
Phi[SA[0]] = -1;
for (int i = 1; i < n; i++)
Phi[SA[i]] = SA[i-1];
int L = 0;
for (int i = 0; i < n; i++) {
if (Phi[i] == -1) {
PLCP[i] = 0;
continue;
}
while (s[i + L] == s[Phi[i] + L])
L++;
PLCP[i] = L;
L = max(L-1, 0);
}
for (int i = 1; i < n; i++)
LCP[i] = PLCP[SA[i]];
}
void score(string &s) {
SCR[s.size()-1] = 1;
int sum = 1;
for (int i=s.size()-2; i>=0; i--) {
if (LCP[i+1] < s.size()-SA[i]-1) {
sum = 1;
} else {
sum++;
}
SCR[i] = sum;
}
}
int main() {
string s = "abababa";
s = string(s.rbegin(), s.rend()) +".";
suffix_array(s);
lcp(s);
score(s);
for(int i=0; i<s.size(); i++) {
string ns = s.substr(SA[i], s.size()-SA[i]-1);
ns = string(ns.rbegin(), ns.rend());
cout << SCR[i] << "*" << ns.size() << " " << ns << endl;
}
}
Most of this code (specially the suffix array and LCP implementations) I have been using for some years in contests. This version in special I adapted from this one I wrote some years ago.
public class Main {
public static void main(String[] args) {
String input = "abababa";
String prefix;
int product;
int maxProduct = 0;
for (int i = 1; i <= input.length(); i++) {
prefix = input.substring(0, i);
String substr;
int occurs = 0;
for (int j = prefix.length(); j <= input.length(); j++) {
substr = input.substring(0, j);
if (substr.endsWith(prefix))
occurs++;
}
product = occurs*prefix.length();
System.out.println("product of " + prefix + " = " +
prefix.length() + " * " + occurs +" = " + product);
maxProduct = (product > maxProduct)?product:maxProduct;
}
System.out.println("maxProduct = " + maxProduct);
}
}
I was working on this challenge for more than 4 days , reading a lot of documentation, I found a solution with O(N) .
I got 81%, the idea is simple using a window slide.
def solution(s: String): Int = {
var max = s.length // length of the string
var i, j = 1 // start with i=j=1 ( is the beginning of the slide and j the end of the slide )
val len = s.length // the length of the string
val count = Array.ofDim[Int](len) // to store intermediate results
while (i < len - 1 || j < len) {
if (i < len && s(0) != s(i)) {
while (i < len && s(0) != s(i)) { // if the begin of the slide is different from
// the first letter of the string skip it
i = i + 1
}
}
j = i + 1
var k = 1
while (j < len && s(j).equals(s(k))) { // check for equality and update the array count
if (count(k) == 0) {
count(k) = 1
}
count(k) = count(k) + 1
max = math.max((k + 1) * count(k), max)
k = k + 1
j = j + 1
}
i = i + 1
}
max // return the max
}

Find all the 4 digit vampire numbers

I am solving a problem to find out all the 4 digit Vampire numbers.
A Vampire Number v=x*y is defined as a number with 'n' even number of digits formed by multiplying a pair of 'n/2'-digit numbers (where the digits are taken from the original number in any order)x and y together. If v is a vampire number, then x&y and are called its "fangs."
Examples of vampire numbers are:
1. 1260=21*60
2. 1395=15*93
3. 1530=30*51
I have tried the brute force algorithm to combine different digits of a given number and multiply them together . But this method is highly inefficient and takes up a lot of time.
Is there a more efficient algorithmic solution to this problem?
Or you can use a property of vampire numbers described on this page (linked from Wikipedia) :
An important theoretical result found by Pete Hartley:
If x·y is a vampire number then x·y == x+y (mod 9)
Proof: Let mod be the binary modulo operator and d(x) the sum of the decimal
digits of x. It is well-known that d(x) mod 9 = x mod 9, for all x.
Assume x·y is a vampire. Then it contains the same digits as x and y,
and in particular d(x·y) = d(x)+d(y). This leads to:
(x·y) mod 9 = d(x·y) mod 9 = (d(x)+d(y)) mod 9 = (d(x) mod 9 + d(y) mod 9) mod 9
= (x mod 9 + y mod 9) mod 9 = (x+y) mod 9
The solutions to the congruence are (x mod 9, y mod 9) in {(0,0),
(2,2), (3,6), (5,8), (6,3), (8,5)}
So your code could look like this :
for(int i=18; i<100; i=i+9){ // 18 is the first multiple of 9 greater than 10
for(int j=i; j<100; j=j+9){ // Start at i because as #sh1 said it's useless to check both x*y and y*x
checkVampire(i,j);
}
}
for(int i=11; i<100; i=i+9){ // 11 is the first number greater than 10 which is = 2 mod 9
for(int j=i; j<100; j=j+9){
checkVampire(i,j);
}
}
for(int i=12; i<100; i=i+9){
for(int j=i+3; j<100; j=j+9){
checkVampire(i,j);
}
}
for(int i=14; i<100; i=i+9){
for(int j=i+3; j<100; j=j+9){
checkVampire(i,j);
}
}
// We don't do the last 2 loops, again for symmetry reasons
Since they are 40 elements in each of the sets like {(x mod 9, y mod 9) = (0,0); 10 <= x <= y <= 100}, you only do 4*40 = 160 iterations, when a brute-force gives you 10ˆ4 iterations. You can do even less operations if you take into account the >= 1000 constraint, for instance you can avoid checking if j < 1000/i.
Now you can easily scale up to find vampires with more than 4 digits =)
Iterate over all possible fangs (100 x 100 = 10000 possibilities), and find if their product has the same digits as the fangs.
Yet another brute force (C) version, with a free bubble sort to boot...
#include <stdio.h>
static inline void bubsort(int *p)
{ while (1)
{ int s = 0;
for (int i = 0; i < 3; ++i)
if (p[i] > p[i + 1])
{ s = 1;
int t = p[i]; p[i] = p[i + 1]; p[i + 1] = t;
}
if (!s) break;
}
}
int main()
{ for (int i = 10; i < 100; ++i)
for (int j = i; j < 100; ++j)
{ int p = i * j;
if (p < 1000) continue;
int xd[4];
xd[0] = i % 10;
xd[1] = i / 10;
xd[2] = j % 10;
xd[3] = j / 10;
bubsort(xd);
int x = xd[0] + xd[1] * 10 + xd[2] * 100 + xd[3] * 1000;
int yd[4];
yd[0] = p % 10;
yd[1] = (p / 10) % 10;
yd[2] = (p / 100) % 10;
yd[3] = (p / 1000);
bubsort(yd);
int y = yd[0] + yd[1] * 10 + yd[2] * 100 + yd[3] * 1000;
if (x == y)
printf("%2d * %2d = %4d\n", i, j, p);
}
return 0;
}
Runs pretty much instantaneously. Variable names aren't too descriptive, but should be pretty obvious...
The basic idea is to start with two potential fangs, break them down into digits, and sort the digits for easy comparison. Then we do the same with the product - break it down to digits and sort. Then we re-constitute two integers from the sorted digits, and if they're equal, we have a match.
Possible improvements: 1) start j at 1000 / i instead of i to avoid having to do if (p < 1000) ..., 2) maybe use insertion sort instead of bubble sort (but who's gonna notice those 2 extra swaps?), 3) use a real swap() implementation, 4) compare the arrays directly rather than building a synthetic integer out of them. Not sure any of those would make any measurable difference, though, unless you run it on a Commodore 64 or something...
Edit: Just out of curiosity, I took this version and generalized it a bit more to work for the 4, 6 and 8 digit cases - without any major optimization, it can find all the 8-digit vampire numbers in < 10 seconds...
This is an ugly hack (brute force, manual checking for permutations, unsafe buffer operations, produces dupes, etc.) but it does the job. Your new exercise is to improve it :P
Wikipedia claims that there are 7 vampire numbers which are 4 digits long. The full code has found them all, even some duplicates.
Edit: Here's a slightly better comparator function.
Edit 2: Here's a C++ version that uniques results (therefore it avoids duplicates) using an std::map (and stores the last occurrence of the particular vampire number along with its factors in it). It also meets the criterion that at least one of the factors should not end with 0, i. e. a number is not a vampire number if both of the multiplicands are divisible by then. This test looks for 6-digit vampire numbers and it does indeed find exactly 148 of them, in accordance with what Wikipedia sates.
The original code:
#include <stdio.h>
void getdigits(char buf[], int n)
{
while (n) {
*buf++ = n % 10;
n /= 10;
}
}
int is_vampire(const char n[4], const char i[2], const char j[2])
{
/* maybe a bit faster if unrolled manually */
if (i[0] == n[0]
&& i[1] == n[1]
&& j[0] == n[2]
&& j[1] == n[3])
return 1;
if (i[0] == n[1]
&& i[1] == n[0]
&& j[0] == n[2]
&& j[1] == n[3])
return 1;
if (i[0] == n[0]
&& i[1] == n[1]
&& j[0] == n[3]
&& j[1] == n[2])
return 1;
if (i[0] == n[1]
&& i[1] == n[0]
&& j[0] == n[3]
&& j[1] == n[2])
return 1;
// et cetera, the following 20 repetitions are redacted for clarity
// (this really should be a loop, shouldn't it?)
return 0;
}
int main()
{
for (int i = 10; i < 100; i++) {
for (int j = 10; j < 100; j++) {
int n = i * j;
if (n < 1000)
continue;
char ndigits[4];
getdigits(ndigits, n);
char idigits[2];
char jdigits[2];
getdigits(idigits, i);
getdigits(jdigits, j);
if (is_vampire(ndigits, idigits, jdigits))
printf("%d * %d = %d\n", i, j, n);
}
}
return 0;
}
I wouldn't have given up so easily on brute force. You have distinct set of numbers, 1000 to 9999 that you must run through. I would divide up the set into some number of subsets, and then spin up threads to handle each subset.
You could further divide the work be coming up with the various combinations of each number; IIRC my discrete math, you have 4*3*2 or 24 combinations for each number to try.
A producer / consumer approach might be worthwhile.
Iteration seems fine to me, since you only need to do this once to find all the values and you can just cache them afterwards. Python (3) version that takes about 1.5 seconds:
# just some setup
from itertools import product, permutations
dtoi = lambda *digits: int(''.join(str(digit) for digit in digits))
gen = ((dtoi(*digits), digits) for digits in product(range(10), repeat=4) if digits[0] != 0)
l = []
for val, digits in gen:
for check1, check2 in ((dtoi(*order[:2]), dtoi(*order[2:])) for order in permutations(digits) if order[0] > 0 and order[2] > 0):
if check1 * check2 == val:
l.append(val)
break
print(l)
Which will give you [1260, 1395, 1435, 1530, 1827, 2187, 6880]
EDIT: full brute force that weeds out identical X and Y values...
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Vampire {
public static void main(String[] args) {
for (int x = 10; x < 100; x++) {
String sx = String.valueOf(x);
for (int y = x; y < 100; y++) {
int v = x * y;
String sy = String.valueOf(y);
String sv = String.valueOf(v);
if (sortVampire(sx + sy).equals(sortVampire(sv))) {
System.out.printf("%d * %d = %d%n", x, y, v);
}
}
}
}
private static List<Character> sortVampire(String v) {
List<Character> vc = new ArrayList<Character>();
for (int j = 0; j < v.length(); j++) {
vc.add(v.charAt(j));
}
Collections.sort(vc);
return vc;
}
}
Brute force version in C# with LINQ:
class VampireNumbers
{
static IEnumerable<int> numberToDigits(int number)
{
while(number > 0)
{
yield return number % 10;
number /= 10;
}
}
static bool isVampire(int first, int second, int result)
{
var resultDigits = numberToDigits(result).OrderBy(x => x);
var vampireDigits = numberToDigits(first)
.Concat(numberToDigits(second))
.OrderBy(x => x);
return resultDigits.SequenceEqual(vampireDigits);
}
static void Main(string[] args)
{
var vampires = from fang1 in Enumerable.Range(10, 89)
from fang2 in Enumerable.Range(10, 89)
where fang1 < fang2
&& isVampire(fang1, fang2, fang1 * fang2)
select new { fang1, fang2 };
foreach(var vampire in vampires)
{
Console.WriteLine(vampire.fang1 * vampire.fang2
+ " = "
+ vampire.fang1
+ " * "
+ vampire.fang2);
}
}
}
Similar to someone mentioned above, my method is to first find all permutations of a number, then split them in half to form two 2-digit numbers, and test if their product equal to the original number.
Another interesting discussion above is how many permutations a number can have. Here is my opinion:
(1) a number whose four digitals are the same has 1 permutation;
(2) a number who has only two different digits has 6 permutations (it doesn't matter if it contains zeros, because we don't care after permutation if it is still a 4-digit number);
(3) a number who has three different digits has 12 permutations;
(4) a number with all four different digits has 24 permutations.
public class VampireNumber {
// method to find all permutations of a 4-digit number
public static void permuta(String x, String s, int v)
{for(int i = 0; i < s.length(); i++)
{permuta( x + s.charAt(i), s.substring(0,i) + s.substring(i+1), v);
if (s.length() == 1)
{x = x + s;
int leftpart = Integer.parseInt(x.substring(0,2));
int rightpart = Integer.parseInt(x.substring(2));
if (leftpart*rightpart == v)
{System.out.println("Vampir = " + v);
}
}
}
}
public static void main(String[] args){
for (int i = 1000; i < 10000; i++) {
permuta("", Integer.toString(i), i); //convert the integer to a string
}
}
}
The approach I would try would be to loop through each number in [1000, 9999], and test if any permutation of its digits (split in the middle) multiplied to make it.
This will require (9999 - 1000) * 24 = 215,976 tests, which should execute acceptably fast on a modern machine.
I would definitely store the digits separately, so you can avoid having to do something like a bunch of division to extract the digits from a single integer.
If you write your code such that you're only ever doing integer addition and multiplication (and maybe the occasional division to carry), it should be pretty fast. You could further increase the speed by skipping two-digit pairs which "obviously" won't work - e.g., ones with leading zeros (note that the largest product than can be produced by a one digit number and a two digit number is 9 * 99, or 891).
Also note that this approach is embarassingly parallel (http://en.wikipedia.org/wiki/Embarrassingly_parallel), so if you really need to speed it up even more then you should look into testing the numbers in separate threads.
<?php
for ($i = 10; $i <= 99; $j++) {
// Extract digits
$digits = str_split($i);
// Loop through 2nd number
for ($j = 10; $j <= 99; $j++) {
// Extract digits
$j_digits = str_split($j);
$digits[2] = $j_digits[0];
$digits[3] = $j_digits[1];
$product = $i * $j;
$product_digits = str_split($product);
// check if fangs
$inc = 0;
while (in_array($digits[$inc], $product_digits)) {
// Remove digit from product table
/// So AAAA -> doesnt match ABCD
unset($product_digits[$array_serach($digits[$inc], $product_digits)]);
$inc++;
// If reached 4 -> vampire number
if ($inc == 4) {
$vampire[] = $product;
break;
}
}
}
}
// Print results
print_r($vampire);
?>
Took less than a second on PHP. couldn't even tell it had to run 8100 computations... computers are fast!
Results:
Gives you all the 4 digits plus some are repeated. You can further process the data and remove duplicates.
It seems to me that to perform the fewest possible tests without relying on any particularly abstract insights, you probably want to iterate over the fangs and cull any obviously pointless candidates.
For example, since x*y == y*x about half your search space can be eliminated by only evaluating cases where y > x. If the largest two-digit fang is 99 then the smallest which can make a four-digit number is 11, so don't start lower than 11.
EDIT:
OK, throwing everything I thought of into the mix (even though it looks silly against the leading solution).
for (x = 11; x < 100; x++)
{
/* start y either at x, or if x is too small then 1000 / x */
for (y = (x * x < 1000 ? 1000 / x : x); y < 100; y++)
{
int p = x * y;
/* if sum of digits in product is != sum of digits in x+y, then skip */
if ((p - (x + y)) % 9 != 0)
continue;
if (is_vampire(p, x, y))
printf("%d\n", p);
}
}
and the test, since I haven't seen anyone use a histogram, yet:
int is_vampire(int p, int x, int y)
{
int h[10] = { 0 };
int i;
for (i = 0; i < 4; i++)
{
h[p % 10]++;
p /= 10;
}
for (i = 0; i < 2; i++)
{
h[x % 10]--;
h[y % 10]--;
x /= 10;
y /= 10;
}
for (i = 0; i < 10; i++)
if (h[i] != 0)
return 0;
return 1;
}
1260 1395 1435 1530 1827 2187 6880 is vampire
I am new to programming... But there are only 12 combinations in finding all 4-digit vampire numbers. My poor answer is:
public class VampNo {
public static void main(String[] args) {
for(int i = 1000; i < 10000; i++) {
int a = i/1000;
int b = i/100%10;
int c = i/10%10;
int d = i%10;
if((a * 10 + b) * (c * 10 + d) == i || (b * 10 + a) * (d * 10 + c) == i ||
(a * 10 + d) * (b * 10 + c) == i || (d * 10 + a) * (c * 10 + b) == i ||
(a * 10 + c) * (b * 10 + d) == i || (c * 10 + a) * (d * 10 + b) == i ||
(a * 10 + b) * (d * 10 + c) == i || (b * 10 + a) * (c * 10 + d) == i ||
(b * 10 + c) * (d * 10 + a) == i || (c * 10 + b) * (a * 10 + d) == i ||
(a * 10 + c) * (d * 10 + b) == i || (c * 10 + a) * (b * 10 + d) == i)
System.out.println(i + " is vampire");
}
}
}
The main task now is to simplify boolean expression in If() block
I've edited Owlstead's algorithm a bit to make it more understandable to Java beginners/learners.
import java.util.Arrays;
public class Vampire {
public static void main(String[] args) {
for (int x = 10; x < 100; x++) {
String sx = Integer.toString(x);
for (int y = x; y < 100; y++) {
int v = x * y;
String sy = Integer.toString(y);
String sv = Integer.toString(v);
if( Arrays.equals(sortVampire(sx + sy), sortVampire(sv)))
System.out.printf("%d * %d = %d%n", x, y, v);
}
}
}
private static char[] sortVampire (String v){
char[] sortedArray = v.toCharArray();
Arrays.sort(sortedArray);
return sortedArray;
}
}
This python code run very fast (O(n2))
result = []
for i in range(10,100):
for j in range(10, 100):
list1 = []
list2 = []
k = i * j
if k < 1000 or k > 10000:
continue
else:
for item in str(i):
list1.append(item)
for item in str(j):
list1.append(item)
for item in str(k):
list2.append(item)
flag = 1
for each in list1:
if each not in list2:
flag = 0
else:
list2.remove(each)
for each in list2:
if each not in list1:
flag = 0
if flag == 1:
if k not in result:
result.append(k)
for each in result:
print(each)
And here is my code. To generate zombie numbers we need to use Random class :)
import java.io.PrintStream;
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;
class VampireNumbers {
static PrintStream p = System.out;
private static Set<Integer> findVampireNumber() {
Set<Integer> vampireSet = new HashSet<Integer>();
for (int y = 1000; y <= 9999; y++) {
char[] numbersSeparately = ("" + y).toCharArray();
int numberOfDigits = numbersSeparately.length;
for (int i = 0; i < numberOfDigits; i++) {
for (int j = 0; j < numberOfDigits; j++) {
if (i != j) {
int value1 = Integer.valueOf("" + numbersSeparately[i] + numbersSeparately[j]);
int ki = -1;
for (int k = 0; k < numberOfDigits; k++) {
if (k != i && k != j) {
ki = k;
}
}
int kj = -1;
for (int t = 0; t < numberOfDigits; t++) {
if (t != i && t != j && t != ki) {
kj = t;
}
}
int value21 = Integer.valueOf("" + numbersSeparately[ki] + numbersSeparately[kj]);
int value22 = Integer.valueOf("" + numbersSeparately[kj] + numbersSeparately[ki]);
if (value1 * value21 == y && !(numbersSeparately[j] == 0 && numbersSeparately[kj] == 0)
|| value1 * value22 == y
&& !(numbersSeparately[j] == 0 && numbersSeparately[ki] == 0)) {
vampireSet.add(y);
}
}
}
}
}
return vampireSet;
}
public static void main(String[] args) {
Set<Integer> vampireSet = findVampireNumber();
Iterator<Integer> i = vampireSet.iterator();
int number = 1;
while (i.hasNext()) {
p.println(number + ": " + i.next());
number++;
}
}
}

Resources