Reputation: 25
I've been trying to figure this out for hours with no success. I'm trying to re-write this Java code into Ruby and I thought I was done, however, something strange is happening.
Java method:
static void analyze (int n, int seriesLen)
{
int digit[] = new int [9];
int d = 0;
int m = n;
series[seriesLen - 1] = n;
while (m >= 10) {
digit[d++] = m % 10;
m /= 10;
}
digit[d++] = m;
for (int subset = (1 << d) - 2; subset > 0; subset--) {
int j = 0;
int s = subset;
int pos = d - 1;
/* find first digit */
while ((s & 1) == 0) {
s >>= 1;
pos--;
}
/* if first digit is a 0, move on */
if (digit[pos] == 0) continue;
do {
if ((s & 1) == 1) j = j*10 + digit[pos];
s >>= 1;
pos--;
} while (s > 0);
if (j > 1 && n % j == 0) {
int k = 0;
s = subset ^ ((1 << d) - 1);
pos = d - 1;
while (s > 0) {
if ((s & 1) == 1) k = k*10 + digit[pos];
s >>= 1;
pos--;
}
analyze (k, seriesLen + 1);
}
}
System.out.println("seriesLen: " + seriesLen);
if (betterSeries (seriesLen)) {
for (int i = 0; i < seriesLen; i++) {
best[i] = series[i];
}
bestLen = seriesLen;
}
}
Ruby method:
def analyze(n, seriesLen)
@digit = [0,0,0,0,0,0,0,0,0]
m = n
d = 0
$series[seriesLen-1] = n
while(m >= 10)
@digit[d] = (m % 10)
d = d + 1
m /= 10
end
@digit[d] = m
d = d + 1
subset = (1 << d) - 2
while (subset > 0)
j = 0
s = subset
pos = d - 1
while ((s & 1) == 0)
s >>= 1
pos -= 1
end
if (@digit[pos] == 0):
subset -= 1
next
end
begin
j = (j*10 + @digit[pos]) if ((s & 1) == 1)
s >>= 1
pos -= 1
end while s > 0
if (j > 1 && n % j == 0):
k = 0
s = (subset) ^ ((1 << d) - 1)
pos = d - 1
while (s > 0)
k = (k*10 + @digit[pos]) if ((s & 1) == 1)
s >>= 1
pos -= 1
end
analyze(k, seriesLen + 1)
end
subset -= 1
end
if (betterSeries(seriesLen)):
for i in 0...seriesLen
$best[i] = $series[i]
end
$bestLen = seriesLen;
end
end
I did some traces on the relevant data for both versions of the code. Everything is exactly the same until about halfway through. After this point, the digit[] array in the Java version has all zeros except for a 2 at digit[2] (which is correct). However, at this point in the Ruby version, digit[2] is zero along with all the other elements. I am very confused about why they seem to work in perfect harmony for so long until this discontinuity appears. I can't even figure out why digit[2] = 2 in the Java version (and I am positive the Java code is correct).
Upvotes: 2
Views: 117
Reputation: 86525
Your @digit
is an instance variable, not a local. (That's what the @
means.) It will get reset to all zeros every time you call analyze
. And since analyze
calls itself halfway through, it ends up overwriting the previous call's version with an array of all zeros before it starts doing its thing. (In the Java code, on the other hand, it's a local -- and each call has its own digit
.)
Try getting rid of the @
in the variable name, and see if that helps.
Upvotes: 1