A friend of mine is interviewing for a job. One of the interview questions got me thinking, just wanted some feedback.
There are 2 non-negative integers: i and j. Gi
A FIFO-based solution needs less storage capacity. Python code.
F = [[1, 0, 0]] # FIFO [value, i, j]
i2 = -1; n2 = n5 = None # indices, nexts
for i in range(1000): # print the first 1000
last = F[-1][:]
print "%3d. %21d = 2^%d * 5^%d" % tuple([i] + last)
if n2 <= last: i2 += 1; n2 = F[i2][:]; n2[0] *= 2; n2[1] += 1
if n5 <= last: i2 -= 1; n5 = F.pop(0); n5[0] *= 5; n5[2] += 1
F.append(min(n2, n5))
output:
0. 1 = 2^0 * 5^0
1. 2 = 2^1 * 5^0
2. 4 = 2^2 * 5^0
...
998. 100000000000000000000 = 2^20 * 5^20
999. 102400000000000000000 = 2^27 * 5^17
Use a Min-heap.
Put 1.
extract-Min. Say you get x.
Push 2x and 5x into the heap.
Repeat.
Instead of storing x = 2^i * 5^j, you can store (i,j) and use a custom compare function.
This is the relevant entry at OEIS.
It seems to be possible to obtain the ordered sequence by generating the first few terms, say
1 2 4 5
and then, starting from the second term, multiplying by 4 and 5 to get the next two
1 2 4 5 8 10
1 2 4 5 8 10 16 20
1 2 4 5 8 10 16 20 25
and so on...
Intuitively, this seems correct, but of course a proof is missing.
calculate the results and put them in a sorted list, together with the values for i
and j
If we are allowed to use java Collection then we can have these number in O(n^2)
public static void main(String[] args) throws Exception {
int powerLimit = 7;
int first = 2;
int second = 5;
SortedSet<Integer> set = new TreeSet<Integer>();
for (int i = 0; i < powerLimit; i++) {
for (int j = 0; j < powerLimit; j++) {
Integer x = (int) (Math.pow(first, i) * Math.pow(second, j));
set.add(x);
}
}
set=set.headSet((int)Math.pow(first, powerLimit));
for (int p : set)
System.out.println(p);
}
Here powerLimit has to be initialised very carefully !! Depending upon how many numbers you want.
Here is my attempt with Scala:
case class IndexValue(twosIndex: Int, fivesIndex: Int)
case class OutputValues(twos: Int, fives: Int, value: Int) {
def test(): Boolean = {
Math.pow(2, twos) * Math.pow(5, fives) == value
}
}
def run(last: IndexValue = IndexValue(0, 0), list: List[OutputValues] = List(OutputValues(0, 0, 1))): List[OutputValues] = {
if (list.size > 20) {
return list
}
val twosValue = list(last.twosIndex).value * 2
val fivesValue = list(last.fivesIndex).value * 5
if (twosValue == fivesValue) {
val lastIndex = IndexValue(last.twosIndex + 1, last.fivesIndex + 1)
val outputValues = OutputValues(value = twosValue, twos = list(last.twosIndex).twos + 1, fives = list(last.fivesIndex).fives + 1)
run(lastIndex, list :+ outputValues)
} else if (twosValue < fivesValue) {
val lastIndex = IndexValue(last.twosIndex + 1, last.fivesIndex)
val outputValues = OutputValues(value = twosValue, twos = list(last.twosIndex).twos + 1, fives = list(last.twosIndex).fives)
run(lastIndex, list :+ outputValues)
} else {
val lastIndex = IndexValue(last.twosIndex, last.fivesIndex + 1)
val outputValues = OutputValues(value = fivesValue, twos = list(last.fivesIndex).twos, fives = list(last.fivesIndex).fives + 1)
run(lastIndex, list :+ outputValues)
}
}
val initialIndex = IndexValue(0, 0)
run(initialIndex, List(OutputValues(0, 0, 1))) foreach println
OutputValues(0,0,1)
OutputValues(1,0,2)
OutputValues(2,0,4)
OutputValues(0,1,5)
OutputValues(3,0,8)
OutputValues(1,1,10)
OutputValues(4,0,16)
OutputValues(2,1,20)
OutputValues(0,2,25)
OutputValues(5,0,32)
OutputValues(3,1,40)
OutputValues(1,2,50)
OutputValues(6,0,64)
OutputValues(4,1,80)
OutputValues(2,2,100)
OutputValues(0,3,125)
OutputValues(7,0,128)
OutputValues(5,1,160)
OutputValues(3,2,200)
OutputValues(1,3,250)
OutputValues(8,0,256)